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