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