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