2 * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.openflowplugin.impl.common;
10 import java.util.ArrayList;
11 import java.util.List;
13 import java.util.Optional;
14 import java.util.stream.Collectors;
15 import org.eclipse.jdt.annotation.Nullable;
16 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
17 import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
18 import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
19 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
20 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
21 import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
22 import org.opendaylight.openflowplugin.impl.util.GroupUtil;
23 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
24 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.FlowStatsResponseConvertorData;
25 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
26 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
27 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.multipart.reply.multipart.reply.body.MultipartReplyDescBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowAggregateStats;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowAggregateStatsBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStats;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStatsBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.multipart.reply.multipart.reply.body.MultipartReplyFlowTableStats;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.multipart.reply.multipart.reply.body.MultipartReplyFlowTableStatsBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.multipart.reply.multipart.reply.body.MultipartReplyPortDesc;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.multipart.reply.multipart.reply.body.MultipartReplyPortDescBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.multipart.reply.multipart.reply.body.multipart.reply.port.desc.PortsBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupDescBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupStats;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupStatsBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Chaining;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.ChainingChecks;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupAll;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupCapability;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFf;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupIndirect;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupSelect;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupType;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectLiveness;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectWeight;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterStats;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterStatsBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBand;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDrop;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDscpRemark;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBurst;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterCapability;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterKbps;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterPktps;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterStats;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.multipart.reply.MultipartReplyBody;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortGrouping;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCase;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCase;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCase;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCase;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCase;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregate;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.MultipartReplyGroupDesc;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.MultipartReplyMeterConfig;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeatures;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats;
103 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;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.multipart.reply.multipart.reply.body.MultipartReplyPortStatsBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapKey;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.multipart.reply.multipart.reply.body.MultipartReplyQueueStats;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.multipart.reply.multipart.reply.body.MultipartReplyQueueStatsBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesBuilder;
114 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
115 import org.opendaylight.yangtools.yang.common.Uint64;
116 import org.opendaylight.yangtools.yang.common.Uint8;
117 import org.slf4j.Logger;
118 import org.slf4j.LoggerFactory;
121 * Class converts multipart reply messages to the objects that can be then written to datastore using
124 public final class MultipartReplyTranslatorUtil {
125 private static final Logger LOG = LoggerFactory.getLogger(MultipartReplyTranslatorUtil.class);
127 private MultipartReplyTranslatorUtil() {
131 public static Optional<? extends MultipartReplyBody> translate(final OfHeader message, final DeviceInfo deviceInfo,
132 final @Nullable ConvertorExecutor convertorExecutor, final @Nullable TranslatorLibrary translatorLibrary) {
134 if (message instanceof MultipartReply) {
135 final MultipartReply msg = (MultipartReply) message;
136 final OpenflowVersion ofVersion = OpenflowVersion.get(deviceInfo.getVersion());
137 final VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(deviceInfo.getVersion());
138 data.setDatapathId(deviceInfo.getDatapathId());
140 switch (msg.getType()) {
142 return translateFlow(msg, data, convertorExecutor);
144 return Optional.of(translateAggregate(msg));
146 return Optional.of(translatePortStats(msg, ofVersion, deviceInfo.getDatapathId()));
148 return translateGroup(msg, data, convertorExecutor);
150 return translateGroupDesc(msg, data, convertorExecutor);
151 case OFPMPGROUPFEATURES:
152 return Optional.of(translateGroupFeatures(msg));
154 return translateMeter(msg, data, convertorExecutor);
155 case OFPMPMETERCONFIG:
156 return translateMeterConfig(msg, data, convertorExecutor);
157 case OFPMPMETERFEATURES:
158 return Optional.of(translateMeterFeatures(msg));
160 return Optional.of(translateTable(msg));
162 return Optional.of(translateQueue(msg, ofVersion, deviceInfo.getDatapathId()));
164 return Optional.of(translateDesc(msg));
165 case OFPMPTABLEFEATURES:
166 return translateTableFeatures(msg, deviceInfo.getVersion(), convertorExecutor);
168 return translatePortDesc(msg, deviceInfo, translatorLibrary);
170 // TODO: log something?
173 } else if (message instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112
175 return Optional.of(((org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112
176 .MultipartReply) message).getMultipartReplyBody());
179 LOG.debug("Failed to translate {} for node {}.", message.implementedInterface(), deviceInfo);
180 return Optional.empty();
183 private static Optional<MultipartReplyPortDesc> translatePortDesc(final MultipartReply msg,
184 final DeviceInfo deviceInfo, final TranslatorLibrary translatorLibrary) {
185 if (translatorLibrary == null) {
186 return Optional.empty();
189 return Optional.of(new MultipartReplyPortDescBuilder()
190 .setPorts(((MultipartReplyPortDescCase) msg.getMultipartReplyBody())
191 .getMultipartReplyPortDesc().nonnullPorts().stream()
193 final MessageTranslator<PortGrouping, FlowCapableNodeConnector> translator =
194 translatorLibrary .lookupTranslator(new TranslatorKey(deviceInfo.getVersion(),
195 PortGrouping.class.getName()));
197 return new PortsBuilder(translator.translate(port, deviceInfo, null)).build();
199 .collect(Collectors.toList()))
203 private static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.multipart.reply
204 .multipart.reply.body.MultipartReplyTableFeatures> translateTableFeatures(final MultipartReply msg,
205 final Uint8 version, final ConvertorExecutor convertorExecutor) {
206 if (convertorExecutor == null) {
207 return Optional.empty();
210 final MultipartReplyTableFeatures multipartReplyTableFeatures =
211 ((MultipartReplyTableFeaturesCase) msg.getMultipartReplyBody()).getMultipartReplyTableFeatures();
212 final Optional<List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features
213 .TableFeatures>> tableFeaturesList = convertorExecutor
214 .convert(multipartReplyTableFeatures, new VersionConvertorData(version));
216 return Optional.of(new MultipartReplyTableFeaturesBuilder()
217 .setTableFeatures(tableFeaturesList.map(BindingMap::ordered).orElse(Map.of()))
221 private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.multipart.reply.multipart
222 .reply.body.MultipartReplyDesc translateDesc(final MultipartReply msg) {
223 final MultipartReplyDesc desc = ((MultipartReplyDescCase) msg.getMultipartReplyBody()).getMultipartReplyDesc();
225 return new MultipartReplyDescBuilder()
226 .setDescription(desc.getDpDesc())
227 .setHardware(desc.getHwDesc())
228 .setManufacturer(desc.getMfrDesc())
229 .setSoftware(desc.getSwDesc())
230 .setSerialNumber(desc.getSerialNum())
234 private static Optional<MultipartReplyFlowStats> translateFlow(final MultipartReply msg,
235 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertor) {
236 if (convertor == null) {
237 return Optional.empty();
240 final FlowStatsResponseConvertorData flowData = new FlowStatsResponseConvertorData(data.getVersion());
241 flowData.setDatapathId(data.getDatapathId());
242 flowData.setMatchPath(MatchPath.FLOWS_STATISTICS_UPDATE_MATCH);
244 final MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase) msg.getMultipartReplyBody();
245 final Optional<List<FlowAndStatisticsMapList>> flowAndStatisticsMapLists =
246 convertor.convert(caseBody.getMultipartReplyFlow().getFlowStats(), flowData);
248 return Optional.of(new MultipartReplyFlowStatsBuilder()
249 .setFlowAndStatisticsMapList(flowAndStatisticsMapLists.orElse(List.of()))
253 private static MultipartReplyFlowAggregateStats translateAggregate(final MultipartReply msg) {
254 final MultipartReplyAggregate replyBody = ((MultipartReplyAggregateCase) msg.getMultipartReplyBody())
255 .getMultipartReplyAggregate();
257 return new MultipartReplyFlowAggregateStatsBuilder()
258 .setByteCount(new Counter64(replyBody.getByteCount()))
259 .setPacketCount(new Counter64(replyBody.getPacketCount()))
260 .setFlowCount(new Counter32(replyBody.getFlowCount()))
264 private static org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.multipart.reply.multipart
265 .reply.body.MultipartReplyPortStats translatePortStats(final MultipartReply msg,
266 final OpenflowVersion ofVersion, final Uint64 datapathId) {
267 MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase) msg.getMultipartReplyBody();
268 MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats();
270 final var statsMap = BindingMap.<NodeConnectorStatisticsAndPortNumberMapKey,
271 NodeConnectorStatisticsAndPortNumberMap>orderedBuilder();
272 for (PortStats portStats : replyBody.nonnullPortStats()) {
273 final DurationBuilder durationBuilder = new DurationBuilder();
274 if (portStats.getDurationSec() != null) {
275 durationBuilder.setSecond(new Counter32(portStats.getDurationSec()));
277 if (portStats.getDurationNsec() != null) {
278 durationBuilder.setNanosecond(new Counter32(portStats.getDurationNsec()));
281 statsMap.add(new NodeConnectorStatisticsAndPortNumberMapBuilder()
282 .setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
283 portStats.getPortNo(), ofVersion))
284 .setBytes(new BytesBuilder()
285 .setReceived(portStats.getRxBytes())
286 .setTransmitted(portStats.getTxBytes())
288 .setPackets(new PacketsBuilder()
289 .setReceived(portStats.getRxPackets())
290 .setTransmitted(portStats.getTxPackets())
292 .setDuration(durationBuilder.build())
293 .setCollisionCount(portStats.getCollisions())
294 .setReceiveCrcError(portStats.getRxCrcErr())
295 .setReceiveDrops(portStats.getRxDropped())
296 .setReceiveErrors(portStats.getRxErrors())
297 .setReceiveFrameError(portStats.getRxFrameErr())
298 .setReceiveOverRunError(portStats.getRxOverErr())
299 .setTransmitDrops(portStats.getTxDropped())
300 .setTransmitErrors(portStats.getTxErrors())
304 return new MultipartReplyPortStatsBuilder()
305 .setNodeConnectorStatisticsAndPortNumberMap(statsMap.build())
309 private static Optional<MultipartReplyGroupStats> translateGroup(final MultipartReply msg,
310 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertorExecutor) {
311 if (convertorExecutor == null) {
312 return Optional.empty();
315 final MultipartReplyGroup replyBody = ((MultipartReplyGroupCase) msg.getMultipartReplyBody())
316 .getMultipartReplyGroup();
317 final Optional<List<GroupStats>> groupStatsList = convertorExecutor.convert(
318 replyBody.getGroupStats(), data);
320 return Optional.of(new MultipartReplyGroupStatsBuilder()
321 .setGroupStats(groupStatsList.map(BindingMap::ordered).orElse(Map.of()))
325 private static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply
326 .multipart.reply.body.MultipartReplyGroupDesc> translateGroupDesc(final MultipartReply msg,
327 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertorExecutor) {
328 if (convertorExecutor == null) {
329 return Optional.empty();
332 MultipartReplyGroupDescCase caseBody = (MultipartReplyGroupDescCase) msg.getMultipartReplyBody();
333 MultipartReplyGroupDesc replyBody = caseBody.getMultipartReplyGroupDesc();
335 final Optional<List<GroupDescStats>> groupDescStatsList = convertorExecutor.convert(
336 replyBody.getGroupDesc(), data);
338 return Optional.of(new MultipartReplyGroupDescBuilder()
339 .setGroupDescStats(groupDescStatsList.map(BindingMap::ordered).orElse(Map.of()))
343 private static org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart
344 .reply.body.MultipartReplyGroupFeatures translateGroupFeatures(final MultipartReply msg) {
345 final MultipartReplyGroupFeatures replyBody = ((MultipartReplyGroupFeaturesCase) msg.getMultipartReplyBody())
346 .getMultipartReplyGroupFeatures();
347 final List<Class<? extends GroupType>> supportedGroups = new ArrayList<>();
348 if (replyBody.getTypes().getOFPGTALL()) {
349 supportedGroups.add(GroupAll.class);
351 if (replyBody.getTypes().getOFPGTSELECT()) {
352 supportedGroups.add(GroupSelect.class);
354 if (replyBody.getTypes().getOFPGTINDIRECT()) {
355 supportedGroups.add(GroupIndirect.class);
357 if (replyBody.getTypes().getOFPGTFF()) {
358 supportedGroups.add(GroupFf.class);
361 List<Class<? extends GroupCapability>> supportedCapabilities = new ArrayList<>();
362 if (replyBody.getCapabilities().getOFPGFCCHAINING()) {
363 supportedCapabilities.add(Chaining.class);
365 if (replyBody.getCapabilities().getOFPGFCCHAININGCHECKS()) {
366 supportedCapabilities.add(ChainingChecks.class);
368 if (replyBody.getCapabilities().getOFPGFCSELECTLIVENESS()) {
369 supportedCapabilities.add(SelectLiveness.class);
371 if (replyBody.getCapabilities().getOFPGFCSELECTWEIGHT()) {
372 supportedCapabilities.add(SelectWeight.class);
375 return new MultipartReplyGroupFeaturesBuilder()
376 .setGroupTypesSupported(supportedGroups)
377 .setMaxGroups(replyBody.getMaxGroups())
378 .setGroupCapabilitiesSupported(supportedCapabilities)
379 .setActions(GroupUtil.extractGroupActionsSupportBitmap(replyBody.getActionsBitmap()))
383 private static Optional<MultipartReplyMeterStats> translateMeter(final MultipartReply msg,
384 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertorExecutor) {
385 if (convertorExecutor == null) {
386 return Optional.empty();
389 final MultipartReplyMeter replyBody = ((MultipartReplyMeterCase) msg.getMultipartReplyBody())
390 .getMultipartReplyMeter();
392 org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats>>
393 meterStatsList = convertorExecutor.convert(replyBody.getMeterStats(), data);
395 return Optional.of(new MultipartReplyMeterStatsBuilder()
396 .setMeterStats(meterStatsList.map(BindingMap::ordered).orElse(Map.of()))
400 private static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply
401 .multipart.reply.body.MultipartReplyMeterConfig> translateMeterConfig(final MultipartReply msg,
402 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertorExecutor) {
403 if (convertorExecutor == null) {
404 return Optional.empty();
407 MultipartReplyMeterConfigCase caseBody = (MultipartReplyMeterConfigCase) msg.getMultipartReplyBody();
408 MultipartReplyMeterConfig replyBody = caseBody.getMultipartReplyMeterConfig();
409 final Optional<List<MeterConfigStats>> meterConfigStatsList
410 = convertorExecutor.convert(replyBody.getMeterConfig(), data);
412 return Optional.of(new MultipartReplyMeterConfigBuilder()
413 .setMeterConfigStats(meterConfigStatsList.map(BindingMap::ordered).orElse(Map.of()))
417 private static org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart
418 .reply.body.MultipartReplyMeterFeatures translateMeterFeatures(final MultipartReply msg) {
419 MultipartReplyMeterFeaturesCase caseBody = (MultipartReplyMeterFeaturesCase) msg.getMultipartReplyBody();
420 MultipartReplyMeterFeatures replyBody = caseBody.getMultipartReplyMeterFeatures();
422 final List<Class<? extends MeterCapability>> supportedCapabilities = new ArrayList<>();
423 if (replyBody.getCapabilities().getOFPMFBURST()) {
424 supportedCapabilities.add(MeterBurst.class);
426 if (replyBody.getCapabilities().getOFPMFKBPS()) {
427 supportedCapabilities.add(MeterKbps.class);
429 if (replyBody.getCapabilities().getOFPMFPKTPS()) {
430 supportedCapabilities.add(MeterPktps.class);
432 if (replyBody.getCapabilities().getOFPMFSTATS()) {
433 supportedCapabilities.add(MeterStats.class);
436 final List<Class<? extends MeterBand>> supportedMeterBand = new ArrayList<>();
437 if (replyBody.getBandTypes().getOFPMBTDROP()) {
438 supportedMeterBand.add(MeterBandDrop.class);
440 if (replyBody.getBandTypes().getOFPMBTDSCPREMARK()) {
441 supportedMeterBand.add(MeterBandDscpRemark.class);
444 return new MultipartReplyMeterFeaturesBuilder()
445 .setMaxBands(replyBody.getMaxBands())
446 .setMaxColor(replyBody.getMaxColor())
447 .setMaxMeter(new Counter32(replyBody.getMaxMeter()))
448 .setMeterCapabilitiesSupported(supportedCapabilities)
449 .setMeterBandSupported(supportedMeterBand)
453 private static MultipartReplyFlowTableStats translateTable(final MultipartReply msg) {
454 final var salFlowStats = ((MultipartReplyTableCase) msg.getMultipartReplyBody()).getMultipartReplyTable()
455 .nonnullTableStats().stream()
456 //TODO: Duplicate code: look at OpendaylightFlowTableStatisticsServiceImpl method transformToNotification
457 .map(swTableStats -> new FlowTableAndStatisticsMapBuilder()
458 .setActiveFlows(new Counter32(swTableStats.getActiveCount()))
459 .setPacketsLookedUp(new Counter64(swTableStats.getLookupCount()))
460 .setPacketsMatched(new Counter64(swTableStats.getMatchedCount()))
461 .setTableId(new TableId(swTableStats.getTableId()))
463 .collect(BindingMap.toOrderedMap());
465 return new MultipartReplyFlowTableStatsBuilder()
466 .setFlowTableAndStatisticsMap(salFlowStats)
470 private static MultipartReplyQueueStats translateQueue(final MultipartReply msg,
471 final OpenflowVersion ofVersion,
472 final Uint64 datapathId) {
473 final var statsMap = ((MultipartReplyQueueCase) msg.getMultipartReplyBody()).getMultipartReplyQueue()
474 .nonnullQueueStats().stream()
475 .map(queueStats -> new QueueIdAndStatisticsMapBuilder()
476 .setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
477 queueStats.getPortNo(), ofVersion))
478 .setQueueId(new QueueId(queueStats.getQueueId()))
479 .setTransmissionErrors(new Counter64(queueStats.getTxErrors()))
480 .setTransmittedBytes(new Counter64(queueStats.getTxBytes()))
481 .setTransmittedPackets(new Counter64(queueStats.getTxPackets()))
482 .setDuration(new DurationBuilder()
483 .setSecond(new Counter32(queueStats.getDurationSec()))
484 .setNanosecond(new Counter32(queueStats.getDurationNsec()))
487 .collect(BindingMap.toOrderedMap());
489 return new MultipartReplyQueueStatsBuilder()
490 .setQueueIdAndStatisticsMap(statsMap)