2 * Copyright (c) 2013, 2015 IBM Corporation 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
9 package org.opendaylight.openflowplugin.openflow.md.core.translator;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.Optional;
16 import java.util.concurrent.CopyOnWriteArrayList;
17 import org.opendaylight.openflowplugin.api.openflow.md.core.IMDMessageTranslator;
18 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
19 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;
20 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
21 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
22 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
23 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
24 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdateBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdateBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdateBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdatedBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdatedBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdatedBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Chaining;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.ChainingChecks;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupAll;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupCapability;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFf;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupIndirect;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupSelect;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupType;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectLiveness;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectWeight;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdatedBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesUpdatedBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdatedBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBand;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDrop;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDscpRemark;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBurst;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterCapability;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterKbps;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterPktps;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterStats;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCase;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCase;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregate;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.MultipartReplyGroupDesc;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.MultipartReplyMeterConfig;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeatures;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats;
88 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;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTable;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdateBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapKey;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueStatisticsUpdateBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
101 import org.opendaylight.yangtools.yang.binding.DataObject;
102 import org.slf4j.Logger;
103 import org.slf4j.LoggerFactory;
106 * Class converts multipart reply messages to the notification objects defined
107 * by statistics provider (manager ).
109 * @author avishnoi@in.ibm.com
112 public class MultipartReplyTranslator implements IMDMessageTranslator<OfHeader, List<DataObject>> {
114 protected static final Logger logger = LoggerFactory
115 .getLogger(MultipartReplyTranslator.class);
119 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sc, final OfHeader msg) {
121 List<DataObject> listDataObject = new CopyOnWriteArrayList<DataObject>();
123 OpenflowVersion ofVersion = OpenflowVersion.get(sc.getPrimaryConductor().getVersion());
125 if(msg instanceof MultipartReplyMessage){
126 MultipartReplyMessage mpReply = (MultipartReplyMessage)msg;
127 NodeId node = MultipartReplyTranslator.nodeIdFromDatapathId(sc.getFeatures().getDatapathId());
128 switch (mpReply.getType()){
130 logger.debug("Received flow statistics reponse from openflow {} switch",msg.getVersion()==1?"1.0":"1.3+");
131 FlowsStatisticsUpdateBuilder message = new FlowsStatisticsUpdateBuilder();
133 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
134 message.setTransactionId(generateTransactionId(mpReply.getXid()));
135 MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase)mpReply.getMultipartReplyBody();
136 MultipartReplyFlow replyBody = caseBody.getMultipartReplyFlow();
137 final VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(sc.getPrimaryConductor().getVersion());
138 data.setDatapathId(sc.getFeatures().getDatapathId());
140 final Optional<List<FlowAndStatisticsMapList>> flowAndStatisticsMapLists = ConvertorManager.getInstance().convert(replyBody.getFlowStats(), data);
142 message.setFlowAndStatisticsMapList(flowAndStatisticsMapLists.orElse(Collections.emptyList()));
143 logger.debug("Converted flow statistics : {}",message.build().toString());
144 listDataObject.add(message.build());
145 return listDataObject;
147 case OFPMPAGGREGATE: {
148 logger.debug("Received aggregate flow statistics reponse from openflow {} switch",msg.getVersion()==1?"1.0":"1.3+");
149 AggregateFlowStatisticsUpdateBuilder message = new AggregateFlowStatisticsUpdateBuilder();
151 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
152 message.setTransactionId(generateTransactionId(mpReply.getXid()));
154 MultipartReplyAggregateCase caseBody = (MultipartReplyAggregateCase)mpReply.getMultipartReplyBody();
155 MultipartReplyAggregate replyBody = caseBody.getMultipartReplyAggregate();
156 message.setByteCount(new Counter64(replyBody.getByteCount()));
157 message.setPacketCount(new Counter64(replyBody.getPacketCount()));
158 message.setFlowCount(new Counter32(replyBody.getFlowCount()));
160 logger.debug("Converted aggregate flow statistics : {}",message.build().toString());
161 listDataObject.add(message.build());
162 return listDataObject;
164 case OFPMPPORTSTATS: {
166 logger.debug("Received port statistics multipart response");
168 NodeConnectorStatisticsUpdateBuilder message = new NodeConnectorStatisticsUpdateBuilder();
170 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
171 message.setTransactionId(generateTransactionId(mpReply.getXid()));
173 MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase)mpReply.getMultipartReplyBody();
174 MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats();
176 List<NodeConnectorStatisticsAndPortNumberMap> statsMap =
177 new ArrayList<NodeConnectorStatisticsAndPortNumberMap>();
178 for (PortStats portStats: replyBody.getPortStats()){
180 NodeConnectorStatisticsAndPortNumberMapBuilder statsBuilder =
181 new NodeConnectorStatisticsAndPortNumberMapBuilder();
182 statsBuilder.setNodeConnectorId(
183 InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(sc.getFeatures().getDatapathId(),
184 portStats.getPortNo(), ofVersion));
186 BytesBuilder bytesBuilder = new BytesBuilder();
187 bytesBuilder.setReceived(portStats.getRxBytes());
188 bytesBuilder.setTransmitted(portStats.getTxBytes());
189 statsBuilder.setBytes(bytesBuilder.build());
191 PacketsBuilder packetsBuilder = new PacketsBuilder();
192 packetsBuilder.setReceived(portStats.getRxPackets());
193 packetsBuilder.setTransmitted(portStats.getTxPackets());
194 statsBuilder.setPackets(packetsBuilder.build());
196 DurationBuilder durationBuilder = new DurationBuilder();
197 if (portStats.getDurationSec() != null) {
198 durationBuilder.setSecond(new Counter32(portStats.getDurationSec()));
200 if (portStats.getDurationNsec() != null) {
201 durationBuilder.setNanosecond(new Counter32(portStats.getDurationNsec()));
203 statsBuilder.setDuration(durationBuilder.build());
204 statsBuilder.setCollisionCount(portStats.getCollisions());
205 statsBuilder.setKey(new NodeConnectorStatisticsAndPortNumberMapKey(statsBuilder.getNodeConnectorId()));
206 statsBuilder.setReceiveCrcError(portStats.getRxCrcErr());
207 statsBuilder.setReceiveDrops(portStats.getRxDropped());
208 statsBuilder.setReceiveErrors(portStats.getRxErrors());
209 statsBuilder.setReceiveFrameError(portStats.getRxFrameErr());
210 statsBuilder.setReceiveOverRunError(portStats.getRxOverErr());
211 statsBuilder.setTransmitDrops(portStats.getTxDropped());
212 statsBuilder.setTransmitErrors(portStats.getTxErrors());
214 statsMap.add(statsBuilder.build());
216 message.setNodeConnectorStatisticsAndPortNumberMap(statsMap);
218 logger.debug("Converted ports statistics : {}",message.build().toString());
220 listDataObject.add(message.build());
221 return listDataObject;
224 logger.debug("Received group statistics multipart reponse");
225 GroupStatisticsUpdatedBuilder message = new GroupStatisticsUpdatedBuilder();
227 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
228 message.setTransactionId(generateTransactionId(mpReply.getXid()));
229 MultipartReplyGroupCase caseBody = (MultipartReplyGroupCase)mpReply.getMultipartReplyBody();
230 MultipartReplyGroup replyBody = caseBody.getMultipartReplyGroup();
231 final Optional<List<GroupStats>> groupStatsList = ConvertorManager.getInstance().convert(replyBody.getGroupStats());
232 message.setGroupStats(groupStatsList.orElse(Collections.emptyList()));
233 logger.debug("Converted group statistics : {}",message.toString());
234 listDataObject.add(message.build());
235 return listDataObject;
237 case OFPMPGROUPDESC:{
238 logger.debug("Received group description statistics multipart reponse");
240 GroupDescStatsUpdatedBuilder message = new GroupDescStatsUpdatedBuilder();
242 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
243 message.setTransactionId(generateTransactionId(mpReply.getXid()));
244 MultipartReplyGroupDescCase caseBody = (MultipartReplyGroupDescCase)mpReply.getMultipartReplyBody();
245 MultipartReplyGroupDesc replyBody = caseBody.getMultipartReplyGroupDesc();
247 final VersionConvertorData data = new VersionConvertorData(sc.getPrimaryConductor().getVersion());
248 final Optional<List<GroupDescStats>> groupDescStatsList = ConvertorManager.getInstance().convert(replyBody.getGroupDesc(), data);
249 message.setGroupDescStats(groupDescStatsList.orElse(Collections.emptyList()));
250 logger.debug("Converted group statistics : {}",message.toString());
251 listDataObject.add(message.build());
252 return listDataObject;
254 case OFPMPGROUPFEATURES: {
255 logger.debug("Received group features multipart reponse");
256 GroupFeaturesUpdatedBuilder message = new GroupFeaturesUpdatedBuilder();
258 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
259 message.setTransactionId(generateTransactionId(mpReply.getXid()));
260 MultipartReplyGroupFeaturesCase caseBody = (MultipartReplyGroupFeaturesCase)mpReply.getMultipartReplyBody();
261 MultipartReplyGroupFeatures replyBody = caseBody.getMultipartReplyGroupFeatures();
262 List<Class<? extends GroupType>> supportedGroups =
263 new ArrayList<Class<? extends GroupType>>();
265 if(replyBody.getTypes().isOFPGTALL()){
266 supportedGroups.add(GroupAll.class);
268 if(replyBody.getTypes().isOFPGTSELECT()){
269 supportedGroups.add(GroupSelect.class);
271 if(replyBody.getTypes().isOFPGTINDIRECT()){
272 supportedGroups.add(GroupIndirect.class);
274 if(replyBody.getTypes().isOFPGTFF()){
275 supportedGroups.add(GroupFf.class);
277 message.setGroupTypesSupported(supportedGroups);
278 message.setMaxGroups(replyBody.getMaxGroups());
280 List<Class<? extends GroupCapability>> supportedCapabilities =
281 new ArrayList<Class<? extends GroupCapability>>();
283 if(replyBody.getCapabilities().isOFPGFCCHAINING()){
284 supportedCapabilities.add(Chaining.class);
286 if(replyBody.getCapabilities().isOFPGFCCHAININGCHECKS()){
287 supportedCapabilities.add(ChainingChecks.class);
289 if(replyBody.getCapabilities().isOFPGFCSELECTLIVENESS()){
290 supportedCapabilities.add(SelectLiveness.class);
292 if(replyBody.getCapabilities().isOFPGFCSELECTWEIGHT()){
293 supportedCapabilities.add(SelectWeight.class);
296 message.setGroupCapabilitiesSupported(supportedCapabilities);
298 message.setActions(getGroupActionsSupportBitmap(replyBody.getActionsBitmap()));
299 listDataObject.add(message.build());
301 return listDataObject;
304 logger.debug("Received meter statistics multipart reponse");
305 MeterStatisticsUpdatedBuilder message = new MeterStatisticsUpdatedBuilder();
307 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
308 message.setTransactionId(generateTransactionId(mpReply.getXid()));
310 MultipartReplyMeterCase caseBody = (MultipartReplyMeterCase)mpReply.getMultipartReplyBody();
311 MultipartReplyMeter replyBody = caseBody.getMultipartReplyMeter();
313 final Optional<List<org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats>> meterStatsList =
314 ConvertorManager.getInstance().convert(replyBody.getMeterStats());
316 message.setMeterStats(meterStatsList.orElse(Collections.emptyList()));
317 listDataObject.add(message.build());
318 return listDataObject;
320 case OFPMPMETERCONFIG:{
321 logger.debug("Received meter config statistics multipart reponse");
323 MeterConfigStatsUpdatedBuilder message = new MeterConfigStatsUpdatedBuilder();
325 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
326 message.setTransactionId(generateTransactionId(mpReply.getXid()));
328 MultipartReplyMeterConfigCase caseBody = (MultipartReplyMeterConfigCase)mpReply.getMultipartReplyBody();
329 MultipartReplyMeterConfig replyBody = caseBody.getMultipartReplyMeterConfig();
331 final Optional<List<MeterConfigStats>> meterConfigStatsList = ConvertorManager.getInstance().convert(replyBody.getMeterConfig());
333 message.setMeterConfigStats(meterConfigStatsList.orElse(Collections.emptyList()));
334 listDataObject.add(message.build());
335 return listDataObject;
337 case OFPMPMETERFEATURES:{
338 logger.debug("Received meter features multipart reponse");
339 //Convert OF message and send it to SAL listener
340 MeterFeaturesUpdatedBuilder message = new MeterFeaturesUpdatedBuilder();
342 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
343 message.setTransactionId(generateTransactionId(mpReply.getXid()));
345 MultipartReplyMeterFeaturesCase caseBody = (MultipartReplyMeterFeaturesCase)mpReply.getMultipartReplyBody();
346 MultipartReplyMeterFeatures replyBody = caseBody.getMultipartReplyMeterFeatures();
347 message.setMaxBands(replyBody.getMaxBands());
348 message.setMaxColor(replyBody.getMaxColor());
349 message.setMaxMeter(new Counter32(replyBody.getMaxMeter()));
351 List<Class<? extends MeterCapability>> supportedCapabilities =
352 new ArrayList<Class<? extends MeterCapability>>();
353 if(replyBody.getCapabilities().isOFPMFBURST()){
354 supportedCapabilities.add(MeterBurst.class);
356 if(replyBody.getCapabilities().isOFPMFKBPS()){
357 supportedCapabilities.add(MeterKbps.class);
360 if(replyBody.getCapabilities().isOFPMFPKTPS()){
361 supportedCapabilities.add(MeterPktps.class);
364 if(replyBody.getCapabilities().isOFPMFSTATS()){
365 supportedCapabilities.add(MeterStats.class);
368 message.setMeterCapabilitiesSupported(supportedCapabilities);
370 List<Class<? extends MeterBand>> supportedMeterBand =
371 new ArrayList<Class <? extends MeterBand>>();
372 if(replyBody.getBandTypes().isOFPMBTDROP()){
373 supportedMeterBand.add(MeterBandDrop.class);
375 if(replyBody.getBandTypes().isOFPMBTDSCPREMARK()){
376 supportedMeterBand.add(MeterBandDscpRemark.class);
378 message.setMeterBandSupported(supportedMeterBand);
379 listDataObject.add(message.build());
381 return listDataObject;
384 logger.debug("Received flow table statistics reponse from openflow {} switch",msg.getVersion()==1?"1.0":"1.3+");
386 FlowTableStatisticsUpdateBuilder message = new FlowTableStatisticsUpdateBuilder();
388 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
389 message.setTransactionId(generateTransactionId(mpReply.getXid()));
391 MultipartReplyTableCase caseBody = (MultipartReplyTableCase)mpReply.getMultipartReplyBody();
392 MultipartReplyTable replyBody = caseBody.getMultipartReplyTable();
393 List<TableStats> swTablesStats = replyBody.getTableStats();
395 List<FlowTableAndStatisticsMap> salFlowStats = new ArrayList<FlowTableAndStatisticsMap>();
396 for(TableStats swTableStats : swTablesStats){
397 FlowTableAndStatisticsMapBuilder statisticsBuilder = new FlowTableAndStatisticsMapBuilder();
399 statisticsBuilder.setActiveFlows(new Counter32(swTableStats.getActiveCount()));
400 statisticsBuilder.setPacketsLookedUp(new Counter64(swTableStats.getLookupCount()));
401 statisticsBuilder.setPacketsMatched(new Counter64(swTableStats.getMatchedCount()));
402 statisticsBuilder.setTableId(new TableId(swTableStats.getTableId()));
403 salFlowStats.add(statisticsBuilder.build());
406 message.setFlowTableAndStatisticsMap(salFlowStats);
408 logger.debug("Converted flow table statistics : {}",message.build().toString());
409 listDataObject.add(message.build());
410 return listDataObject;
413 logger.debug("Received queue statistics multipart response");
415 QueueStatisticsUpdateBuilder message = new QueueStatisticsUpdateBuilder();
417 message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
418 message.setTransactionId(generateTransactionId(mpReply.getXid()));
420 MultipartReplyQueueCase caseBody = (MultipartReplyQueueCase)mpReply.getMultipartReplyBody();
421 MultipartReplyQueue replyBody = caseBody.getMultipartReplyQueue();
423 List<QueueIdAndStatisticsMap> statsMap =
424 new ArrayList<QueueIdAndStatisticsMap>();
426 for (QueueStats queueStats: replyBody.getQueueStats()){
428 QueueIdAndStatisticsMapBuilder statsBuilder =
429 new QueueIdAndStatisticsMapBuilder();
430 statsBuilder.setNodeConnectorId(
431 InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(sc.getFeatures().getDatapathId(),
432 queueStats.getPortNo(), ofVersion));
433 statsBuilder.setTransmissionErrors(new Counter64(queueStats.getTxErrors()));
434 statsBuilder.setTransmittedBytes(new Counter64(queueStats.getTxBytes()));
435 statsBuilder.setTransmittedPackets(new Counter64(queueStats.getTxPackets()));
437 DurationBuilder durationBuilder = new DurationBuilder();
438 durationBuilder.setSecond(new Counter32(queueStats.getDurationSec()));
439 durationBuilder.setNanosecond(new Counter32(queueStats.getDurationNsec()));
440 statsBuilder.setDuration(durationBuilder.build());
442 statsBuilder.setQueueId(new QueueId(queueStats.getQueueId()));
443 statsBuilder.setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(sc.getFeatures().getDatapathId(),
444 queueStats.getPortNo(), ofVersion));
446 statsMap.add(statsBuilder.build());
448 message.setQueueIdAndStatisticsMap(statsMap);
450 logger.debug("Converted queue statistics : {}",message.build().toString());
451 listDataObject.add(message.build());
452 return listDataObject;
456 return listDataObject;
460 return listDataObject;
463 private static NodeId nodeIdFromDatapathId(final BigInteger datapathId) {
464 String current = datapathId.toString();
465 return new NodeId("openflow:" + current);
468 private static TransactionId generateTransactionId(final Long xid){
469 BigInteger bigIntXid = BigInteger.valueOf(xid);
470 return new TransactionId(bigIntXid);
474 * Method returns the bitmap of actions supported by each group.
475 * TODO: My recommendation would be, its good to have a respective model of
476 * 'type bits', which will generate a class where all these flags will eventually
477 * be stored as boolean. It will be convenient for application to check the
478 * supported action, rather then doing bitmap operation.
479 * @param actionsSupported
482 private static List<Long> getGroupActionsSupportBitmap(final List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType> actionsSupported){
483 List<Long> supportActionByGroups = new ArrayList<Long>();
484 for(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType supportedActions : actionsSupported){
485 long supportActionBitmap = 0;
486 supportActionBitmap |= supportedActions.isOFPATOUTPUT()?(1 << 0): 0;
487 supportActionBitmap |= supportedActions.isOFPATCOPYTTLOUT()?(1 << 11): 0;
488 supportActionBitmap |= supportedActions.isOFPATCOPYTTLIN()?(1 << 12): 0;
489 supportActionBitmap |= supportedActions.isOFPATSETMPLSTTL()?(1 << 15): 0;
490 supportActionBitmap |= supportedActions.isOFPATDECMPLSTTL()?(1 << 16): 0;
491 supportActionBitmap |= supportedActions.isOFPATPUSHVLAN()?(1 << 17): 0;
492 supportActionBitmap |= supportedActions.isOFPATPOPVLAN()?(1 << 18): 0;
493 supportActionBitmap |= supportedActions.isOFPATPUSHMPLS()?(1 << 19): 0;
494 supportActionBitmap |= supportedActions.isOFPATPOPMPLS()?(1 << 20): 0;
495 supportActionBitmap |= supportedActions.isOFPATSETQUEUE()?(1 << 21): 0;
496 supportActionBitmap |= supportedActions.isOFPATGROUP()?(1 << 22): 0;
497 supportActionBitmap |= supportedActions.isOFPATSETNWTTL()?(1 << 23): 0;
498 supportActionBitmap |= supportedActions.isOFPATDECNWTTL()?(1 << 24): 0;
499 supportActionBitmap |= supportedActions.isOFPATSETFIELD()?(1 << 25): 0;
500 supportActionBitmap |= supportedActions.isOFPATPUSHPBB()?(1 << 26): 0;
501 supportActionBitmap |= supportedActions.isOFPATPOPPBB()?(1 << 27): 0;
502 supportActionByGroups.add(Long.valueOf(supportActionBitmap));
504 return supportActionByGroups;