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