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.slf4j.Logger;
117 import org.slf4j.LoggerFactory;
120 * Class converts multipart reply messages to the objects that can be then written to datastore using
123 public final class MultipartReplyTranslatorUtil {
124 private static final Logger LOG = LoggerFactory.getLogger(MultipartReplyTranslatorUtil.class);
126 private MultipartReplyTranslatorUtil() {
130 public static Optional<? extends MultipartReplyBody> translate(final OfHeader message, final DeviceInfo deviceInfo,
131 final @Nullable ConvertorExecutor convertorExecutor, final @Nullable TranslatorLibrary translatorLibrary) {
133 if (message instanceof MultipartReply) {
134 final MultipartReply msg = (MultipartReply) message;
135 final OpenflowVersion ofVersion = OpenflowVersion.get(deviceInfo.getVersion());
136 final VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(deviceInfo.getVersion());
137 data.setDatapathId(deviceInfo.getDatapathId());
139 switch (msg.getType()) {
141 return translateFlow(msg, data, convertorExecutor);
143 return Optional.of(translateAggregate(msg));
145 return Optional.of(translatePortStats(msg, ofVersion, deviceInfo.getDatapathId()));
147 return translateGroup(msg, data, convertorExecutor);
149 return translateGroupDesc(msg, data, convertorExecutor);
150 case OFPMPGROUPFEATURES:
151 return Optional.of(translateGroupFeatures(msg));
153 return translateMeter(msg, data, convertorExecutor);
154 case OFPMPMETERCONFIG:
155 return translateMeterConfig(msg, data, convertorExecutor);
156 case OFPMPMETERFEATURES:
157 return Optional.of(translateMeterFeatures(msg));
159 return Optional.of(translateTable(msg));
161 return Optional.of(translateQueue(msg, ofVersion, deviceInfo.getDatapathId()));
163 return Optional.of(translateDesc(msg));
164 case OFPMPTABLEFEATURES:
165 return translateTableFeatures(msg, deviceInfo.getVersion(), convertorExecutor);
167 return translatePortDesc(msg, deviceInfo, translatorLibrary);
169 // TODO: log something?
172 } else if (message instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112
174 return Optional.of(((org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112
175 .MultipartReply) message).getMultipartReplyBody());
178 LOG.debug("Failed to translate {} for node {}.", message.implementedInterface(), deviceInfo);
179 return Optional.empty();
182 private static Optional<MultipartReplyPortDesc> translatePortDesc(final MultipartReply msg,
183 final DeviceInfo deviceInfo, final TranslatorLibrary translatorLibrary) {
184 if (translatorLibrary == null) {
185 return Optional.empty();
188 return Optional.of(new MultipartReplyPortDescBuilder()
189 .setPorts(((MultipartReplyPortDescCase) msg.getMultipartReplyBody())
190 .getMultipartReplyPortDesc().nonnullPorts().stream()
192 final MessageTranslator<PortGrouping, FlowCapableNodeConnector> translator =
193 translatorLibrary .lookupTranslator(new TranslatorKey(deviceInfo.getVersion(),
194 PortGrouping.class.getName()));
196 return new PortsBuilder(translator.translate(port, deviceInfo, null)).build();
198 .collect(Collectors.toList()))
202 private static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.multipart.reply
203 .multipart.reply.body.MultipartReplyTableFeatures> translateTableFeatures(final MultipartReply msg,
204 final short version, final ConvertorExecutor convertorExecutor) {
205 if (convertorExecutor == null) {
206 return Optional.empty();
209 final MultipartReplyTableFeatures multipartReplyTableFeatures =
210 ((MultipartReplyTableFeaturesCase) msg.getMultipartReplyBody()).getMultipartReplyTableFeatures();
211 final Optional<List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features
212 .TableFeatures>> tableFeaturesList = convertorExecutor
213 .convert(multipartReplyTableFeatures, new VersionConvertorData(version));
215 return Optional.of(new MultipartReplyTableFeaturesBuilder()
216 .setTableFeatures(tableFeaturesList.map(BindingMap::ordered).orElse(Map.of()))
220 private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.multipart.reply.multipart
221 .reply.body.MultipartReplyDesc translateDesc(final MultipartReply msg) {
222 final MultipartReplyDesc desc = ((MultipartReplyDescCase) msg.getMultipartReplyBody()).getMultipartReplyDesc();
224 return new MultipartReplyDescBuilder()
225 .setDescription(desc.getDpDesc())
226 .setHardware(desc.getHwDesc())
227 .setManufacturer(desc.getMfrDesc())
228 .setSoftware(desc.getSwDesc())
229 .setSerialNumber(desc.getSerialNum())
233 private static Optional<MultipartReplyFlowStats> translateFlow(final MultipartReply msg,
234 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertor) {
235 if (convertor == null) {
236 return Optional.empty();
239 final FlowStatsResponseConvertorData flowData = new FlowStatsResponseConvertorData(data.getVersion());
240 flowData.setDatapathId(data.getDatapathId());
241 flowData.setMatchPath(MatchPath.FLOWS_STATISTICS_UPDATE_MATCH);
243 final MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase) msg.getMultipartReplyBody();
244 final Optional<List<FlowAndStatisticsMapList>> flowAndStatisticsMapLists =
245 convertor.convert(caseBody.getMultipartReplyFlow().getFlowStats(), flowData);
247 return Optional.of(new MultipartReplyFlowStatsBuilder()
248 .setFlowAndStatisticsMapList(flowAndStatisticsMapLists.orElse(List.of()))
252 private static MultipartReplyFlowAggregateStats translateAggregate(final MultipartReply msg) {
253 final MultipartReplyAggregate replyBody = ((MultipartReplyAggregateCase) msg.getMultipartReplyBody())
254 .getMultipartReplyAggregate();
256 return new MultipartReplyFlowAggregateStatsBuilder()
257 .setByteCount(new Counter64(replyBody.getByteCount()))
258 .setPacketCount(new Counter64(replyBody.getPacketCount()))
259 .setFlowCount(new Counter32(replyBody.getFlowCount()))
263 private static org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.multipart.reply.multipart
264 .reply.body.MultipartReplyPortStats translatePortStats(final MultipartReply msg,
265 final OpenflowVersion ofVersion, final Uint64 datapathId) {
266 MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase) msg.getMultipartReplyBody();
267 MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats();
269 final var statsMap = BindingMap.<NodeConnectorStatisticsAndPortNumberMapKey,
270 NodeConnectorStatisticsAndPortNumberMap>orderedBuilder();
271 for (PortStats portStats : replyBody.nonnullPortStats()) {
272 final DurationBuilder durationBuilder = new DurationBuilder();
273 if (portStats.getDurationSec() != null) {
274 durationBuilder.setSecond(new Counter32(portStats.getDurationSec()));
276 if (portStats.getDurationNsec() != null) {
277 durationBuilder.setNanosecond(new Counter32(portStats.getDurationNsec()));
280 statsMap.add(new NodeConnectorStatisticsAndPortNumberMapBuilder()
281 .setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
282 portStats.getPortNo(), ofVersion))
283 .setBytes(new BytesBuilder()
284 .setReceived(portStats.getRxBytes())
285 .setTransmitted(portStats.getTxBytes())
287 .setPackets(new PacketsBuilder()
288 .setReceived(portStats.getRxPackets())
289 .setTransmitted(portStats.getTxPackets())
291 .setDuration(durationBuilder.build())
292 .setCollisionCount(portStats.getCollisions())
293 .setReceiveCrcError(portStats.getRxCrcErr())
294 .setReceiveDrops(portStats.getRxDropped())
295 .setReceiveErrors(portStats.getRxErrors())
296 .setReceiveFrameError(portStats.getRxFrameErr())
297 .setReceiveOverRunError(portStats.getRxOverErr())
298 .setTransmitDrops(portStats.getTxDropped())
299 .setTransmitErrors(portStats.getTxErrors())
303 return new MultipartReplyPortStatsBuilder()
304 .setNodeConnectorStatisticsAndPortNumberMap(statsMap.build())
308 private static Optional<MultipartReplyGroupStats> translateGroup(final MultipartReply msg,
309 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertorExecutor) {
310 if (convertorExecutor == null) {
311 return Optional.empty();
314 final MultipartReplyGroup replyBody = ((MultipartReplyGroupCase) msg.getMultipartReplyBody())
315 .getMultipartReplyGroup();
316 final Optional<List<GroupStats>> groupStatsList = convertorExecutor.convert(
317 replyBody.getGroupStats(), data);
319 return Optional.of(new MultipartReplyGroupStatsBuilder()
320 .setGroupStats(groupStatsList.map(BindingMap::ordered).orElse(Map.of()))
324 private static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply
325 .multipart.reply.body.MultipartReplyGroupDesc> translateGroupDesc(final MultipartReply msg,
326 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertorExecutor) {
327 if (convertorExecutor == null) {
328 return Optional.empty();
331 MultipartReplyGroupDescCase caseBody = (MultipartReplyGroupDescCase) msg.getMultipartReplyBody();
332 MultipartReplyGroupDesc replyBody = caseBody.getMultipartReplyGroupDesc();
334 final Optional<List<GroupDescStats>> groupDescStatsList = convertorExecutor.convert(
335 replyBody.getGroupDesc(), data);
337 return Optional.of(new MultipartReplyGroupDescBuilder()
338 .setGroupDescStats(groupDescStatsList.map(BindingMap::ordered).orElse(Map.of()))
342 private static org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart
343 .reply.body.MultipartReplyGroupFeatures translateGroupFeatures(final MultipartReply msg) {
344 final MultipartReplyGroupFeatures replyBody = ((MultipartReplyGroupFeaturesCase) msg.getMultipartReplyBody())
345 .getMultipartReplyGroupFeatures();
346 final List<Class<? extends GroupType>> supportedGroups = new ArrayList<>();
347 if (replyBody.getTypes().getOFPGTALL()) {
348 supportedGroups.add(GroupAll.class);
350 if (replyBody.getTypes().getOFPGTSELECT()) {
351 supportedGroups.add(GroupSelect.class);
353 if (replyBody.getTypes().getOFPGTINDIRECT()) {
354 supportedGroups.add(GroupIndirect.class);
356 if (replyBody.getTypes().getOFPGTFF()) {
357 supportedGroups.add(GroupFf.class);
360 List<Class<? extends GroupCapability>> supportedCapabilities = new ArrayList<>();
361 if (replyBody.getCapabilities().getOFPGFCCHAINING()) {
362 supportedCapabilities.add(Chaining.class);
364 if (replyBody.getCapabilities().getOFPGFCCHAININGCHECKS()) {
365 supportedCapabilities.add(ChainingChecks.class);
367 if (replyBody.getCapabilities().getOFPGFCSELECTLIVENESS()) {
368 supportedCapabilities.add(SelectLiveness.class);
370 if (replyBody.getCapabilities().getOFPGFCSELECTWEIGHT()) {
371 supportedCapabilities.add(SelectWeight.class);
374 return new MultipartReplyGroupFeaturesBuilder()
375 .setGroupTypesSupported(supportedGroups)
376 .setMaxGroups(replyBody.getMaxGroups())
377 .setGroupCapabilitiesSupported(supportedCapabilities)
378 .setActions(GroupUtil.extractGroupActionsSupportBitmap(replyBody.getActionsBitmap()))
382 private static Optional<MultipartReplyMeterStats> translateMeter(final MultipartReply msg,
383 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertorExecutor) {
384 if (convertorExecutor == null) {
385 return Optional.empty();
388 final MultipartReplyMeter replyBody = ((MultipartReplyMeterCase) msg.getMultipartReplyBody())
389 .getMultipartReplyMeter();
391 org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats>>
392 meterStatsList = convertorExecutor.convert(replyBody.getMeterStats(), data);
394 return Optional.of(new MultipartReplyMeterStatsBuilder()
395 .setMeterStats(meterStatsList.map(BindingMap::ordered).orElse(Map.of()))
399 private static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply
400 .multipart.reply.body.MultipartReplyMeterConfig> translateMeterConfig(final MultipartReply msg,
401 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertorExecutor) {
402 if (convertorExecutor == null) {
403 return Optional.empty();
406 MultipartReplyMeterConfigCase caseBody = (MultipartReplyMeterConfigCase) msg.getMultipartReplyBody();
407 MultipartReplyMeterConfig replyBody = caseBody.getMultipartReplyMeterConfig();
408 final Optional<List<MeterConfigStats>> meterConfigStatsList
409 = convertorExecutor.convert(replyBody.getMeterConfig(), data);
411 return Optional.of(new MultipartReplyMeterConfigBuilder()
412 .setMeterConfigStats(meterConfigStatsList.map(BindingMap::ordered).orElse(Map.of()))
416 private static org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart
417 .reply.body.MultipartReplyMeterFeatures translateMeterFeatures(final MultipartReply msg) {
418 MultipartReplyMeterFeaturesCase caseBody = (MultipartReplyMeterFeaturesCase) msg.getMultipartReplyBody();
419 MultipartReplyMeterFeatures replyBody = caseBody.getMultipartReplyMeterFeatures();
421 final List<Class<? extends MeterCapability>> supportedCapabilities = new ArrayList<>();
422 if (replyBody.getCapabilities().getOFPMFBURST()) {
423 supportedCapabilities.add(MeterBurst.class);
425 if (replyBody.getCapabilities().getOFPMFKBPS()) {
426 supportedCapabilities.add(MeterKbps.class);
428 if (replyBody.getCapabilities().getOFPMFPKTPS()) {
429 supportedCapabilities.add(MeterPktps.class);
431 if (replyBody.getCapabilities().getOFPMFSTATS()) {
432 supportedCapabilities.add(MeterStats.class);
435 final List<Class<? extends MeterBand>> supportedMeterBand = new ArrayList<>();
436 if (replyBody.getBandTypes().getOFPMBTDROP()) {
437 supportedMeterBand.add(MeterBandDrop.class);
439 if (replyBody.getBandTypes().getOFPMBTDSCPREMARK()) {
440 supportedMeterBand.add(MeterBandDscpRemark.class);
443 return new MultipartReplyMeterFeaturesBuilder()
444 .setMaxBands(replyBody.getMaxBands())
445 .setMaxColor(replyBody.getMaxColor())
446 .setMaxMeter(new Counter32(replyBody.getMaxMeter()))
447 .setMeterCapabilitiesSupported(supportedCapabilities)
448 .setMeterBandSupported(supportedMeterBand)
452 private static MultipartReplyFlowTableStats translateTable(final MultipartReply msg) {
453 final var salFlowStats = ((MultipartReplyTableCase) msg.getMultipartReplyBody()).getMultipartReplyTable()
454 .nonnullTableStats().stream()
455 //TODO: Duplicate code: look at OpendaylightFlowTableStatisticsServiceImpl method transformToNotification
456 .map(swTableStats -> new FlowTableAndStatisticsMapBuilder()
457 .setActiveFlows(new Counter32(swTableStats.getActiveCount()))
458 .setPacketsLookedUp(new Counter64(swTableStats.getLookupCount()))
459 .setPacketsMatched(new Counter64(swTableStats.getMatchedCount()))
460 .setTableId(new TableId(swTableStats.getTableId()))
462 .collect(BindingMap.toOrderedMap());
464 return new MultipartReplyFlowTableStatsBuilder()
465 .setFlowTableAndStatisticsMap(salFlowStats)
469 private static MultipartReplyQueueStats translateQueue(final MultipartReply msg,
470 final OpenflowVersion ofVersion,
471 final Uint64 datapathId) {
472 final var statsMap = ((MultipartReplyQueueCase) msg.getMultipartReplyBody()).getMultipartReplyQueue()
473 .nonnullQueueStats().stream()
474 .map(queueStats -> new QueueIdAndStatisticsMapBuilder()
475 .setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
476 queueStats.getPortNo(), ofVersion))
477 .setQueueId(new QueueId(queueStats.getQueueId()))
478 .setTransmissionErrors(new Counter64(queueStats.getTxErrors()))
479 .setTransmittedBytes(new Counter64(queueStats.getTxBytes()))
480 .setTransmittedPackets(new Counter64(queueStats.getTxPackets()))
481 .setDuration(new DurationBuilder()
482 .setSecond(new Counter32(queueStats.getDurationSec()))
483 .setNanosecond(new Counter32(queueStats.getDurationNsec()))
486 .collect(BindingMap.toOrderedMap());
488 return new MultipartReplyQueueStatsBuilder()
489 .setQueueIdAndStatisticsMap(statsMap)