Update MRI projects for Aluminium
[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 java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.Optional;
16 import java.util.Set;
17 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
18 import org.opendaylight.openflowplugin.extension.api.AugmentTuple;
19 import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
20 import org.opendaylight.openflowplugin.openflow.md.core.extension.MatchExtensionHelper;
21 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.action.data.ActionResponseConvertorData;
22 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.Convertor;
23 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.FlowStatsResponseConvertorData;
24 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
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.common.Uint8;
44
45 /**
46  * Converts flow related statistics messages coming from openflow switch to MD-SAL messages.
47  *
48  * <p>
49  * Example usage:
50  * <pre>
51  * {@code
52  * VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(version);
53  * data.setDatapathId(datapathId);
54  * Optional<List<FlowAndStatisticsMapList>> salFlowStats = convertorManager.convert(ofFlowStats, data);
55  * }
56  * </pre>
57  */
58 public class FlowStatsResponseConvertor extends Convertor<List<FlowStats>, List<FlowAndStatisticsMapList>,
59         FlowStatsResponseConvertorData> {
60
61     private static final Set<Class<?>> TYPES = Collections.singleton(FlowStats.class);
62
63     /**
64      * Method wraps openflow 1.0 actions list to Apply Action Instructions.
65      *
66      * @param actionsList list of action
67      * @param ipProtocol ip protocol
68      * @return OF10 actions as an instructions
69      */
70     private Instructions wrapOF10ActionsToInstruction(
71             final List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions
72                 .grouping.Action> actionsList,
73             final short version, final Uint8 ipProtocol) {
74         ActionResponseConvertorData actionResponseConvertorData = new ActionResponseConvertorData(version);
75         actionResponseConvertorData.setActionPath(ActionPath.FLOWS_STATISTICS_UPDATE_WRITE_ACTIONS);
76         actionResponseConvertorData.setIpProtocol(ipProtocol);
77
78         ApplyActionsCaseBuilder applyActionsCaseBuilder = new ApplyActionsCaseBuilder();
79         ApplyActionsBuilder applyActionsBuilder = new ApplyActionsBuilder();
80
81         final Optional<List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action>>
82             actions = getConvertorExecutor().convert(actionsList, actionResponseConvertorData);
83
84         applyActionsBuilder.setAction(FlowConvertorUtil.wrapActionList(actions.orElse(Collections.emptyList())));
85         applyActionsCaseBuilder.setApplyActions(applyActionsBuilder.build());
86
87         InstructionBuilder instBuilder = new InstructionBuilder();
88         instBuilder.setInstruction(applyActionsCaseBuilder.build());
89         instBuilder.withKey(new InstructionKey(0));
90         instBuilder.setOrder(0);
91         List<Instruction> salInstructionList = new ArrayList<>();
92         salInstructionList.add(instBuilder.build());
93
94         InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
95         instructionsBuilder.setInstruction(salInstructionList);
96         return instructionsBuilder.build();
97     }
98
99     @Override
100     public Collection<Class<?>> getTypes() {
101         return TYPES;
102     }
103
104     @Override
105     public List<FlowAndStatisticsMapList> convert(final List<FlowStats> source,
106             final FlowStatsResponseConvertorData data) {
107         final List<FlowAndStatisticsMapList> result = new ArrayList<>();
108
109         for (FlowStats flowStats : source) {
110             // Convert Openflow switch specific flow statistics to the MD-SAL format flow statistics
111             FlowAndStatisticsMapListBuilder salFlowStatsBuilder = new FlowAndStatisticsMapListBuilder();
112             salFlowStatsBuilder.setByteCount(new Counter64(flowStats.getByteCount()));
113
114             if (flowStats.getCookie() != null) {
115                 salFlowStatsBuilder.setCookie(new FlowCookie(flowStats.getCookie()));
116             }
117
118             DurationBuilder time = new DurationBuilder();
119             time.setSecond(new Counter32(flowStats.getDurationSec()));
120             time.setNanosecond(new Counter32(flowStats.getDurationNsec()));
121             salFlowStatsBuilder.setDuration(time.build());
122
123             salFlowStatsBuilder.setHardTimeout(flowStats.getHardTimeout());
124             salFlowStatsBuilder.setIdleTimeout(flowStats.getIdleTimeout());
125             salFlowStatsBuilder.setPacketCount(new Counter64(flowStats.getPacketCount()));
126             salFlowStatsBuilder.setPriority(flowStats.getPriority());
127             salFlowStatsBuilder.setTableId(flowStats.getTableId());
128
129             if (flowStats.getMatchV10() != null) {
130                 final Optional<MatchBuilder> matchBuilderOptional = getConvertorExecutor().convert(
131                         flowStats.getMatchV10(), data);
132                 Uint8 ipProtocol = null;
133
134                 if (matchBuilderOptional.isPresent()) {
135                     final MatchBuilder matchBuilder = matchBuilderOptional.get();
136                     final IpMatch ipMatch = matchBuilder.getIpMatch();
137                     if (ipMatch != null) {
138                         ipProtocol = ipMatch.getIpProtocol();
139                     }
140
141                     salFlowStatsBuilder.setMatch(matchBuilder.build());
142                 }
143
144                 if (flowStats.getAction() != null && flowStats.getAction().size() != 0) {
145                     salFlowStatsBuilder.setInstructions(wrapOF10ActionsToInstruction(flowStats.getAction(),
146                             data.getVersion(), ipProtocol));
147                 }
148             }
149
150             if (flowStats.getMatch() != null) {
151                 final Optional<MatchBuilder> matchBuilderOptional = getConvertorExecutor().convert(
152                         flowStats.getMatch(), data);
153
154                 if (matchBuilderOptional.isPresent()) {
155                     final MatchBuilder matchBuilder = matchBuilderOptional.get();
156
157                     final AugmentTuple<Match> matchExtensionWrap =
158                             MatchExtensionHelper.processAllExtensions(
159                                     flowStats.getMatch().nonnullMatchEntry(),
160                                     OpenflowVersion.get(data.getVersion()),
161                                     data.getMatchPath());
162
163                     if (matchExtensionWrap != null) {
164                         matchBuilder.addAugmentation(matchExtensionWrap.getAugmentationClass(),
165                                 matchExtensionWrap.getAugmentationObject());
166                     }
167
168                     salFlowStatsBuilder.setMatch(matchBuilder.build());
169                 }
170
171
172                 salFlowStatsBuilder.setFlags(
173                         new FlowModFlags(flowStats.getFlags().isOFPFFCHECKOVERLAP(),
174                                 flowStats.getFlags().isOFPFFRESETCOUNTS(),
175                                 flowStats.getFlags().isOFPFFNOPKTCOUNTS(),
176                                 flowStats.getFlags().isOFPFFNOBYTCOUNTS(),
177                                 flowStats.getFlags().isOFPFFSENDFLOWREM()));
178             }
179
180             if (flowStats.getInstruction() != null) {
181                 final VersionConvertorData simpleConvertorData = new VersionConvertorData(data.getVersion());
182                 final Optional<Instructions> instructions = getConvertorExecutor().convert(
183                         flowStats.getInstruction(), simpleConvertorData);
184
185                 salFlowStatsBuilder.setInstructions(instructions.orElse(new InstructionsBuilder()
186                         .setInstruction(Collections.emptyList()).build()));
187             }
188
189             result.add(salFlowStatsBuilder.build());
190         }
191
192         return result;
193     }
194 }