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