94295ca69c85df6260e733f64b18ea51cf007ed0
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / translator / MultipartReplyTranslator.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.translator;
10
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.Optional;
16 import java.util.concurrent.CopyOnWriteArrayList;
17 import org.opendaylight.openflowplugin.api.openflow.md.core.IMDMessageTranslator;
18 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
19 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;
20 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
21 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
22 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.FlowStatsResponseConvertor;
23 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
24 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
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.AggregateFlowStatisticsUpdateBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdateBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdateBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdatedBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdatedBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdatedBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Chaining;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.ChainingChecks;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupAll;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupCapability;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFf;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupIndirect;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupSelect;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupType;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectLiveness;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectWeight;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdatedBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesUpdatedBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdatedBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBand;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDrop;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDscpRemark;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBurst;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterCapability;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterKbps;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterPktps;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterStats;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCase;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCase;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregate;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.MultipartReplyGroupDesc;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.MultipartReplyMeterConfig;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeatures;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStats;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTable;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdateBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueStatisticsUpdateBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
100 import org.opendaylight.yangtools.yang.binding.DataObject;
101 import org.slf4j.Logger;
102 import org.slf4j.LoggerFactory;
103
104 /**
105  * Class converts multipart reply messages to the notification objects defined
106  * by statistics provider (manager ).
107  *
108  * @author avishnoi@in.ibm.com
109  *
110  */
111 public class MultipartReplyTranslator implements IMDMessageTranslator<OfHeader,  List<DataObject>> {
112
113     protected static final Logger logger = LoggerFactory
114             .getLogger(MultipartReplyTranslator.class);
115
116     private static FlowStatsResponseConvertor flowStatsConvertor = new FlowStatsResponseConvertor();
117
118
119     @Override
120     public  List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sc, final OfHeader msg) {
121
122         List<DataObject> listDataObject = new CopyOnWriteArrayList<DataObject>();
123
124         OpenflowVersion ofVersion = OpenflowVersion.get(sc.getPrimaryConductor().getVersion());
125
126         if(msg instanceof MultipartReplyMessage){
127             MultipartReplyMessage mpReply = (MultipartReplyMessage)msg;
128             NodeId node = MultipartReplyTranslator.nodeIdFromDatapathId(sc.getFeatures().getDatapathId());
129             switch (mpReply.getType()){
130             case OFPMPFLOW: {
131                 logger.debug("Received flow statistics reponse from openflow {} switch",msg.getVersion()==1?"1.0":"1.3+");
132                 FlowsStatisticsUpdateBuilder message = new FlowsStatisticsUpdateBuilder();
133                 message.setId(node);
134                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
135                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
136                 MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase)mpReply.getMultipartReplyBody();
137                 MultipartReplyFlow replyBody = caseBody.getMultipartReplyFlow();
138                 message.setFlowAndStatisticsMapList(flowStatsConvertor.toSALFlowStatsList(replyBody.getFlowStats(),sc.getFeatures().getDatapathId(), ofVersion));
139
140                 logger.debug("Converted flow statistics : {}",message.build().toString());
141                 listDataObject.add(message.build());
142                 return listDataObject;
143             }
144             case OFPMPAGGREGATE: {
145                 logger.debug("Received aggregate flow statistics reponse from openflow {} switch",msg.getVersion()==1?"1.0":"1.3+");
146                 AggregateFlowStatisticsUpdateBuilder message = new AggregateFlowStatisticsUpdateBuilder();
147                 message.setId(node);
148                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
149                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
150
151                 MultipartReplyAggregateCase caseBody = (MultipartReplyAggregateCase)mpReply.getMultipartReplyBody();
152                 MultipartReplyAggregate replyBody = caseBody.getMultipartReplyAggregate();
153                 message.setByteCount(new Counter64(replyBody.getByteCount()));
154                 message.setPacketCount(new Counter64(replyBody.getPacketCount()));
155                 message.setFlowCount(new Counter32(replyBody.getFlowCount()));
156
157                 logger.debug("Converted aggregate flow statistics : {}",message.build().toString());
158                 listDataObject.add(message.build());
159                 return listDataObject;
160             }
161             case OFPMPPORTSTATS: {
162
163                 logger.debug("Received port statistics multipart response");
164
165                 NodeConnectorStatisticsUpdateBuilder message = new NodeConnectorStatisticsUpdateBuilder();
166                 message.setId(node);
167                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
168                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
169
170                 MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase)mpReply.getMultipartReplyBody();
171                 MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats();
172
173                 List<NodeConnectorStatisticsAndPortNumberMap> statsMap =
174                         new ArrayList<NodeConnectorStatisticsAndPortNumberMap>();
175                 for (PortStats portStats: replyBody.getPortStats()){
176
177                     NodeConnectorStatisticsAndPortNumberMapBuilder statsBuilder =
178                             new NodeConnectorStatisticsAndPortNumberMapBuilder();
179                     statsBuilder.setNodeConnectorId(
180                             InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(sc.getFeatures().getDatapathId(),
181                                     portStats.getPortNo(), ofVersion));
182
183                     BytesBuilder bytesBuilder = new BytesBuilder();
184                     bytesBuilder.setReceived(portStats.getRxBytes());
185                     bytesBuilder.setTransmitted(portStats.getTxBytes());
186                     statsBuilder.setBytes(bytesBuilder.build());
187
188                     PacketsBuilder packetsBuilder = new PacketsBuilder();
189                     packetsBuilder.setReceived(portStats.getRxPackets());
190                     packetsBuilder.setTransmitted(portStats.getTxPackets());
191                     statsBuilder.setPackets(packetsBuilder.build());
192
193                     DurationBuilder durationBuilder = new DurationBuilder();
194                     if (portStats.getDurationSec() != null) {
195                         durationBuilder.setSecond(new Counter32(portStats.getDurationSec()));
196                     }
197                     if (portStats.getDurationNsec() != null) {
198                         durationBuilder.setNanosecond(new Counter32(portStats.getDurationNsec()));
199                     }
200                     statsBuilder.setDuration(durationBuilder.build());
201                     statsBuilder.setCollisionCount(portStats.getCollisions());
202                     statsBuilder.setKey(new NodeConnectorStatisticsAndPortNumberMapKey(statsBuilder.getNodeConnectorId()));
203                     statsBuilder.setReceiveCrcError(portStats.getRxCrcErr());
204                     statsBuilder.setReceiveDrops(portStats.getRxDropped());
205                     statsBuilder.setReceiveErrors(portStats.getRxErrors());
206                     statsBuilder.setReceiveFrameError(portStats.getRxFrameErr());
207                     statsBuilder.setReceiveOverRunError(portStats.getRxOverErr());
208                     statsBuilder.setTransmitDrops(portStats.getTxDropped());
209                     statsBuilder.setTransmitErrors(portStats.getTxErrors());
210
211                     statsMap.add(statsBuilder.build());
212                 }
213                 message.setNodeConnectorStatisticsAndPortNumberMap(statsMap);
214
215                 logger.debug("Converted ports statistics : {}",message.build().toString());
216
217                 listDataObject.add(message.build());
218                 return listDataObject;
219             }
220             case OFPMPGROUP:{
221                 logger.debug("Received group statistics multipart reponse");
222                 GroupStatisticsUpdatedBuilder message = new GroupStatisticsUpdatedBuilder();
223                 message.setId(node);
224                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
225                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
226                 MultipartReplyGroupCase caseBody = (MultipartReplyGroupCase)mpReply.getMultipartReplyBody();
227                 MultipartReplyGroup replyBody = caseBody.getMultipartReplyGroup();
228                 final Optional<List<GroupStats>> groupStatsList = ConvertorManager.getInstance().convert(replyBody.getGroupStats());
229                 message.setGroupStats(groupStatsList.orElse(Collections.emptyList()));
230                 logger.debug("Converted group statistics : {}",message.toString());
231                 listDataObject.add(message.build());
232                 return listDataObject;
233             }
234             case OFPMPGROUPDESC:{
235                 logger.debug("Received group description statistics multipart reponse");
236
237                 GroupDescStatsUpdatedBuilder message = new GroupDescStatsUpdatedBuilder();
238                 message.setId(node);
239                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
240                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
241                 MultipartReplyGroupDescCase caseBody = (MultipartReplyGroupDescCase)mpReply.getMultipartReplyBody();
242                 MultipartReplyGroupDesc replyBody = caseBody.getMultipartReplyGroupDesc();
243
244                 final VersionConvertorData data = new VersionConvertorData(sc.getPrimaryConductor().getVersion());
245                 final Optional<List<GroupDescStats>> groupDescStatsList = ConvertorManager.getInstance().convert(replyBody.getGroupDesc(), data);
246                 message.setGroupDescStats(groupDescStatsList.orElse(Collections.emptyList()));
247                 logger.debug("Converted group statistics : {}",message.toString());
248                 listDataObject.add(message.build());
249                 return listDataObject;
250             }
251             case OFPMPGROUPFEATURES: {
252                 logger.debug("Received group features multipart reponse");
253                 GroupFeaturesUpdatedBuilder message = new GroupFeaturesUpdatedBuilder();
254                 message.setId(node);
255                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
256                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
257                 MultipartReplyGroupFeaturesCase caseBody = (MultipartReplyGroupFeaturesCase)mpReply.getMultipartReplyBody();
258                 MultipartReplyGroupFeatures replyBody = caseBody.getMultipartReplyGroupFeatures();
259                 List<Class<? extends GroupType>> supportedGroups =
260                         new ArrayList<Class<? extends GroupType>>();
261
262                 if(replyBody.getTypes().isOFPGTALL()){
263                     supportedGroups.add(GroupAll.class);
264                 }
265                 if(replyBody.getTypes().isOFPGTSELECT()){
266                     supportedGroups.add(GroupSelect.class);
267                 }
268                 if(replyBody.getTypes().isOFPGTINDIRECT()){
269                     supportedGroups.add(GroupIndirect.class);
270                 }
271                 if(replyBody.getTypes().isOFPGTFF()){
272                     supportedGroups.add(GroupFf.class);
273                 }
274                 message.setGroupTypesSupported(supportedGroups);
275                 message.setMaxGroups(replyBody.getMaxGroups());
276
277                 List<Class<? extends GroupCapability>> supportedCapabilities =
278                         new ArrayList<Class<? extends GroupCapability>>();
279
280                 if(replyBody.getCapabilities().isOFPGFCCHAINING()){
281                     supportedCapabilities.add(Chaining.class);
282                 }
283                 if(replyBody.getCapabilities().isOFPGFCCHAININGCHECKS()){
284                     supportedCapabilities.add(ChainingChecks.class);
285                 }
286                 if(replyBody.getCapabilities().isOFPGFCSELECTLIVENESS()){
287                     supportedCapabilities.add(SelectLiveness.class);
288                 }
289                 if(replyBody.getCapabilities().isOFPGFCSELECTWEIGHT()){
290                     supportedCapabilities.add(SelectWeight.class);
291                 }
292
293                 message.setGroupCapabilitiesSupported(supportedCapabilities);
294
295                 message.setActions(getGroupActionsSupportBitmap(replyBody.getActionsBitmap()));
296                 listDataObject.add(message.build());
297
298                 return listDataObject;
299             }
300             case OFPMPMETER: {
301                 logger.debug("Received meter statistics multipart reponse");
302                 MeterStatisticsUpdatedBuilder message = new MeterStatisticsUpdatedBuilder();
303                 message.setId(node);
304                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
305                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
306
307                 MultipartReplyMeterCase caseBody = (MultipartReplyMeterCase)mpReply.getMultipartReplyBody();
308                 MultipartReplyMeter replyBody = caseBody.getMultipartReplyMeter();
309
310                 final Optional<List<org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats>> meterStatsList =
311                         ConvertorManager.getInstance().convert(replyBody.getMeterStats());
312
313                 message.setMeterStats(meterStatsList.orElse(Collections.emptyList()));
314                 listDataObject.add(message.build());
315                 return listDataObject;
316             }
317             case OFPMPMETERCONFIG:{
318                 logger.debug("Received meter config statistics multipart reponse");
319
320                 MeterConfigStatsUpdatedBuilder message = new MeterConfigStatsUpdatedBuilder();
321                 message.setId(node);
322                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
323                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
324
325                 MultipartReplyMeterConfigCase caseBody = (MultipartReplyMeterConfigCase)mpReply.getMultipartReplyBody();
326                 MultipartReplyMeterConfig replyBody = caseBody.getMultipartReplyMeterConfig();
327
328                 final Optional<List<MeterConfigStats>> meterConfigStatsList = ConvertorManager.getInstance().convert(replyBody.getMeterConfig());
329
330                 message.setMeterConfigStats(meterConfigStatsList.orElse(Collections.emptyList()));
331                 listDataObject.add(message.build());
332                 return listDataObject;
333             }
334             case OFPMPMETERFEATURES:{
335                 logger.debug("Received meter features multipart reponse");
336                 //Convert OF message and send it to SAL listener
337                 MeterFeaturesUpdatedBuilder message = new MeterFeaturesUpdatedBuilder();
338                 message.setId(node);
339                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
340                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
341
342                 MultipartReplyMeterFeaturesCase caseBody = (MultipartReplyMeterFeaturesCase)mpReply.getMultipartReplyBody();
343                 MultipartReplyMeterFeatures replyBody = caseBody.getMultipartReplyMeterFeatures();
344                 message.setMaxBands(replyBody.getMaxBands());
345                 message.setMaxColor(replyBody.getMaxColor());
346                 message.setMaxMeter(new Counter32(replyBody.getMaxMeter()));
347
348                 List<Class<? extends MeterCapability>> supportedCapabilities =
349                         new ArrayList<Class<? extends MeterCapability>>();
350                 if(replyBody.getCapabilities().isOFPMFBURST()){
351                     supportedCapabilities.add(MeterBurst.class);
352                 }
353                 if(replyBody.getCapabilities().isOFPMFKBPS()){
354                     supportedCapabilities.add(MeterKbps.class);
355
356                 }
357                 if(replyBody.getCapabilities().isOFPMFPKTPS()){
358                     supportedCapabilities.add(MeterPktps.class);
359
360                 }
361                 if(replyBody.getCapabilities().isOFPMFSTATS()){
362                     supportedCapabilities.add(MeterStats.class);
363
364                 }
365                 message.setMeterCapabilitiesSupported(supportedCapabilities);
366
367                 List<Class<? extends MeterBand>> supportedMeterBand =
368                         new ArrayList<Class <? extends MeterBand>>();
369                 if(replyBody.getBandTypes().isOFPMBTDROP()){
370                     supportedMeterBand.add(MeterBandDrop.class);
371                 }
372                 if(replyBody.getBandTypes().isOFPMBTDSCPREMARK()){
373                     supportedMeterBand.add(MeterBandDscpRemark.class);
374                 }
375                 message.setMeterBandSupported(supportedMeterBand);
376                 listDataObject.add(message.build());
377
378                 return listDataObject;
379             }
380             case OFPMPTABLE: {
381                 logger.debug("Received flow table statistics reponse from openflow {} switch",msg.getVersion()==1?"1.0":"1.3+");
382
383                 FlowTableStatisticsUpdateBuilder message = new FlowTableStatisticsUpdateBuilder();
384                 message.setId(node);
385                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
386                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
387
388                 MultipartReplyTableCase caseBody = (MultipartReplyTableCase)mpReply.getMultipartReplyBody();
389                 MultipartReplyTable replyBody = caseBody.getMultipartReplyTable();
390                 List<TableStats> swTablesStats = replyBody.getTableStats();
391
392                 List<FlowTableAndStatisticsMap> salFlowStats = new ArrayList<FlowTableAndStatisticsMap>();
393                 for(TableStats swTableStats : swTablesStats){
394                     FlowTableAndStatisticsMapBuilder statisticsBuilder  = new FlowTableAndStatisticsMapBuilder();
395
396                     statisticsBuilder.setActiveFlows(new Counter32(swTableStats.getActiveCount()));
397                     statisticsBuilder.setPacketsLookedUp(new Counter64(swTableStats.getLookupCount()));
398                     statisticsBuilder.setPacketsMatched(new Counter64(swTableStats.getMatchedCount()));
399                     statisticsBuilder.setTableId(new TableId(swTableStats.getTableId()));
400                     salFlowStats.add(statisticsBuilder.build());
401                 }
402
403                 message.setFlowTableAndStatisticsMap(salFlowStats);
404
405                 logger.debug("Converted flow table statistics : {}",message.build().toString());
406                 listDataObject.add(message.build());
407                 return listDataObject;
408             }
409             case OFPMPQUEUE: {
410                 logger.debug("Received queue statistics multipart response");
411
412                 QueueStatisticsUpdateBuilder message = new QueueStatisticsUpdateBuilder();
413                 message.setId(node);
414                 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
415                 message.setTransactionId(generateTransactionId(mpReply.getXid()));
416
417                 MultipartReplyQueueCase caseBody = (MultipartReplyQueueCase)mpReply.getMultipartReplyBody();
418                 MultipartReplyQueue replyBody = caseBody.getMultipartReplyQueue();
419
420                 List<QueueIdAndStatisticsMap> statsMap =
421                         new ArrayList<QueueIdAndStatisticsMap>();
422
423                 for (QueueStats queueStats: replyBody.getQueueStats()){
424
425                     QueueIdAndStatisticsMapBuilder statsBuilder =
426                             new QueueIdAndStatisticsMapBuilder();
427                     statsBuilder.setNodeConnectorId(
428                             InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(sc.getFeatures().getDatapathId(),
429                                     queueStats.getPortNo(), ofVersion));
430                     statsBuilder.setTransmissionErrors(new Counter64(queueStats.getTxErrors()));
431                     statsBuilder.setTransmittedBytes(new Counter64(queueStats.getTxBytes()));
432                     statsBuilder.setTransmittedPackets(new Counter64(queueStats.getTxPackets()));
433
434                     DurationBuilder durationBuilder = new DurationBuilder();
435                     durationBuilder.setSecond(new Counter32(queueStats.getDurationSec()));
436                     durationBuilder.setNanosecond(new Counter32(queueStats.getDurationNsec()));
437                     statsBuilder.setDuration(durationBuilder.build());
438
439                     statsBuilder.setQueueId(new QueueId(queueStats.getQueueId()));
440                     statsBuilder.setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(sc.getFeatures().getDatapathId(),
441                             queueStats.getPortNo(), ofVersion));
442
443                     statsMap.add(statsBuilder.build());
444                 }
445                 message.setQueueIdAndStatisticsMap(statsMap);
446
447                 logger.debug("Converted queue statistics : {}",message.build().toString());
448                 listDataObject.add(message.build());
449                 return listDataObject;
450             }
451
452             default:
453                 return listDataObject;
454             }
455         }
456
457         return listDataObject;
458     }
459
460     private static NodeId nodeIdFromDatapathId(final BigInteger datapathId) {
461         String current = datapathId.toString();
462         return new NodeId("openflow:" + current);
463     }
464
465     private static TransactionId generateTransactionId(final Long xid){
466         BigInteger bigIntXid = BigInteger.valueOf(xid);
467         return new TransactionId(bigIntXid);
468     }
469
470     /*
471      * Method returns the bitmap of actions supported by each group.
472      * TODO: My recommendation would be, its good to have a respective model of
473      * 'type bits', which will generate a class where all these flags will eventually
474      * be stored as boolean. It will be convenient for application to check the
475      * supported action, rather then doing bitmap operation.
476      * @param actionsSupported
477      * @return
478      */
479     private static List<Long> getGroupActionsSupportBitmap(final List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType> actionsSupported){
480         List<Long> supportActionByGroups = new ArrayList<Long>();
481         for(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType supportedActions : actionsSupported){
482             long supportActionBitmap = 0;
483             supportActionBitmap |= supportedActions.isOFPATOUTPUT()?(1 << 0): 0;
484             supportActionBitmap |= supportedActions.isOFPATCOPYTTLOUT()?(1 << 11): 0;
485             supportActionBitmap |= supportedActions.isOFPATCOPYTTLIN()?(1 << 12): 0;
486             supportActionBitmap |= supportedActions.isOFPATSETMPLSTTL()?(1 << 15): 0;
487             supportActionBitmap |= supportedActions.isOFPATDECMPLSTTL()?(1 << 16): 0;
488             supportActionBitmap |= supportedActions.isOFPATPUSHVLAN()?(1 << 17): 0;
489             supportActionBitmap |= supportedActions.isOFPATPOPVLAN()?(1 << 18): 0;
490             supportActionBitmap |= supportedActions.isOFPATPUSHMPLS()?(1 << 19): 0;
491             supportActionBitmap |= supportedActions.isOFPATPOPMPLS()?(1 << 20): 0;
492             supportActionBitmap |= supportedActions.isOFPATSETQUEUE()?(1 << 21): 0;
493             supportActionBitmap |= supportedActions.isOFPATGROUP()?(1 << 22): 0;
494             supportActionBitmap |= supportedActions.isOFPATSETNWTTL()?(1 << 23): 0;
495             supportActionBitmap |= supportedActions.isOFPATDECNWTTL()?(1 << 24): 0;
496             supportActionBitmap |= supportedActions.isOFPATSETFIELD()?(1 << 25): 0;
497             supportActionBitmap |= supportedActions.isOFPATPUSHPBB()?(1 << 26): 0;
498             supportActionBitmap |= supportedActions.isOFPATPOPPBB()?(1 << 27): 0;
499             supportActionByGroups.add(Long.valueOf(supportActionBitmap));
500         }
501         return supportActionByGroups;
502     }
503
504 }