Bug 5540 - FlowConvertor, FlowStatsResponseConvertor, FlowInstructionResponseConvertor
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / statistics / SinglePurposeMultipartReplyTranslator.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.openflowplugin.impl.statistics;
9
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.List;
14 import java.util.Optional;
15 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
16 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
17 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
18 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
19 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdateBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdateBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdateBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
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.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
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.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCase;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCase;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCase;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase;
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.MultipartReplyQueueCase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregate;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.MultipartReplyGroupDesc;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.MultipartReplyMeterConfig;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeatures;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats;
84 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;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTable;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdateBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapKey;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueStatisticsUpdateBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
97 import org.opendaylight.yangtools.yang.binding.DataObject;
98 import org.slf4j.Logger;
99 import org.slf4j.LoggerFactory;
100
101 /**
102  * Class converts multipart reply messages to the notification objects defined
103  * by statistics provider (manager ). It is ment to be replaced by translators
104  * and to be used for translating statistics data only.
105  *
106  * @author avishnoi@in.ibm.com
107  */
108 @Deprecated
109 public class SinglePurposeMultipartReplyTranslator {
110
111     protected static final Logger logger = LoggerFactory
112             .getLogger(SinglePurposeMultipartReplyTranslator.class);
113
114     public List<DataObject> translate(final BigInteger datapathId, final short version, final OfHeader msg) {
115
116         List<DataObject> listDataObject = new ArrayList<>();
117
118         if (msg instanceof MultipartReplyMessage) {
119             MultipartReplyMessage mpReply = (MultipartReplyMessage) msg;
120             OpenflowVersion ofVersion = OpenflowVersion.get(version);
121             NodeId node = nodeIdFromDatapathId(datapathId);
122             VersionDatapathIdConvertorData versionDatapathIdConvertorData = new VersionDatapathIdConvertorData(version);
123             versionDatapathIdConvertorData.setDatapathId(datapathId);
124             VersionConvertorData simpleConvertorData = new VersionConvertorData(version);
125
126             translateFlow(listDataObject, mpReply, node, versionDatapathIdConvertorData);
127             translateAggregate(listDataObject, mpReply, node);
128             translatePortStats(listDataObject, mpReply, node, ofVersion, datapathId);
129             translateGroup(listDataObject, mpReply, node);
130             translateGroupDesc(listDataObject, mpReply, node, simpleConvertorData);
131             translateGroupFeatures(listDataObject, mpReply, node);
132             translateMeter(listDataObject, mpReply, node);
133             translateMeterConfig(listDataObject, mpReply, node);
134             translateMeterFeatures(listDataObject, mpReply, node);
135             translateTable(listDataObject, mpReply, node);
136             translateQueue(listDataObject, mpReply, node, ofVersion, datapathId);
137         }
138
139         return listDataObject;
140     }
141
142     private static void translateFlow(final List<DataObject> listDataObject,
143                                       final MultipartReplyMessage mpReply,
144                                       final NodeId node, VersionDatapathIdConvertorData versionDatapathIdConvertorData) {
145         if (!MultipartType.OFPMPFLOW.equals(mpReply.getType())) {
146             return;
147         }
148
149         FlowsStatisticsUpdateBuilder message = new FlowsStatisticsUpdateBuilder();
150         message.setId(node);
151         message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
152         message.setTransactionId(generateTransactionId(mpReply.getXid()));
153         MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase) mpReply.getMultipartReplyBody();
154         MultipartReplyFlow replyBody = caseBody.getMultipartReplyFlow();
155         final Optional<List<FlowAndStatisticsMapList>> flowAndStatisticsMapLists =
156                 ConvertorManager.getInstance().convert(replyBody.getFlowStats(), versionDatapathIdConvertorData);
157
158         message.setFlowAndStatisticsMapList(flowAndStatisticsMapLists.orElse(Collections.emptyList()));
159
160         listDataObject.add(message.build());
161     }
162
163     private static void translateAggregate(final List<DataObject> listDataObject,
164                                            final MultipartReplyMessage mpReply,
165                                            final NodeId node) {
166         if (!MultipartType.OFPMPAGGREGATE.equals(mpReply.getType())) {
167             return;
168         }
169
170         AggregateFlowStatisticsUpdateBuilder message = new AggregateFlowStatisticsUpdateBuilder();
171         message.setId(node);
172         message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
173         message.setTransactionId(generateTransactionId(mpReply.getXid()));
174
175         MultipartReplyAggregateCase caseBody = (MultipartReplyAggregateCase) mpReply.getMultipartReplyBody();
176         MultipartReplyAggregate replyBody = caseBody.getMultipartReplyAggregate();
177         message.setByteCount(new Counter64(replyBody.getByteCount()));
178         message.setPacketCount(new Counter64(replyBody.getPacketCount()));
179         message.setFlowCount(new Counter32(replyBody.getFlowCount()));
180
181         listDataObject.add(message.build());
182     }
183
184     private static void translatePortStats(final List<DataObject> listDataObject,
185                                            final MultipartReplyMessage mpReply,
186                                            final NodeId node,
187                                            final OpenflowVersion ofVersion,
188                                            final BigInteger datapathId) {
189         if (!MultipartType.OFPMPPORTSTATS.equals(mpReply.getType())) {
190             return;
191         }
192
193         NodeConnectorStatisticsUpdateBuilder message = new NodeConnectorStatisticsUpdateBuilder();
194         message.setId(node);
195         message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
196         message.setTransactionId(generateTransactionId(mpReply.getXid()));
197
198         MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase) mpReply.getMultipartReplyBody();
199         MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats();
200
201         List<NodeConnectorStatisticsAndPortNumberMap> statsMap =
202                 new ArrayList<>();
203         for (PortStats portStats : replyBody.getPortStats()) {
204
205             NodeConnectorStatisticsAndPortNumberMapBuilder statsBuilder =
206                     new NodeConnectorStatisticsAndPortNumberMapBuilder();
207             statsBuilder.setNodeConnectorId(
208                     InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
209                             portStats.getPortNo(), ofVersion));
210
211             BytesBuilder bytesBuilder = new BytesBuilder();
212             bytesBuilder.setReceived(portStats.getRxBytes());
213             bytesBuilder.setTransmitted(portStats.getTxBytes());
214             statsBuilder.setBytes(bytesBuilder.build());
215
216             PacketsBuilder packetsBuilder = new PacketsBuilder();
217             packetsBuilder.setReceived(portStats.getRxPackets());
218             packetsBuilder.setTransmitted(portStats.getTxPackets());
219             statsBuilder.setPackets(packetsBuilder.build());
220
221             DurationBuilder durationBuilder = new DurationBuilder();
222             if (portStats.getDurationSec() != null) {
223                 durationBuilder.setSecond(new Counter32(portStats.getDurationSec()));
224             }
225             if (portStats.getDurationNsec() != null) {
226                 durationBuilder.setNanosecond(new Counter32(portStats.getDurationNsec()));
227             }
228             statsBuilder.setDuration(durationBuilder.build());
229             statsBuilder.setCollisionCount(portStats.getCollisions());
230             statsBuilder.setKey(new NodeConnectorStatisticsAndPortNumberMapKey(statsBuilder.getNodeConnectorId()));
231             statsBuilder.setReceiveCrcError(portStats.getRxCrcErr());
232             statsBuilder.setReceiveDrops(portStats.getRxDropped());
233             statsBuilder.setReceiveErrors(portStats.getRxErrors());
234             statsBuilder.setReceiveFrameError(portStats.getRxFrameErr());
235             statsBuilder.setReceiveOverRunError(portStats.getRxOverErr());
236             statsBuilder.setTransmitDrops(portStats.getTxDropped());
237             statsBuilder.setTransmitErrors(portStats.getTxErrors());
238
239             statsMap.add(statsBuilder.build());
240         }
241         message.setNodeConnectorStatisticsAndPortNumberMap(statsMap);
242
243
244         listDataObject.add(message.build());
245     }
246
247     private static void translateGroup(final List<DataObject> listDataObject,
248                                        final MultipartReplyMessage mpReply,
249                                        final NodeId node) {
250         if (!MultipartType.OFPMPGROUP.equals(mpReply.getType())) {
251             return;
252         }
253
254         GroupStatisticsUpdatedBuilder message = new GroupStatisticsUpdatedBuilder();
255         message.setId(node);
256         message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
257         message.setTransactionId(generateTransactionId(mpReply.getXid()));
258         MultipartReplyGroupCase caseBody = (MultipartReplyGroupCase) mpReply.getMultipartReplyBody();
259         MultipartReplyGroup replyBody = caseBody.getMultipartReplyGroup();
260         final Optional<List<GroupStats>> groupStatsList = ConvertorManager.getInstance().convert(
261                 replyBody.getGroupStats());
262
263         message.setGroupStats(groupStatsList.orElse(Collections.emptyList()));
264
265         listDataObject.add(message.build());
266     }
267
268     private static void translateGroupDesc(final List<DataObject> listDataObject,
269                                            final MultipartReplyMessage mpReply,
270                                            final NodeId node,
271                                            VersionConvertorData simpleConvertorData) {
272         if (!MultipartType.OFPMPGROUPDESC.equals(mpReply.getType())) {
273             return;
274         }
275
276         GroupDescStatsUpdatedBuilder message = new GroupDescStatsUpdatedBuilder();
277         message.setId(node);
278         message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
279         message.setTransactionId(generateTransactionId(mpReply.getXid()));
280         MultipartReplyGroupDescCase caseBody = (MultipartReplyGroupDescCase) mpReply.getMultipartReplyBody();
281         MultipartReplyGroupDesc replyBody = caseBody.getMultipartReplyGroupDesc();
282
283         final Optional<List<GroupDescStats>> groupDescStatsList = ConvertorManager.getInstance().convert(
284                 replyBody.getGroupDesc(), simpleConvertorData);
285
286         message.setGroupDescStats(groupDescStatsList.orElse(Collections.emptyList()));
287
288         listDataObject.add(message.build());
289     }
290
291     private static void translateGroupFeatures(final List<DataObject> listDataObject,
292                                                final MultipartReplyMessage mpReply,
293                                                final NodeId node) {
294         if (!MultipartType.OFPMPGROUPFEATURES.equals(mpReply.getType())) {
295             return;
296         }
297
298         GroupFeaturesUpdatedBuilder message = new GroupFeaturesUpdatedBuilder();
299         message.setId(node);
300         message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
301         message.setTransactionId(generateTransactionId(mpReply.getXid()));
302         MultipartReplyGroupFeaturesCase caseBody = (MultipartReplyGroupFeaturesCase) mpReply.getMultipartReplyBody();
303         MultipartReplyGroupFeatures replyBody = caseBody.getMultipartReplyGroupFeatures();
304         List<Class<? extends GroupType>> supportedGroups =
305                 new ArrayList<>();
306
307         if (replyBody.getTypes().isOFPGTALL()) {
308             supportedGroups.add(GroupAll.class);
309         }
310         if (replyBody.getTypes().isOFPGTSELECT()) {
311             supportedGroups.add(GroupSelect.class);
312         }
313         if (replyBody.getTypes().isOFPGTINDIRECT()) {
314             supportedGroups.add(GroupIndirect.class);
315         }
316         if (replyBody.getTypes().isOFPGTFF()) {
317             supportedGroups.add(GroupFf.class);
318         }
319         message.setGroupTypesSupported(supportedGroups);
320         message.setMaxGroups(replyBody.getMaxGroups());
321
322         List<Class<? extends GroupCapability>> supportedCapabilities =
323                 new ArrayList<>();
324
325         if (replyBody.getCapabilities().isOFPGFCCHAINING()) {
326             supportedCapabilities.add(Chaining.class);
327         }
328         if (replyBody.getCapabilities().isOFPGFCCHAININGCHECKS()) {
329             supportedCapabilities.add(ChainingChecks.class);
330         }
331         if (replyBody.getCapabilities().isOFPGFCSELECTLIVENESS()) {
332             supportedCapabilities.add(SelectLiveness.class);
333         }
334         if (replyBody.getCapabilities().isOFPGFCSELECTWEIGHT()) {
335             supportedCapabilities.add(SelectWeight.class);
336         }
337
338         message.setGroupCapabilitiesSupported(supportedCapabilities);
339
340         message.setActions(getGroupActionsSupportBitmap(replyBody.getActionsBitmap()));
341         listDataObject.add(message.build());
342     }
343
344     private static void translateMeter(final List<DataObject> listDataObject,
345                                        final MultipartReplyMessage mpReply,
346                                        final NodeId node) {
347         if (!MultipartType.OFPMPMETER.equals(mpReply.getType())) {
348             return;
349         }
350
351         MeterStatisticsUpdatedBuilder message = new MeterStatisticsUpdatedBuilder();
352         message.setId(node);
353         message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
354         message.setTransactionId(generateTransactionId(mpReply.getXid()));
355
356         MultipartReplyMeterCase caseBody = (MultipartReplyMeterCase) mpReply.getMultipartReplyBody();
357         MultipartReplyMeter replyBody = caseBody.getMultipartReplyMeter();
358         final Optional<List<org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats>> meterStatsList =
359                 ConvertorManager.getInstance().convert(replyBody.getMeterStats());
360
361         message.setMeterStats(meterStatsList.orElse(Collections.emptyList()));
362
363         listDataObject.add(message.build());
364     }
365
366     private static void translateMeterConfig(final List<DataObject> listDataObject,
367                                              final MultipartReplyMessage mpReply,
368                                              final NodeId node) {
369         if (!MultipartType.OFPMPMETERCONFIG.equals(mpReply.getType())) {
370             return;
371         }
372
373         MeterConfigStatsUpdatedBuilder message = new MeterConfigStatsUpdatedBuilder();
374         message.setId(node);
375         message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
376         message.setTransactionId(generateTransactionId(mpReply.getXid()));
377
378         MultipartReplyMeterConfigCase caseBody = (MultipartReplyMeterConfigCase) mpReply.getMultipartReplyBody();
379         MultipartReplyMeterConfig replyBody = caseBody.getMultipartReplyMeterConfig();
380         final Optional<List<MeterConfigStats>> meterConfigStatsList = ConvertorManager.getInstance().convert(replyBody.getMeterConfig());
381
382         message.setMeterConfigStats(meterConfigStatsList.orElse(Collections.emptyList()));
383
384         listDataObject.add(message.build());
385     }
386
387     private static void translateMeterFeatures(final List<DataObject> listDataObject,
388                                                final MultipartReplyMessage mpReply,
389                                                final NodeId node) {
390         if (!MultipartType.OFPMPMETERFEATURES.equals(mpReply.getType())) {
391             return;
392         }
393
394         //Convert OF message and send it to SAL listener
395         MeterFeaturesUpdatedBuilder message = new MeterFeaturesUpdatedBuilder();
396         message.setId(node);
397         message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
398         message.setTransactionId(generateTransactionId(mpReply.getXid()));
399
400         MultipartReplyMeterFeaturesCase caseBody = (MultipartReplyMeterFeaturesCase) mpReply.getMultipartReplyBody();
401         MultipartReplyMeterFeatures replyBody = caseBody.getMultipartReplyMeterFeatures();
402         message.setMaxBands(replyBody.getMaxBands());
403         message.setMaxColor(replyBody.getMaxColor());
404         message.setMaxMeter(new Counter32(replyBody.getMaxMeter()));
405
406         List<Class<? extends MeterCapability>> supportedCapabilities =
407                 new ArrayList<>();
408         if (replyBody.getCapabilities().isOFPMFBURST()) {
409             supportedCapabilities.add(MeterBurst.class);
410         }
411         if (replyBody.getCapabilities().isOFPMFKBPS()) {
412             supportedCapabilities.add(MeterKbps.class);
413
414         }
415         if (replyBody.getCapabilities().isOFPMFPKTPS()) {
416             supportedCapabilities.add(MeterPktps.class);
417
418         }
419         if (replyBody.getCapabilities().isOFPMFSTATS()) {
420             supportedCapabilities.add(MeterStats.class);
421
422         }
423         message.setMeterCapabilitiesSupported(supportedCapabilities);
424
425         List<Class<? extends MeterBand>> supportedMeterBand =
426                 new ArrayList<>();
427         if (replyBody.getBandTypes().isOFPMBTDROP()) {
428             supportedMeterBand.add(MeterBandDrop.class);
429         }
430         if (replyBody.getBandTypes().isOFPMBTDSCPREMARK()) {
431             supportedMeterBand.add(MeterBandDscpRemark.class);
432         }
433         message.setMeterBandSupported(supportedMeterBand);
434         listDataObject.add(message.build());
435     }
436
437     private static void translateTable(final List<DataObject> listDataObject,
438                                        final MultipartReplyMessage mpReply,
439                                        final NodeId node) {
440         if (!MultipartType.OFPMPTABLE.equals(mpReply.getType())) {
441             return;
442         }
443
444         FlowTableStatisticsUpdateBuilder message = new FlowTableStatisticsUpdateBuilder();
445         message.setId(node);
446         message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
447         message.setTransactionId(generateTransactionId(mpReply.getXid()));
448
449         MultipartReplyTableCase caseBody = (MultipartReplyTableCase) mpReply.getMultipartReplyBody();
450         MultipartReplyTable replyBody = caseBody.getMultipartReplyTable();
451         List<TableStats> swTablesStats = replyBody.getTableStats();
452
453         List<FlowTableAndStatisticsMap> salFlowStats = new ArrayList<FlowTableAndStatisticsMap>();
454         for (TableStats swTableStats : swTablesStats) {
455             FlowTableAndStatisticsMapBuilder statisticsBuilder = new FlowTableAndStatisticsMapBuilder();
456
457             statisticsBuilder.setActiveFlows(new Counter32(swTableStats.getActiveCount()));
458             statisticsBuilder.setPacketsLookedUp(new Counter64(swTableStats.getLookupCount()));
459             statisticsBuilder.setPacketsMatched(new Counter64(swTableStats.getMatchedCount()));
460             statisticsBuilder.setTableId(new TableId(swTableStats.getTableId()));
461             salFlowStats.add(statisticsBuilder.build());
462         }
463
464         message.setFlowTableAndStatisticsMap(salFlowStats);
465         listDataObject.add(message.build());
466     }
467
468     private static void translateQueue(final List<DataObject> listDataObject,
469                                        final MultipartReplyMessage mpReply,
470                                        final NodeId node,
471                                        final OpenflowVersion ofVersion,
472                                        final BigInteger datapathId) {
473         if (!MultipartType.OFPMPQUEUE.equals(mpReply.getType())) {
474             return;
475         }
476
477         QueueStatisticsUpdateBuilder message = new QueueStatisticsUpdateBuilder();
478         message.setId(node);
479         message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
480         message.setTransactionId(generateTransactionId(mpReply.getXid()));
481
482         MultipartReplyQueueCase caseBody = (MultipartReplyQueueCase) mpReply.getMultipartReplyBody();
483         MultipartReplyQueue replyBody = caseBody.getMultipartReplyQueue();
484
485         List<QueueIdAndStatisticsMap> statsMap =
486                 new ArrayList<QueueIdAndStatisticsMap>();
487
488         for (QueueStats queueStats : replyBody.getQueueStats()) {
489
490             QueueIdAndStatisticsMapBuilder statsBuilder =
491                     new QueueIdAndStatisticsMapBuilder();
492             statsBuilder.setNodeConnectorId(
493                     InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
494                             queueStats.getPortNo(), ofVersion));
495             statsBuilder.setTransmissionErrors(new Counter64(queueStats.getTxErrors()));
496             statsBuilder.setTransmittedBytes(new Counter64(queueStats.getTxBytes()));
497             statsBuilder.setTransmittedPackets(new Counter64(queueStats.getTxPackets()));
498
499             DurationBuilder durationBuilder = new DurationBuilder();
500             durationBuilder.setSecond(new Counter32(queueStats.getDurationSec()));
501             durationBuilder.setNanosecond(new Counter32(queueStats.getDurationNsec()));
502             statsBuilder.setDuration(durationBuilder.build());
503
504             statsBuilder.setQueueId(new QueueId(queueStats.getQueueId()));
505             statsBuilder.setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
506                     queueStats.getPortNo(), ofVersion));
507
508             statsMap.add(statsBuilder.build());
509         }
510         message.setQueueIdAndStatisticsMap(statsMap);
511
512         listDataObject.add(message.build());
513     }
514
515     private static NodeId nodeIdFromDatapathId(final BigInteger datapathId) {
516         String current = datapathId.toString();
517         return new NodeId("openflow:" + current);
518     }
519
520     private static TransactionId generateTransactionId(final Long xid) {
521         BigInteger bigIntXid = BigInteger.valueOf(xid);
522         return new TransactionId(bigIntXid);
523     }
524
525     /*
526      * Method returns the bitmap of actions supported by each group.
527      *
528      * @param actionsSupported
529      * @return
530      */
531     static List<Long> getGroupActionsSupportBitmap(final List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType> actionsSupported) {
532         List<Long> supportActionByGroups = new ArrayList<Long>();
533         for (org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType supportedActions : actionsSupported) {
534             long supportActionBitmap = 0;
535             supportActionBitmap |= supportedActions.isOFPATOUTPUT() ? (1 << 0) : 0;
536             supportActionBitmap |= supportedActions.isOFPATCOPYTTLOUT() ? (1 << 11) : 0;
537             supportActionBitmap |= supportedActions.isOFPATCOPYTTLIN() ? (1 << 12) : 0;
538             supportActionBitmap |= supportedActions.isOFPATSETMPLSTTL() ? (1 << 15) : 0;
539             supportActionBitmap |= supportedActions.isOFPATDECMPLSTTL() ? (1 << 16) : 0;
540             supportActionBitmap |= supportedActions.isOFPATPUSHVLAN() ? (1 << 17) : 0;
541             supportActionBitmap |= supportedActions.isOFPATPOPVLAN() ? (1 << 18) : 0;
542             supportActionBitmap |= supportedActions.isOFPATPUSHMPLS() ? (1 << 19) : 0;
543             supportActionBitmap |= supportedActions.isOFPATPOPMPLS() ? (1 << 20) : 0;
544             supportActionBitmap |= supportedActions.isOFPATSETQUEUE() ? (1 << 21) : 0;
545             supportActionBitmap |= supportedActions.isOFPATGROUP() ? (1 << 22) : 0;
546             supportActionBitmap |= supportedActions.isOFPATSETNWTTL() ? (1 << 23) : 0;
547             supportActionBitmap |= supportedActions.isOFPATDECNWTTL() ? (1 << 24) : 0;
548             supportActionBitmap |= supportedActions.isOFPATSETFIELD() ? (1 << 25) : 0;
549             supportActionBitmap |= supportedActions.isOFPATPUSHPBB() ? (1 << 26) : 0;
550             supportActionBitmap |= supportedActions.isOFPATPOPPBB() ? (1 << 27) : 0;
551             supportActionByGroups.add(Long.valueOf(supportActionBitmap));
552         }
553         return supportActionByGroups;
554     }
555
556 }