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 com.google.common.collect.ImmutableSet;
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();
348 final var replyTypes = replyBody.getTypes();
349 final var supportedGroups = ImmutableSet.<Class<? extends GroupType>>builder();
350 if (replyTypes.getOFPGTALL()) {
351 supportedGroups.add(GroupAll.class);
353 if (replyTypes.getOFPGTSELECT()) {
354 supportedGroups.add(GroupSelect.class);
356 if (replyTypes.getOFPGTINDIRECT()) {
357 supportedGroups.add(GroupIndirect.class);
359 if (replyTypes.getOFPGTFF()) {
360 supportedGroups.add(GroupFf.class);
363 final var replyCapabilities = replyBody.getCapabilities();
364 final var supportedCapabilities = ImmutableSet.<Class<? extends GroupCapability>>builder();
365 if (replyCapabilities.getOFPGFCCHAINING()) {
366 supportedCapabilities.add(Chaining.class);
368 if (replyCapabilities.getOFPGFCCHAININGCHECKS()) {
369 supportedCapabilities.add(ChainingChecks.class);
371 if (replyCapabilities.getOFPGFCSELECTLIVENESS()) {
372 supportedCapabilities.add(SelectLiveness.class);
374 if (replyCapabilities.getOFPGFCSELECTWEIGHT()) {
375 supportedCapabilities.add(SelectWeight.class);
378 return new MultipartReplyGroupFeaturesBuilder()
379 .setGroupTypesSupported(supportedGroups.build())
380 .setMaxGroups(replyBody.getMaxGroups())
381 .setGroupCapabilitiesSupported(supportedCapabilities.build())
382 .setActions(GroupUtil.extractGroupActionsSupportBitmap(replyBody.getActionsBitmap()))
386 private static Optional<MultipartReplyMeterStats> translateMeter(final MultipartReply msg,
387 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertorExecutor) {
388 if (convertorExecutor == null) {
389 return Optional.empty();
392 final MultipartReplyMeter replyBody = ((MultipartReplyMeterCase) msg.getMultipartReplyBody())
393 .getMultipartReplyMeter();
395 org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats>>
396 meterStatsList = convertorExecutor.convert(replyBody.getMeterStats(), data);
398 return Optional.of(new MultipartReplyMeterStatsBuilder()
399 .setMeterStats(meterStatsList.map(BindingMap::ordered).orElse(Map.of()))
403 private static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply
404 .multipart.reply.body.MultipartReplyMeterConfig> translateMeterConfig(final MultipartReply msg,
405 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertorExecutor) {
406 if (convertorExecutor == null) {
407 return Optional.empty();
410 MultipartReplyMeterConfigCase caseBody = (MultipartReplyMeterConfigCase) msg.getMultipartReplyBody();
411 MultipartReplyMeterConfig replyBody = caseBody.getMultipartReplyMeterConfig();
412 final Optional<List<MeterConfigStats>> meterConfigStatsList
413 = convertorExecutor.convert(replyBody.getMeterConfig(), data);
415 return Optional.of(new MultipartReplyMeterConfigBuilder()
416 .setMeterConfigStats(meterConfigStatsList.map(BindingMap::ordered).orElse(Map.of()))
420 private static org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart
421 .reply.body.MultipartReplyMeterFeatures translateMeterFeatures(final MultipartReply msg) {
422 MultipartReplyMeterFeaturesCase caseBody = (MultipartReplyMeterFeaturesCase) msg.getMultipartReplyBody();
423 MultipartReplyMeterFeatures replyBody = caseBody.getMultipartReplyMeterFeatures();
425 final var replyCapabilities = replyBody.getCapabilities();
426 final var supportedCapabilities = ImmutableSet.<Class<? extends MeterCapability>>builder();
427 if (replyCapabilities.getOFPMFBURST()) {
428 supportedCapabilities.add(MeterBurst.class);
430 if (replyCapabilities.getOFPMFKBPS()) {
431 supportedCapabilities.add(MeterKbps.class);
433 if (replyCapabilities.getOFPMFPKTPS()) {
434 supportedCapabilities.add(MeterPktps.class);
436 if (replyCapabilities.getOFPMFSTATS()) {
437 supportedCapabilities.add(MeterStats.class);
440 final var replyMeterBand = replyBody.getBandTypes();
441 final var supportedMeterBand = ImmutableSet.<Class<? extends MeterBand>>builder();
442 if (replyMeterBand.getOFPMBTDROP()) {
443 supportedMeterBand.add(MeterBandDrop.class);
445 if (replyMeterBand.getOFPMBTDSCPREMARK()) {
446 supportedMeterBand.add(MeterBandDscpRemark.class);
449 return new MultipartReplyMeterFeaturesBuilder()
450 .setMaxBands(replyBody.getMaxBands())
451 .setMaxColor(replyBody.getMaxColor())
452 .setMaxMeter(new Counter32(replyBody.getMaxMeter()))
453 .setMeterCapabilitiesSupported(supportedCapabilities.build())
454 .setMeterBandSupported(supportedMeterBand.build())
458 private static MultipartReplyFlowTableStats translateTable(final MultipartReply msg) {
459 final var salFlowStats = ((MultipartReplyTableCase) msg.getMultipartReplyBody()).getMultipartReplyTable()
460 .nonnullTableStats().stream()
461 //TODO: Duplicate code: look at OpendaylightFlowTableStatisticsServiceImpl method transformToNotification
462 .map(swTableStats -> new FlowTableAndStatisticsMapBuilder()
463 .setActiveFlows(new Counter32(swTableStats.getActiveCount()))
464 .setPacketsLookedUp(new Counter64(swTableStats.getLookupCount()))
465 .setPacketsMatched(new Counter64(swTableStats.getMatchedCount()))
466 .setTableId(new TableId(swTableStats.getTableId()))
468 .collect(BindingMap.toOrderedMap());
470 return new MultipartReplyFlowTableStatsBuilder()
471 .setFlowTableAndStatisticsMap(salFlowStats)
475 private static MultipartReplyQueueStats translateQueue(final MultipartReply msg,
476 final OpenflowVersion ofVersion,
477 final Uint64 datapathId) {
478 final var statsMap = ((MultipartReplyQueueCase) msg.getMultipartReplyBody()).getMultipartReplyQueue()
479 .nonnullQueueStats().stream()
480 .map(queueStats -> new QueueIdAndStatisticsMapBuilder()
481 .setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
482 queueStats.getPortNo(), ofVersion))
483 .setQueueId(new QueueId(queueStats.getQueueId()))
484 .setTransmissionErrors(new Counter64(queueStats.getTxErrors()))
485 .setTransmittedBytes(new Counter64(queueStats.getTxBytes()))
486 .setTransmittedPackets(new Counter64(queueStats.getTxPackets()))
487 .setDuration(new DurationBuilder()
488 .setSecond(new Counter32(queueStats.getDurationSec()))
489 .setNanosecond(new Counter32(queueStats.getDurationNsec()))
492 .collect(BindingMap.toOrderedMap());
494 return new MultipartReplyQueueStatsBuilder()
495 .setQueueIdAndStatisticsMap(statsMap)