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.queue.statistics.rev131216.multipart.reply.multipart.reply.body.MultipartReplyQueueStats;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.multipart.reply.multipart.reply.body.MultipartReplyQueueStatsBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesBuilder;
113 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
114 import org.opendaylight.yangtools.yang.common.Uint64;
115 import org.slf4j.Logger;
116 import org.slf4j.LoggerFactory;
119 * Class converts multipart reply messages to the objects that can be then written to datastore using
122 public final class MultipartReplyTranslatorUtil {
123 private static final Logger LOG = LoggerFactory.getLogger(MultipartReplyTranslatorUtil.class);
125 private MultipartReplyTranslatorUtil() {
129 public static Optional<? extends MultipartReplyBody> translate(final OfHeader message, final DeviceInfo deviceInfo,
130 final @Nullable ConvertorExecutor convertorExecutor, final @Nullable TranslatorLibrary translatorLibrary) {
132 if (message instanceof MultipartReply) {
133 final MultipartReply msg = (MultipartReply) message;
134 final OpenflowVersion ofVersion = OpenflowVersion.get(deviceInfo.getVersion());
135 final VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(deviceInfo.getVersion());
136 data.setDatapathId(deviceInfo.getDatapathId());
138 switch (msg.getType()) {
140 return translateFlow(msg, data, convertorExecutor);
142 return Optional.of(translateAggregate(msg));
144 return Optional.of(translatePortStats(msg, ofVersion, deviceInfo.getDatapathId()));
146 return translateGroup(msg, data, convertorExecutor);
148 return translateGroupDesc(msg, data, convertorExecutor);
149 case OFPMPGROUPFEATURES:
150 return Optional.of(translateGroupFeatures(msg));
152 return translateMeter(msg, data, convertorExecutor);
153 case OFPMPMETERCONFIG:
154 return translateMeterConfig(msg, data, convertorExecutor);
155 case OFPMPMETERFEATURES:
156 return Optional.of(translateMeterFeatures(msg));
158 return Optional.of(translateTable(msg));
160 return Optional.of(translateQueue(msg, ofVersion, deviceInfo.getDatapathId()));
162 return Optional.of(translateDesc(msg));
163 case OFPMPTABLEFEATURES:
164 return translateTableFeatures(msg, deviceInfo.getVersion(), convertorExecutor);
166 return translatePortDesc(msg, deviceInfo, translatorLibrary);
168 // TODO: log something?
171 } else if (message instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112
173 return Optional.of(((org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112
174 .MultipartReply) message).getMultipartReplyBody());
177 LOG.debug("Failed to translate {} for node {}.", message.implementedInterface(), deviceInfo);
178 return Optional.empty();
181 private static Optional<MultipartReplyPortDesc> translatePortDesc(final MultipartReply msg,
182 final DeviceInfo deviceInfo, final TranslatorLibrary translatorLibrary) {
183 if (translatorLibrary == null) {
184 return Optional.empty();
187 return Optional.of(new MultipartReplyPortDescBuilder()
188 .setPorts(((MultipartReplyPortDescCase) msg.getMultipartReplyBody())
189 .getMultipartReplyPortDesc().nonnullPorts().stream()
191 final MessageTranslator<PortGrouping, FlowCapableNodeConnector> translator =
192 translatorLibrary .lookupTranslator(new TranslatorKey(deviceInfo.getVersion(),
193 PortGrouping.class.getName()));
195 return new PortsBuilder(translator.translate(port, deviceInfo, null)).build();
197 .collect(Collectors.toList()))
201 private static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.multipart.reply
202 .multipart.reply.body.MultipartReplyTableFeatures> translateTableFeatures(final MultipartReply msg,
203 final short version, final ConvertorExecutor convertorExecutor) {
204 if (convertorExecutor == null) {
205 return Optional.empty();
208 final MultipartReplyTableFeatures multipartReplyTableFeatures =
209 ((MultipartReplyTableFeaturesCase) msg.getMultipartReplyBody()).getMultipartReplyTableFeatures();
210 final Optional<List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features
211 .TableFeatures>> tableFeaturesList = convertorExecutor
212 .convert(multipartReplyTableFeatures, new VersionConvertorData(version));
214 return Optional.of(new MultipartReplyTableFeaturesBuilder()
215 .setTableFeatures(tableFeaturesList.map(BindingMap::ordered).orElse(Map.of()))
219 private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.multipart.reply.multipart
220 .reply.body.MultipartReplyDesc translateDesc(final MultipartReply msg) {
221 final MultipartReplyDesc desc = ((MultipartReplyDescCase) msg.getMultipartReplyBody()).getMultipartReplyDesc();
223 return new MultipartReplyDescBuilder()
224 .setDescription(desc.getDpDesc())
225 .setHardware(desc.getHwDesc())
226 .setManufacturer(desc.getMfrDesc())
227 .setSoftware(desc.getSwDesc())
228 .setSerialNumber(desc.getSerialNum())
232 private static Optional<MultipartReplyFlowStats> translateFlow(final MultipartReply msg,
233 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertor) {
234 if (convertor == null) {
235 return Optional.empty();
238 final FlowStatsResponseConvertorData flowData = new FlowStatsResponseConvertorData(data.getVersion());
239 flowData.setDatapathId(data.getDatapathId());
240 flowData.setMatchPath(MatchPath.FLOWS_STATISTICS_UPDATE_MATCH);
242 final MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase) msg.getMultipartReplyBody();
243 final Optional<List<FlowAndStatisticsMapList>> flowAndStatisticsMapLists =
244 convertor.convert(caseBody.getMultipartReplyFlow().getFlowStats(), flowData);
246 return Optional.of(new MultipartReplyFlowStatsBuilder()
247 .setFlowAndStatisticsMapList(flowAndStatisticsMapLists.orElse(List.of()))
251 private static MultipartReplyFlowAggregateStats translateAggregate(final MultipartReply msg) {
252 final MultipartReplyAggregate replyBody = ((MultipartReplyAggregateCase) msg.getMultipartReplyBody())
253 .getMultipartReplyAggregate();
255 return new MultipartReplyFlowAggregateStatsBuilder()
256 .setByteCount(new Counter64(replyBody.getByteCount()))
257 .setPacketCount(new Counter64(replyBody.getPacketCount()))
258 .setFlowCount(new Counter32(replyBody.getFlowCount()))
262 private static org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.multipart.reply.multipart
263 .reply.body.MultipartReplyPortStats translatePortStats(final MultipartReply msg,
264 final OpenflowVersion ofVersion, final Uint64 datapathId) {
265 MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase) msg.getMultipartReplyBody();
266 MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats();
268 List<NodeConnectorStatisticsAndPortNumberMap> statsMap = new ArrayList<>();
269 for (PortStats portStats : replyBody.nonnullPortStats()) {
270 final DurationBuilder durationBuilder = new DurationBuilder();
271 if (portStats.getDurationSec() != null) {
272 durationBuilder.setSecond(new Counter32(portStats.getDurationSec()));
274 if (portStats.getDurationNsec() != null) {
275 durationBuilder.setNanosecond(new Counter32(portStats.getDurationNsec()));
278 statsMap.add(new NodeConnectorStatisticsAndPortNumberMapBuilder()
279 .setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
280 portStats.getPortNo(), ofVersion))
281 .setBytes(new BytesBuilder()
282 .setReceived(portStats.getRxBytes())
283 .setTransmitted(portStats.getTxBytes())
285 .setPackets(new PacketsBuilder()
286 .setReceived(portStats.getRxPackets())
287 .setTransmitted(portStats.getTxPackets())
289 .setDuration(durationBuilder.build())
290 .setCollisionCount(portStats.getCollisions())
291 .setReceiveCrcError(portStats.getRxCrcErr())
292 .setReceiveDrops(portStats.getRxDropped())
293 .setReceiveErrors(portStats.getRxErrors())
294 .setReceiveFrameError(portStats.getRxFrameErr())
295 .setReceiveOverRunError(portStats.getRxOverErr())
296 .setTransmitDrops(portStats.getTxDropped())
297 .setTransmitErrors(portStats.getTxErrors())
301 return new MultipartReplyPortStatsBuilder()
302 .setNodeConnectorStatisticsAndPortNumberMap(statsMap)
306 private static Optional<MultipartReplyGroupStats> translateGroup(final MultipartReply msg,
307 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertorExecutor) {
308 if (convertorExecutor == null) {
309 return Optional.empty();
312 final MultipartReplyGroup replyBody = ((MultipartReplyGroupCase) msg.getMultipartReplyBody())
313 .getMultipartReplyGroup();
314 final Optional<List<GroupStats>> groupStatsList = convertorExecutor.convert(
315 replyBody.getGroupStats(), data);
317 return Optional.of(new MultipartReplyGroupStatsBuilder()
318 .setGroupStats(groupStatsList.map(BindingMap::ordered).orElse(Map.of()))
322 private static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply
323 .multipart.reply.body.MultipartReplyGroupDesc> translateGroupDesc(final MultipartReply msg,
324 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertorExecutor) {
325 if (convertorExecutor == null) {
326 return Optional.empty();
329 MultipartReplyGroupDescCase caseBody = (MultipartReplyGroupDescCase) msg.getMultipartReplyBody();
330 MultipartReplyGroupDesc replyBody = caseBody.getMultipartReplyGroupDesc();
332 final Optional<List<GroupDescStats>> groupDescStatsList = convertorExecutor.convert(
333 replyBody.getGroupDesc(), data);
335 return Optional.of(new MultipartReplyGroupDescBuilder()
336 .setGroupDescStats(groupDescStatsList.map(BindingMap::ordered).orElse(Map.of()))
340 private static org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart
341 .reply.body.MultipartReplyGroupFeatures translateGroupFeatures(final MultipartReply msg) {
342 final MultipartReplyGroupFeatures replyBody = ((MultipartReplyGroupFeaturesCase) msg.getMultipartReplyBody())
343 .getMultipartReplyGroupFeatures();
344 final List<Class<? extends GroupType>> supportedGroups = new ArrayList<>();
345 if (replyBody.getTypes().getOFPGTALL()) {
346 supportedGroups.add(GroupAll.class);
348 if (replyBody.getTypes().getOFPGTSELECT()) {
349 supportedGroups.add(GroupSelect.class);
351 if (replyBody.getTypes().getOFPGTINDIRECT()) {
352 supportedGroups.add(GroupIndirect.class);
354 if (replyBody.getTypes().getOFPGTFF()) {
355 supportedGroups.add(GroupFf.class);
358 List<Class<? extends GroupCapability>> supportedCapabilities = new ArrayList<>();
359 if (replyBody.getCapabilities().getOFPGFCCHAINING()) {
360 supportedCapabilities.add(Chaining.class);
362 if (replyBody.getCapabilities().getOFPGFCCHAININGCHECKS()) {
363 supportedCapabilities.add(ChainingChecks.class);
365 if (replyBody.getCapabilities().getOFPGFCSELECTLIVENESS()) {
366 supportedCapabilities.add(SelectLiveness.class);
368 if (replyBody.getCapabilities().getOFPGFCSELECTWEIGHT()) {
369 supportedCapabilities.add(SelectWeight.class);
372 return new MultipartReplyGroupFeaturesBuilder()
373 .setGroupTypesSupported(supportedGroups)
374 .setMaxGroups(replyBody.getMaxGroups())
375 .setGroupCapabilitiesSupported(supportedCapabilities)
376 .setActions(GroupUtil.extractGroupActionsSupportBitmap(replyBody.getActionsBitmap()))
380 private static Optional<MultipartReplyMeterStats> translateMeter(final MultipartReply msg,
381 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertorExecutor) {
382 if (convertorExecutor == null) {
383 return Optional.empty();
386 final MultipartReplyMeter replyBody = ((MultipartReplyMeterCase) msg.getMultipartReplyBody())
387 .getMultipartReplyMeter();
389 org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats>>
390 meterStatsList = convertorExecutor.convert(replyBody.getMeterStats(), data);
392 return Optional.of(new MultipartReplyMeterStatsBuilder()
393 .setMeterStats(meterStatsList.map(BindingMap::ordered).orElse(Map.of()))
397 private static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply
398 .multipart.reply.body.MultipartReplyMeterConfig> translateMeterConfig(final MultipartReply msg,
399 final VersionDatapathIdConvertorData data, final ConvertorExecutor convertorExecutor) {
400 if (convertorExecutor == null) {
401 return Optional.empty();
404 MultipartReplyMeterConfigCase caseBody = (MultipartReplyMeterConfigCase) msg.getMultipartReplyBody();
405 MultipartReplyMeterConfig replyBody = caseBody.getMultipartReplyMeterConfig();
406 final Optional<List<MeterConfigStats>> meterConfigStatsList
407 = convertorExecutor.convert(replyBody.getMeterConfig(), data);
409 return Optional.of(new MultipartReplyMeterConfigBuilder()
410 .setMeterConfigStats(meterConfigStatsList.map(BindingMap::ordered).orElse(Map.of()))
414 private static org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart
415 .reply.body.MultipartReplyMeterFeatures translateMeterFeatures(final MultipartReply msg) {
416 MultipartReplyMeterFeaturesCase caseBody = (MultipartReplyMeterFeaturesCase) msg.getMultipartReplyBody();
417 MultipartReplyMeterFeatures replyBody = caseBody.getMultipartReplyMeterFeatures();
419 final List<Class<? extends MeterCapability>> supportedCapabilities = new ArrayList<>();
420 if (replyBody.getCapabilities().getOFPMFBURST()) {
421 supportedCapabilities.add(MeterBurst.class);
423 if (replyBody.getCapabilities().getOFPMFKBPS()) {
424 supportedCapabilities.add(MeterKbps.class);
426 if (replyBody.getCapabilities().getOFPMFPKTPS()) {
427 supportedCapabilities.add(MeterPktps.class);
429 if (replyBody.getCapabilities().getOFPMFSTATS()) {
430 supportedCapabilities.add(MeterStats.class);
433 final List<Class<? extends MeterBand>> supportedMeterBand = new ArrayList<>();
434 if (replyBody.getBandTypes().getOFPMBTDROP()) {
435 supportedMeterBand.add(MeterBandDrop.class);
437 if (replyBody.getBandTypes().getOFPMBTDSCPREMARK()) {
438 supportedMeterBand.add(MeterBandDscpRemark.class);
441 return new MultipartReplyMeterFeaturesBuilder()
442 .setMaxBands(replyBody.getMaxBands())
443 .setMaxColor(replyBody.getMaxColor())
444 .setMaxMeter(new Counter32(replyBody.getMaxMeter()))
445 .setMeterCapabilitiesSupported(supportedCapabilities)
446 .setMeterBandSupported(supportedMeterBand)
450 private static MultipartReplyFlowTableStats translateTable(final MultipartReply msg) {
451 final var salFlowStats = ((MultipartReplyTableCase) msg.getMultipartReplyBody()).getMultipartReplyTable()
452 .nonnullTableStats().stream()
453 //TODO: Duplicate code: look at OpendaylightFlowTableStatisticsServiceImpl method transformToNotification
454 .map(swTableStats -> new FlowTableAndStatisticsMapBuilder()
455 .setActiveFlows(new Counter32(swTableStats.getActiveCount()))
456 .setPacketsLookedUp(new Counter64(swTableStats.getLookupCount()))
457 .setPacketsMatched(new Counter64(swTableStats.getMatchedCount()))
458 .setTableId(new TableId(swTableStats.getTableId()))
460 .collect(BindingMap.toOrderedMap());
462 return new MultipartReplyFlowTableStatsBuilder()
463 .setFlowTableAndStatisticsMap(salFlowStats)
467 private static MultipartReplyQueueStats translateQueue(final MultipartReply msg,
468 final OpenflowVersion ofVersion,
469 final Uint64 datapathId) {
470 final var statsMap = ((MultipartReplyQueueCase) msg.getMultipartReplyBody()).getMultipartReplyQueue()
471 .nonnullQueueStats().stream()
472 .map(queueStats -> new QueueIdAndStatisticsMapBuilder()
473 .setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
474 queueStats.getPortNo(), ofVersion))
475 .setQueueId(new QueueId(queueStats.getQueueId()))
476 .setTransmissionErrors(new Counter64(queueStats.getTxErrors()))
477 .setTransmittedBytes(new Counter64(queueStats.getTxBytes()))
478 .setTransmittedPackets(new Counter64(queueStats.getTxPackets()))
479 .setDuration(new DurationBuilder()
480 .setSecond(new Counter32(queueStats.getDurationSec()))
481 .setNanosecond(new Counter32(queueStats.getDurationNsec()))
484 .collect(BindingMap.toOrderedMap());
486 return new MultipartReplyQueueStatsBuilder()
487 .setQueueIdAndStatisticsMap(statsMap)