Merge "OPNFLWPLUG-1000 : Execute reconciliation asynchronously when the user selected...
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / common / MultipartReplyTranslatorUtil.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies s.r.o. 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
9 package org.opendaylight.openflowplugin.impl.common;
10
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.Optional;
16 import java.util.stream.Collectors;
17 import javax.annotation.Nullable;
18 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
19 import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
20 import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
21 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
22 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
23 import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
24 import org.opendaylight.openflowplugin.impl.util.GroupUtil;
25 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
26 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.FlowStatsResponseConvertorData;
27 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
28 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
29 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.multipart.reply.multipart.reply.body.MultipartReplyDescBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowAggregateStats;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowAggregateStatsBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStats;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStatsBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.multipart.reply.multipart.reply.body.MultipartReplyFlowTableStats;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.multipart.reply.multipart.reply.body.MultipartReplyFlowTableStatsBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.multipart.reply.multipart.reply.body.MultipartReplyPortDesc;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.multipart.reply.multipart.reply.body.MultipartReplyPortDescBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.multipart.reply.multipart.reply.body.multipart.reply.port.desc.PortsBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupDescBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupStats;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupStatsBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Chaining;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.ChainingChecks;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupAll;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupCapability;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFf;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupIndirect;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupSelect;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupType;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectLiveness;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectWeight;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterStats;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterStatsBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBand;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDrop;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDscpRemark;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBurst;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterCapability;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterKbps;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterPktps;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterStats;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.multipart.reply.MultipartReplyBody;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortGrouping;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCase;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCase;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCase;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCase;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCase;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregate;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.MultipartReplyGroupDesc;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.MultipartReplyMeterConfig;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeatures;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats;
107 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;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTable;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.multipart.reply.multipart.reply.body.MultipartReplyPortStatsBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapKey;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.multipart.reply.multipart.reply.body.MultipartReplyQueueStats;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.multipart.reply.multipart.reply.body.MultipartReplyQueueStatsBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesBuilder;
123 import org.slf4j.Logger;
124 import org.slf4j.LoggerFactory;
125
126 /**
127  * Class converts multipart reply messages to the objects that can be then written to datastore using
128  * multipart writers.
129  */
130 public final class MultipartReplyTranslatorUtil {
131     private static final Logger LOG = LoggerFactory.getLogger(MultipartReplyTranslatorUtil.class);
132
133     private MultipartReplyTranslatorUtil() {
134     }
135
136     public static Optional<? extends MultipartReplyBody> translate(
137             final OfHeader message,
138             final DeviceInfo deviceInfo,
139             @Nullable final ConvertorExecutor convertorExecutor,
140             @Nullable final TranslatorLibrary translatorLibrary) {
141
142         if (message instanceof MultipartReply) {
143             final Optional<ConvertorExecutor> convertor = Optional.ofNullable(convertorExecutor);
144             final Optional<TranslatorLibrary> translator = Optional.ofNullable(translatorLibrary);
145             final MultipartReply msg = MultipartReply.class.cast(message);
146             final OpenflowVersion ofVersion = OpenflowVersion.get(deviceInfo.getVersion());
147             final VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(deviceInfo.getVersion());
148             data.setDatapathId(deviceInfo.getDatapathId());
149
150             switch (msg.getType()) {
151                 case OFPMPFLOW:
152                     return convertor.flatMap(c -> Optional.of(translateFlow(msg, data, c)));
153                 case OFPMPAGGREGATE:
154                     return Optional.of(translateAggregate(msg));
155                 case OFPMPPORTSTATS:
156                     return Optional.of(translatePortStats(msg, ofVersion, deviceInfo.getDatapathId()));
157                 case OFPMPGROUP:
158                     return convertor.flatMap(c -> Optional.of(translateGroup(msg, data, c)));
159                 case OFPMPGROUPDESC:
160                     return convertor.flatMap(c -> Optional.of(translateGroupDesc(msg, data, c)));
161                 case OFPMPGROUPFEATURES:
162                     return Optional.of(translateGroupFeatures(msg));
163                 case OFPMPMETER:
164                     return convertor.flatMap(c -> Optional.of(translateMeter(msg, data, c)));
165                 case OFPMPMETERCONFIG:
166                     return convertor.flatMap(c -> Optional.of(translateMeterConfig(msg, data, c)));
167                 case OFPMPMETERFEATURES:
168                     return Optional.of(translateMeterFeatures(msg));
169                 case OFPMPTABLE:
170                     return Optional.of(translateTable(msg));
171                 case OFPMPQUEUE:
172                     return Optional.of(translateQueue(msg, ofVersion, deviceInfo.getDatapathId()));
173                 case OFPMPDESC:
174                     return Optional.of(translateDesc(msg));
175                 case OFPMPTABLEFEATURES:
176                     return convertor.flatMap(c -> Optional.of(translateTableFeatures(msg, deviceInfo.getVersion(), c)));
177                 case OFPMPPORTDESC:
178                     return translator.flatMap(t -> Optional.of(translatePortDesc(msg, deviceInfo, t)));
179                 default:
180             }
181         } else if (message instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112
182             .MultipartReply) {
183             return Optional.of(org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112
184                 .MultipartReply.class.cast(message).getMultipartReplyBody());
185         }
186
187         LOG.debug("Failed to translate {} for node {}.", message.getImplementedInterface(), deviceInfo);
188         return Optional.empty();
189     }
190
191     private static MultipartReplyPortDesc translatePortDesc(final MultipartReply msg,
192                                                             final DeviceInfo deviceInfo,
193                                                             final TranslatorLibrary translatorLibrary) {
194         return new MultipartReplyPortDescBuilder()
195             .setPorts(((MultipartReplyPortDescCase) msg.getMultipartReplyBody())
196                 .getMultipartReplyPortDesc()
197                 .getPorts()
198                 .stream()
199                 .map(port -> {
200                     final TranslatorKey translatorKey = new TranslatorKey(
201                         deviceInfo.getVersion(),
202                         PortGrouping.class.getName());
203
204                     final MessageTranslator<PortGrouping, FlowCapableNodeConnector> translator = translatorLibrary
205                         .lookupTranslator(translatorKey);
206
207                     return new PortsBuilder(translator
208                         .translate(port, deviceInfo, null))
209                         .build();
210                 })
211                 .collect(Collectors.toList()))
212             .build();
213     }
214
215     private static org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.multipart.reply.multipart
216             .reply.body.MultipartReplyTableFeatures translateTableFeatures(
217                     final MultipartReply msg,
218                     final short version,
219                     final ConvertorExecutor convertorExecutor) {
220         MultipartReplyTableFeaturesCase caseBody = (MultipartReplyTableFeaturesCase) msg.getMultipartReplyBody();
221         final MultipartReplyTableFeatures multipartReplyTableFeatures = caseBody.getMultipartReplyTableFeatures();
222         final Optional<List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features
223             .TableFeatures>> tableFeaturesList = convertorExecutor
224             .convert(multipartReplyTableFeatures, new VersionConvertorData(version));
225
226         return new MultipartReplyTableFeaturesBuilder()
227             .setTableFeatures(tableFeaturesList.orElse(Collections.emptyList()))
228             .build();
229     }
230
231     private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.multipart.reply.multipart
232             .reply.body.MultipartReplyDesc translateDesc(final MultipartReply msg) {
233         final MultipartReplyDesc desc = ((MultipartReplyDescCase) msg.getMultipartReplyBody()).getMultipartReplyDesc();
234
235         return new MultipartReplyDescBuilder()
236             .setDescription(desc.getDpDesc())
237             .setHardware(desc.getHwDesc())
238             .setManufacturer(desc.getMfrDesc())
239             .setSoftware(desc.getSwDesc())
240             .setSerialNumber(desc.getSerialNum())
241             .build();
242     }
243
244     private static MultipartReplyFlowStats translateFlow(final MultipartReply msg,
245                                                          final VersionDatapathIdConvertorData data,
246                                                          final ConvertorExecutor convertorExecutor) {
247         FlowStatsResponseConvertorData flowData = new FlowStatsResponseConvertorData(data.getVersion());
248         flowData.setDatapathId(data.getDatapathId());
249         flowData.setMatchPath(MatchPath.FLOWS_STATISTICS_UPDATE_MATCH);
250         MultipartReplyFlowStatsBuilder message = new MultipartReplyFlowStatsBuilder();
251         MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase) msg.getMultipartReplyBody();
252         MultipartReplyFlow replyBody = caseBody.getMultipartReplyFlow();
253         final Optional<List<FlowAndStatisticsMapList>> flowAndStatisticsMapLists =
254             convertorExecutor.convert(replyBody.getFlowStats(), flowData);
255
256         message.setFlowAndStatisticsMapList(flowAndStatisticsMapLists.orElse(Collections.emptyList()));
257         return message.build();
258     }
259
260     private static MultipartReplyFlowAggregateStats translateAggregate(final MultipartReply msg) {
261         MultipartReplyFlowAggregateStatsBuilder message = new MultipartReplyFlowAggregateStatsBuilder();
262         MultipartReplyAggregateCase caseBody = (MultipartReplyAggregateCase) msg.getMultipartReplyBody();
263         MultipartReplyAggregate replyBody = caseBody.getMultipartReplyAggregate();
264         message.setByteCount(new Counter64(replyBody.getByteCount()));
265         message.setPacketCount(new Counter64(replyBody.getPacketCount()));
266         message.setFlowCount(new Counter32(replyBody.getFlowCount()));
267         return message.build();
268     }
269
270     private static org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.multipart.reply.multipart
271             .reply.body.MultipartReplyPortStats translatePortStats(
272                     final MultipartReply msg,
273                     final OpenflowVersion ofVersion,
274                     final BigInteger datapathId) {
275         MultipartReplyPortStatsBuilder message = new MultipartReplyPortStatsBuilder();
276         MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase) msg.getMultipartReplyBody();
277         MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats();
278
279         List<NodeConnectorStatisticsAndPortNumberMap> statsMap =
280             new ArrayList<>();
281         for (PortStats portStats : replyBody.getPortStats()) {
282
283             NodeConnectorStatisticsAndPortNumberMapBuilder statsBuilder =
284                 new NodeConnectorStatisticsAndPortNumberMapBuilder();
285             statsBuilder.setNodeConnectorId(
286                 InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
287                     portStats.getPortNo(), ofVersion));
288
289             BytesBuilder bytesBuilder = new BytesBuilder();
290             bytesBuilder.setReceived(portStats.getRxBytes());
291             bytesBuilder.setTransmitted(portStats.getTxBytes());
292             statsBuilder.setBytes(bytesBuilder.build());
293
294             PacketsBuilder packetsBuilder = new PacketsBuilder();
295             packetsBuilder.setReceived(portStats.getRxPackets());
296             packetsBuilder.setTransmitted(portStats.getTxPackets());
297             statsBuilder.setPackets(packetsBuilder.build());
298
299             DurationBuilder durationBuilder = new DurationBuilder();
300             if (portStats.getDurationSec() != null) {
301                 durationBuilder.setSecond(new Counter32(portStats.getDurationSec()));
302             }
303             if (portStats.getDurationNsec() != null) {
304                 durationBuilder.setNanosecond(new Counter32(portStats.getDurationNsec()));
305             }
306             statsBuilder.setDuration(durationBuilder.build());
307             statsBuilder.setCollisionCount(portStats.getCollisions());
308             statsBuilder.withKey(new NodeConnectorStatisticsAndPortNumberMapKey(statsBuilder.getNodeConnectorId()));
309             statsBuilder.setReceiveCrcError(portStats.getRxCrcErr());
310             statsBuilder.setReceiveDrops(portStats.getRxDropped());
311             statsBuilder.setReceiveErrors(portStats.getRxErrors());
312             statsBuilder.setReceiveFrameError(portStats.getRxFrameErr());
313             statsBuilder.setReceiveOverRunError(portStats.getRxOverErr());
314             statsBuilder.setTransmitDrops(portStats.getTxDropped());
315             statsBuilder.setTransmitErrors(portStats.getTxErrors());
316
317             statsMap.add(statsBuilder.build());
318         }
319         message.setNodeConnectorStatisticsAndPortNumberMap(statsMap);
320
321
322         return message.build();
323     }
324
325     private static MultipartReplyGroupStats translateGroup(final MultipartReply msg,
326                                                            final VersionDatapathIdConvertorData data,
327                                                            final ConvertorExecutor convertorExecutor) {
328         MultipartReplyGroupStatsBuilder message = new MultipartReplyGroupStatsBuilder();
329         MultipartReplyGroupCase caseBody = (MultipartReplyGroupCase) msg.getMultipartReplyBody();
330         MultipartReplyGroup replyBody = caseBody.getMultipartReplyGroup();
331         final Optional<List<GroupStats>> groupStatsList = convertorExecutor.convert(
332             replyBody.getGroupStats(), data);
333
334         message.setGroupStats(groupStatsList.orElse(Collections.emptyList()));
335
336         return message.build();
337     }
338
339     private static org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart
340             .reply.body.MultipartReplyGroupDesc translateGroupDesc(
341                     final MultipartReply msg,
342                     final VersionDatapathIdConvertorData data,
343                     final ConvertorExecutor convertorExecutor) {
344         MultipartReplyGroupDescBuilder message = new MultipartReplyGroupDescBuilder();
345         MultipartReplyGroupDescCase caseBody = (MultipartReplyGroupDescCase) msg.getMultipartReplyBody();
346         MultipartReplyGroupDesc replyBody = caseBody.getMultipartReplyGroupDesc();
347
348         final Optional<List<GroupDescStats>> groupDescStatsList = convertorExecutor.convert(
349             replyBody.getGroupDesc(), data);
350
351         message.setGroupDescStats(groupDescStatsList.orElse(Collections.emptyList()));
352
353         return message.build();
354     }
355
356     private static org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart
357             .reply.body.MultipartReplyGroupFeatures translateGroupFeatures(final MultipartReply msg) {
358         final MultipartReplyGroupFeaturesBuilder message = new MultipartReplyGroupFeaturesBuilder();
359         final MultipartReplyGroupFeaturesCase caseBody = (MultipartReplyGroupFeaturesCase) msg.getMultipartReplyBody();
360         final MultipartReplyGroupFeatures replyBody = caseBody.getMultipartReplyGroupFeatures();
361         List<Class<? extends GroupType>> supportedGroups =
362             new ArrayList<>();
363
364         if (replyBody.getTypes().isOFPGTALL()) {
365             supportedGroups.add(GroupAll.class);
366         }
367         if (replyBody.getTypes().isOFPGTSELECT()) {
368             supportedGroups.add(GroupSelect.class);
369         }
370         if (replyBody.getTypes().isOFPGTINDIRECT()) {
371             supportedGroups.add(GroupIndirect.class);
372         }
373         if (replyBody.getTypes().isOFPGTFF()) {
374             supportedGroups.add(GroupFf.class);
375         }
376         message.setGroupTypesSupported(supportedGroups);
377         message.setMaxGroups(replyBody.getMaxGroups());
378
379         List<Class<? extends GroupCapability>> supportedCapabilities =
380             new ArrayList<>();
381
382         if (replyBody.getCapabilities().isOFPGFCCHAINING()) {
383             supportedCapabilities.add(Chaining.class);
384         }
385         if (replyBody.getCapabilities().isOFPGFCCHAININGCHECKS()) {
386             supportedCapabilities.add(ChainingChecks.class);
387         }
388         if (replyBody.getCapabilities().isOFPGFCSELECTLIVENESS()) {
389             supportedCapabilities.add(SelectLiveness.class);
390         }
391         if (replyBody.getCapabilities().isOFPGFCSELECTWEIGHT()) {
392             supportedCapabilities.add(SelectWeight.class);
393         }
394
395         message.setGroupCapabilitiesSupported(supportedCapabilities);
396
397         message.setActions(GroupUtil.extractGroupActionsSupportBitmap(replyBody.getActionsBitmap()));
398         return message.build();
399     }
400
401     private static MultipartReplyMeterStats translateMeter(final MultipartReply msg,
402                                                            final VersionDatapathIdConvertorData data,
403                                                            final ConvertorExecutor convertorExecutor) {
404         MultipartReplyMeterStatsBuilder message = new MultipartReplyMeterStatsBuilder();
405         MultipartReplyMeterCase caseBody = (MultipartReplyMeterCase) msg.getMultipartReplyBody();
406         MultipartReplyMeter replyBody = caseBody.getMultipartReplyMeter();
407         final Optional<List<
408                 org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats
409                 >>
410                 meterStatsList = convertorExecutor.convert(replyBody.getMeterStats(), data);
411
412         message.setMeterStats(meterStatsList.orElse(Collections.emptyList()));
413
414         return message.build();
415     }
416
417     private static org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart
418             .reply.body.MultipartReplyMeterConfig translateMeterConfig(
419                     final MultipartReply msg,
420                     final VersionDatapathIdConvertorData data,
421                     final ConvertorExecutor convertorExecutor) {
422         MultipartReplyMeterConfigBuilder message = new MultipartReplyMeterConfigBuilder();
423         MultipartReplyMeterConfigCase caseBody = (MultipartReplyMeterConfigCase) msg.getMultipartReplyBody();
424         MultipartReplyMeterConfig replyBody = caseBody.getMultipartReplyMeterConfig();
425         final Optional<List<MeterConfigStats>> meterConfigStatsList
426                 = convertorExecutor.convert(replyBody.getMeterConfig(), data);
427
428         message.setMeterConfigStats(meterConfigStatsList.orElse(Collections.emptyList()));
429
430         return message.build();
431     }
432
433     private static org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart
434             .reply.body.MultipartReplyMeterFeatures translateMeterFeatures(final MultipartReply msg) {
435         MultipartReplyMeterFeaturesBuilder message = new MultipartReplyMeterFeaturesBuilder();
436         MultipartReplyMeterFeaturesCase caseBody = (MultipartReplyMeterFeaturesCase) msg.getMultipartReplyBody();
437         MultipartReplyMeterFeatures replyBody = caseBody.getMultipartReplyMeterFeatures();
438         message.setMaxBands(replyBody.getMaxBands());
439         message.setMaxColor(replyBody.getMaxColor());
440         message.setMaxMeter(new Counter32(replyBody.getMaxMeter()));
441
442         List<Class<? extends MeterCapability>> supportedCapabilities =
443             new ArrayList<>();
444         if (replyBody.getCapabilities().isOFPMFBURST()) {
445             supportedCapabilities.add(MeterBurst.class);
446         }
447         if (replyBody.getCapabilities().isOFPMFKBPS()) {
448             supportedCapabilities.add(MeterKbps.class);
449
450         }
451         if (replyBody.getCapabilities().isOFPMFPKTPS()) {
452             supportedCapabilities.add(MeterPktps.class);
453
454         }
455         if (replyBody.getCapabilities().isOFPMFSTATS()) {
456             supportedCapabilities.add(MeterStats.class);
457
458         }
459         message.setMeterCapabilitiesSupported(supportedCapabilities);
460
461         List<Class<? extends MeterBand>> supportedMeterBand =
462             new ArrayList<>();
463         if (replyBody.getBandTypes().isOFPMBTDROP()) {
464             supportedMeterBand.add(MeterBandDrop.class);
465         }
466         if (replyBody.getBandTypes().isOFPMBTDSCPREMARK()) {
467             supportedMeterBand.add(MeterBandDscpRemark.class);
468         }
469         message.setMeterBandSupported(supportedMeterBand);
470         return message.build();
471     }
472
473     private static MultipartReplyFlowTableStats translateTable(final MultipartReply msg) {
474         MultipartReplyFlowTableStatsBuilder message = new MultipartReplyFlowTableStatsBuilder();
475         MultipartReplyTableCase caseBody = (MultipartReplyTableCase) msg.getMultipartReplyBody();
476         MultipartReplyTable replyBody = caseBody.getMultipartReplyTable();
477         List<TableStats> swTablesStats = replyBody.getTableStats();
478
479         List<FlowTableAndStatisticsMap> salFlowStats = new ArrayList<>();
480         //TODO: Duplicate code: look at OpendaylightFlowTableStatisticsServiceImpl method transformToNotification
481         for (TableStats swTableStats : swTablesStats) {
482             FlowTableAndStatisticsMapBuilder statisticsBuilder = new FlowTableAndStatisticsMapBuilder();
483
484             statisticsBuilder.setActiveFlows(new Counter32(swTableStats.getActiveCount()));
485             statisticsBuilder.setPacketsLookedUp(new Counter64(swTableStats.getLookupCount()));
486             statisticsBuilder.setPacketsMatched(new Counter64(swTableStats.getMatchedCount()));
487             statisticsBuilder.setTableId(new TableId(swTableStats.getTableId()));
488             salFlowStats.add(statisticsBuilder.build());
489         }
490
491         message.setFlowTableAndStatisticsMap(salFlowStats);
492         return message.build();
493     }
494
495     private static MultipartReplyQueueStats translateQueue(final MultipartReply msg,
496                                                            final OpenflowVersion ofVersion,
497                                                            final BigInteger datapathId) {
498         MultipartReplyQueueStatsBuilder message = new MultipartReplyQueueStatsBuilder();
499         MultipartReplyQueueCase caseBody = (MultipartReplyQueueCase) msg.getMultipartReplyBody();
500         MultipartReplyQueue replyBody = caseBody.getMultipartReplyQueue();
501
502         List<QueueIdAndStatisticsMap> statsMap =
503             new ArrayList<>();
504
505         for (QueueStats queueStats : replyBody.getQueueStats()) {
506
507             QueueIdAndStatisticsMapBuilder statsBuilder =
508                 new QueueIdAndStatisticsMapBuilder();
509             statsBuilder.setNodeConnectorId(
510                 InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
511                     queueStats.getPortNo(), ofVersion));
512             statsBuilder.setTransmissionErrors(new Counter64(queueStats.getTxErrors()));
513             statsBuilder.setTransmittedBytes(new Counter64(queueStats.getTxBytes()));
514             statsBuilder.setTransmittedPackets(new Counter64(queueStats.getTxPackets()));
515
516             DurationBuilder durationBuilder = new DurationBuilder();
517             durationBuilder.setSecond(new Counter32(queueStats.getDurationSec()));
518             durationBuilder.setNanosecond(new Counter32(queueStats.getDurationNsec()));
519             statsBuilder.setDuration(durationBuilder.build());
520
521             statsBuilder.setQueueId(new QueueId(queueStats.getQueueId()));
522             statsBuilder.setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
523                 queueStats.getPortNo(), ofVersion));
524
525             statsMap.add(statsBuilder.build());
526         }
527         message.setQueueIdAndStatisticsMap(statsMap);
528
529         return message.build();
530     }
531
532 }