Bug 5540 - ConvertorManager DataContainer source, one Convertor interface
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / flow / FlowStatsResponseConvertor.java
1 /*
2  * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.flow;
10
11 import com.google.common.annotations.VisibleForTesting;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.Optional;
16 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
17 import org.opendaylight.openflowplugin.extension.api.AugmentTuple;
18 import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
19 import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
20 import org.opendaylight.openflowplugin.openflow.md.core.extension.MatchExtensionHelper;
21 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
22 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.action.data.ActionResponseConvertorData;
23 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.Convertor;
24 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
25 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStats;
43 import org.opendaylight.yangtools.yang.binding.DataContainer;
44
45 /**
46  * Converts flow related statistics messages coming from openflow switch to MD-SAL messages.
47  *
48  * Example usage:
49  * <pre>
50  * {@code
51  * VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(version);
52  * data.setDatapathId(datapathId);
53  * Optional<List<FlowAndStatisticsMapList>> salFlowStats = ConvertorManager.getInstance().convert(ofFlowStats, data);
54  * }
55  * </pre>
56  */
57 public class FlowStatsResponseConvertor implements Convertor<List<FlowStats>, List<FlowAndStatisticsMapList>, VersionDatapathIdConvertorData> {
58
59     /**
60      * Method wraps openflow 1.0 actions list to Apply Action Instructions
61      *
62      * @param actionsList list of action
63      * @return OF10 actions as an instructions
64      */
65     @VisibleForTesting
66     static Instructions wrapOF10ActionsToInstruction(List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action> actionsList, final short version) {
67         ActionResponseConvertorData actionResponseConvertorData = new ActionResponseConvertorData(version);
68         actionResponseConvertorData.setActionPath(ActionPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION);
69
70         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
71         List<Instruction> salInstructionList = new ArrayList<>();
72
73         ApplyActionsCaseBuilder applyActionsCaseBuilder = new ApplyActionsCaseBuilder();
74         ApplyActionsBuilder applyActionsBuilder = new ApplyActionsBuilder();
75
76         final Optional<List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action>> actions = ConvertorManager.getInstance().convert(
77                 actionsList, actionResponseConvertorData);
78
79         applyActionsBuilder.setAction(FlowConvertorUtil.wrapActionList(actions.orElse(Collections.emptyList())));
80         applyActionsCaseBuilder.setApplyActions(applyActionsBuilder.build());
81
82         InstructionBuilder instBuilder = new InstructionBuilder();
83         instBuilder.setInstruction(applyActionsCaseBuilder.build());
84         instBuilder.setKey(new InstructionKey(0));
85         instBuilder.setOrder(0);
86         salInstructionList.add(instBuilder.build());
87
88         instructionsBuilder.setInstruction(salInstructionList);
89         return instructionsBuilder.build();
90     }
91
92     @Override
93     public Class<? extends DataContainer> getType() {
94         return FlowStats.class;
95     }
96
97     @Override
98     public List<FlowAndStatisticsMapList> convert(List<FlowStats> source, VersionDatapathIdConvertorData data) {
99         final List<FlowAndStatisticsMapList> result = new ArrayList<>();
100
101         for (FlowStats flowStats : source) {
102             // Convert Openflow switch specific flow statistics to the MD-SAL format flow statistics
103             FlowAndStatisticsMapListBuilder salFlowStatsBuilder = new FlowAndStatisticsMapListBuilder();
104             salFlowStatsBuilder.setByteCount(new Counter64(flowStats.getByteCount()));
105
106             if (flowStats.getCookie() != null) {
107                 salFlowStatsBuilder.setCookie(new FlowCookie(flowStats.getCookie()));
108             }
109
110             DurationBuilder time = new DurationBuilder();
111             time.setSecond(new Counter32(flowStats.getDurationSec()));
112             time.setNanosecond(new Counter32(flowStats.getDurationNsec()));
113             salFlowStatsBuilder.setDuration(time.build());
114
115             salFlowStatsBuilder.setHardTimeout(flowStats.getHardTimeout());
116             salFlowStatsBuilder.setIdleTimeout(flowStats.getIdleTimeout());
117             salFlowStatsBuilder.setPacketCount(new Counter64(flowStats.getPacketCount()));
118             salFlowStatsBuilder.setPriority(flowStats.getPriority());
119             salFlowStatsBuilder.setTableId(flowStats.getTableId());
120
121             if (flowStats.getMatchV10() != null) {
122                 final Optional<MatchBuilder> matchBuilderOptional = ConvertorManager.getInstance().convert(flowStats.getMatchV10(), data);
123
124                 if (matchBuilderOptional.isPresent()) {
125                     salFlowStatsBuilder.setMatch(matchBuilderOptional.get().build());
126                 }
127
128                 if (flowStats.getAction() != null && flowStats.getAction().size() != 0) {
129                     salFlowStatsBuilder.setInstructions(wrapOF10ActionsToInstruction(flowStats.getAction(), data.getVersion()));
130                 }
131             }
132
133             if (flowStats.getMatch() != null) {
134                 final Optional<MatchBuilder> matchBuilderOptional = ConvertorManager.getInstance().convert(flowStats.getMatch(), data);
135
136                 if (matchBuilderOptional.isPresent()) {
137                     final MatchBuilder matchBuilder = matchBuilderOptional.get();
138
139                     final AugmentTuple<Match> matchExtensionWrap =
140                             MatchExtensionHelper.processAllExtensions(
141                                     flowStats.getMatch().getMatchEntry(),
142                                     OpenflowVersion.get(data.getVersion()),
143                                     MatchPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_MATCH);
144
145                     if (matchExtensionWrap != null) {
146                         matchBuilder.addAugmentation(matchExtensionWrap.getAugmentationClass(), matchExtensionWrap.getAugmentationObject());
147                     }
148
149                     salFlowStatsBuilder.setMatch(matchBuilder.build());
150                 }
151
152
153                 salFlowStatsBuilder.setFlags(
154                         new FlowModFlags(flowStats.getFlags().isOFPFFCHECKOVERLAP(),
155                                 flowStats.getFlags().isOFPFFRESETCOUNTS(),
156                                 flowStats.getFlags().isOFPFFNOPKTCOUNTS(),
157                                 flowStats.getFlags().isOFPFFNOBYTCOUNTS(),
158                                 flowStats.getFlags().isOFPFFSENDFLOWREM()));
159             }
160
161             if (flowStats.getInstruction() != null) {
162                 final VersionConvertorData simpleConvertorData = new VersionConvertorData(data.getVersion());
163                 final Optional<Instructions> instructions = ConvertorManager.getInstance().convert(
164                         flowStats.getInstruction(), simpleConvertorData);
165
166                 salFlowStatsBuilder.setInstructions(instructions.orElse(new InstructionsBuilder()
167                         .setInstruction(Collections.emptyList()).build()));
168             }
169
170             result.add(salFlowStatsBuilder.build());
171         }
172
173         return result;
174     }
175 }