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