/*
* Copyright (c) 2013, 2015 IBM Corporation and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.openflowplugin.openflow.md.core.translator;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import org.opendaylight.openflowplugin.api.openflow.md.core.IMDMessageTranslator;
import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;
import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.FlowStatsResponseConvertorData;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdateBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdateBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdateBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdatedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdatedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdatedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Chaining;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.ChainingChecks;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupAll;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupCapability;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFf;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupIndirect;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupSelect;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectLiveness;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectWeight;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdatedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesUpdatedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdatedBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBand;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDrop;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDscpRemark;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBurst;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterCapability;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterKbps;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterPktps;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregate;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.MultipartReplyGroupDesc;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.MultipartReplyMeterConfig;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeatures;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats;
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;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTable;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdateBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueStatisticsUpdateBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Class converts multipart reply messages to the notification objects defined
* by statistics provider (manager ).
*
* @author avishnoi@in.ibm.com
*
*/
public class MultipartReplyTranslator implements IMDMessageTranslator<OfHeader, List<DataObject>> {
protected static final Logger logger = LoggerFactory
.getLogger(MultipartReplyTranslator.class);
private final ConvertorExecutor convertorExecutor;
public MultipartReplyTranslator(ConvertorExecutor convertorExecutor) {
this.convertorExecutor = convertorExecutor;
}
@Override
public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sc, final OfHeader msg) {
List<DataObject> listDataObject = new CopyOnWriteArrayList<DataObject>();
OpenflowVersion ofVersion = OpenflowVersion.get(sc.getPrimaryConductor().getVersion());
final VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(sc.getPrimaryConductor().getVersion());
data.setDatapathId(sc.getFeatures().getDatapathId());
if(msg instanceof MultipartReplyMessage){
MultipartReplyMessage mpReply = (MultipartReplyMessage)msg;
NodeId node = MultipartReplyTranslator.nodeIdFromDatapathId(sc.getFeatures().getDatapathId());
switch (mpReply.getType()){
case OFPMPFLOW: {
logger.debug("Received flow statistics reponse from openflow {} switch",msg.getVersion()==1?"1.0":"1.3+");
FlowStatsResponseConvertorData flowData = new FlowStatsResponseConvertorData(data.getVersion());
flowData.setDatapathId(data.getDatapathId());
flowData.setMatchPath(MatchPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_MATCH);
FlowsStatisticsUpdateBuilder message = new FlowsStatisticsUpdateBuilder();
message.setId(node);
message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
message.setTransactionId(generateTransactionId(mpReply.getXid()));
MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase)mpReply.getMultipartReplyBody();
MultipartReplyFlow replyBody = caseBody.getMultipartReplyFlow();
final Optional<List<FlowAndStatisticsMapList>> flowAndStatisticsMapLists = convertorExecutor.convert(replyBody.getFlowStats(), flowData);
message.setFlowAndStatisticsMapList(flowAndStatisticsMapLists.orElse(Collections.emptyList()));
logger.debug("Converted flow statistics : {}",message.build().toString());
listDataObject.add(message.build());
return listDataObject;
}
case OFPMPAGGREGATE: {
logger.debug("Received aggregate flow statistics reponse from openflow {} switch",msg.getVersion()==1?"1.0":"1.3+");
AggregateFlowStatisticsUpdateBuilder message = new AggregateFlowStatisticsUpdateBuilder();
message.setId(node);
message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
message.setTransactionId(generateTransactionId(mpReply.getXid()));
MultipartReplyAggregateCase caseBody = (MultipartReplyAggregateCase)mpReply.getMultipartReplyBody();
MultipartReplyAggregate replyBody = caseBody.getMultipartReplyAggregate();
message.setByteCount(new Counter64(replyBody.getByteCount()));
message.setPacketCount(new Counter64(replyBody.getPacketCount()));
message.setFlowCount(new Counter32(replyBody.getFlowCount()));
logger.debug("Converted aggregate flow statistics : {}",message.build().toString());
listDataObject.add(message.build());
return listDataObject;
}
case OFPMPPORTSTATS: {
logger.debug("Received port statistics multipart response");
NodeConnectorStatisticsUpdateBuilder message = new NodeConnectorStatisticsUpdateBuilder();
message.setId(node);
message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
message.setTransactionId(generateTransactionId(mpReply.getXid()));
MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase)mpReply.getMultipartReplyBody();
MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats();
List<NodeConnectorStatisticsAndPortNumberMap> statsMap =
new ArrayList<NodeConnectorStatisticsAndPortNumberMap>();
for (PortStats portStats: replyBody.getPortStats()){
NodeConnectorStatisticsAndPortNumberMapBuilder statsBuilder =
new NodeConnectorStatisticsAndPortNumberMapBuilder();
statsBuilder.setNodeConnectorId(
InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(sc.getFeatures().getDatapathId(),
portStats.getPortNo(), ofVersion));
BytesBuilder bytesBuilder = new BytesBuilder();
bytesBuilder.setReceived(portStats.getRxBytes());
bytesBuilder.setTransmitted(portStats.getTxBytes());
statsBuilder.setBytes(bytesBuilder.build());
PacketsBuilder packetsBuilder = new PacketsBuilder();
packetsBuilder.setReceived(portStats.getRxPackets());
packetsBuilder.setTransmitted(portStats.getTxPackets());
statsBuilder.setPackets(packetsBuilder.build());
DurationBuilder durationBuilder = new DurationBuilder();
if (portStats.getDurationSec() != null) {
durationBuilder.setSecond(new Counter32(portStats.getDurationSec()));
}
if (portStats.getDurationNsec() != null) {
durationBuilder.setNanosecond(new Counter32(portStats.getDurationNsec()));
}
statsBuilder.setDuration(durationBuilder.build());
statsBuilder.setCollisionCount(portStats.getCollisions());
statsBuilder.setKey(new NodeConnectorStatisticsAndPortNumberMapKey(statsBuilder.getNodeConnectorId()));
statsBuilder.setReceiveCrcError(portStats.getRxCrcErr());
statsBuilder.setReceiveDrops(portStats.getRxDropped());
statsBuilder.setReceiveErrors(portStats.getRxErrors());
statsBuilder.setReceiveFrameError(portStats.getRxFrameErr());
statsBuilder.setReceiveOverRunError(portStats.getRxOverErr());
statsBuilder.setTransmitDrops(portStats.getTxDropped());
statsBuilder.setTransmitErrors(portStats.getTxErrors());
statsMap.add(statsBuilder.build());
}
message.setNodeConnectorStatisticsAndPortNumberMap(statsMap);
logger.debug("Converted ports statistics : {}",message.build().toString());
listDataObject.add(message.build());
return listDataObject;
}
case OFPMPGROUP:{
logger.debug("Received group statistics multipart reponse");
GroupStatisticsUpdatedBuilder message = new GroupStatisticsUpdatedBuilder();
message.setId(node);
message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
message.setTransactionId(generateTransactionId(mpReply.getXid()));
MultipartReplyGroupCase caseBody = (MultipartReplyGroupCase)mpReply.getMultipartReplyBody();
MultipartReplyGroup replyBody = caseBody.getMultipartReplyGroup();
final Optional<List<GroupStats>> groupStatsList = convertorExecutor.convert(replyBody.getGroupStats(), data);
message.setGroupStats(groupStatsList.orElse(Collections.emptyList()));
logger.debug("Converted group statistics : {}",message.toString());
listDataObject.add(message.build());
return listDataObject;
}
case OFPMPGROUPDESC:{
logger.debug("Received group description statistics multipart reponse");
GroupDescStatsUpdatedBuilder message = new GroupDescStatsUpdatedBuilder();
message.setId(node);
message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
message.setTransactionId(generateTransactionId(mpReply.getXid()));
MultipartReplyGroupDescCase caseBody = (MultipartReplyGroupDescCase)mpReply.getMultipartReplyBody();
MultipartReplyGroupDesc replyBody = caseBody.getMultipartReplyGroupDesc();
final Optional<List<GroupDescStats>> groupDescStatsList = convertorExecutor.convert(replyBody.getGroupDesc(), data);
message.setGroupDescStats(groupDescStatsList.orElse(Collections.emptyList()));
logger.debug("Converted group statistics : {}",message.toString());
listDataObject.add(message.build());
return listDataObject;
}
case OFPMPGROUPFEATURES: {
logger.debug("Received group features multipart reponse");
GroupFeaturesUpdatedBuilder message = new GroupFeaturesUpdatedBuilder();
message.setId(node);
message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
message.setTransactionId(generateTransactionId(mpReply.getXid()));
MultipartReplyGroupFeaturesCase caseBody = (MultipartReplyGroupFeaturesCase)mpReply.getMultipartReplyBody();
MultipartReplyGroupFeatures replyBody = caseBody.getMultipartReplyGroupFeatures();
List<Class<? extends GroupType>> supportedGroups =
new ArrayList<Class<? extends GroupType>>();
if(replyBody.getTypes().isOFPGTALL()){
supportedGroups.add(GroupAll.class);
}
if(replyBody.getTypes().isOFPGTSELECT()){
supportedGroups.add(GroupSelect.class);
}
if(replyBody.getTypes().isOFPGTINDIRECT()){
supportedGroups.add(GroupIndirect.class);
}
if(replyBody.getTypes().isOFPGTFF()){
supportedGroups.add(GroupFf.class);
}
message.setGroupTypesSupported(supportedGroups);
message.setMaxGroups(replyBody.getMaxGroups());
List<Class<? extends GroupCapability>> supportedCapabilities =
new ArrayList<Class<? extends GroupCapability>>();
if(replyBody.getCapabilities().isOFPGFCCHAINING()){
supportedCapabilities.add(Chaining.class);
}
if(replyBody.getCapabilities().isOFPGFCCHAININGCHECKS()){
supportedCapabilities.add(ChainingChecks.class);
}
if(replyBody.getCapabilities().isOFPGFCSELECTLIVENESS()){
supportedCapabilities.add(SelectLiveness.class);
}
if(replyBody.getCapabilities().isOFPGFCSELECTWEIGHT()){
supportedCapabilities.add(SelectWeight.class);
}
message.setGroupCapabilitiesSupported(supportedCapabilities);
message.setActions(getGroupActionsSupportBitmap(replyBody.getActionsBitmap()));
listDataObject.add(message.build());
return listDataObject;
}
case OFPMPMETER: {
logger.debug("Received meter statistics multipart reponse");
MeterStatisticsUpdatedBuilder message = new MeterStatisticsUpdatedBuilder();
message.setId(node);
message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
message.setTransactionId(generateTransactionId(mpReply.getXid()));
MultipartReplyMeterCase caseBody = (MultipartReplyMeterCase)mpReply.getMultipartReplyBody();
MultipartReplyMeter replyBody = caseBody.getMultipartReplyMeter();
final Optional<List<org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats>> meterStatsList =
convertorExecutor.convert(replyBody.getMeterStats(), data);
message.setMeterStats(meterStatsList.orElse(Collections.emptyList()));
listDataObject.add(message.build());
return listDataObject;
}
case OFPMPMETERCONFIG:{
logger.debug("Received meter config statistics multipart reponse");
MeterConfigStatsUpdatedBuilder message = new MeterConfigStatsUpdatedBuilder();
message.setId(node);
message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
message.setTransactionId(generateTransactionId(mpReply.getXid()));
MultipartReplyMeterConfigCase caseBody = (MultipartReplyMeterConfigCase)mpReply.getMultipartReplyBody();
MultipartReplyMeterConfig replyBody = caseBody.getMultipartReplyMeterConfig();
final Optional<List<MeterConfigStats>> meterConfigStatsList = convertorExecutor.convert(replyBody.getMeterConfig(), data);
message.setMeterConfigStats(meterConfigStatsList.orElse(Collections.emptyList()));
listDataObject.add(message.build());
return listDataObject;
}
case OFPMPMETERFEATURES:{
logger.debug("Received meter features multipart reponse");
//Convert OF message and send it to SAL listener
MeterFeaturesUpdatedBuilder message = new MeterFeaturesUpdatedBuilder();
message.setId(node);
message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
message.setTransactionId(generateTransactionId(mpReply.getXid()));
MultipartReplyMeterFeaturesCase caseBody = (MultipartReplyMeterFeaturesCase)mpReply.getMultipartReplyBody();
MultipartReplyMeterFeatures replyBody = caseBody.getMultipartReplyMeterFeatures();
message.setMaxBands(replyBody.getMaxBands());
message.setMaxColor(replyBody.getMaxColor());
message.setMaxMeter(new Counter32(replyBody.getMaxMeter()));
List<Class<? extends MeterCapability>> supportedCapabilities =
new ArrayList<Class<? extends MeterCapability>>();
if(replyBody.getCapabilities().isOFPMFBURST()){
supportedCapabilities.add(MeterBurst.class);
}
if(replyBody.getCapabilities().isOFPMFKBPS()){
supportedCapabilities.add(MeterKbps.class);
}
if(replyBody.getCapabilities().isOFPMFPKTPS()){
supportedCapabilities.add(MeterPktps.class);
}
if(replyBody.getCapabilities().isOFPMFSTATS()){
supportedCapabilities.add(MeterStats.class);
}
message.setMeterCapabilitiesSupported(supportedCapabilities);
List<Class<? extends MeterBand>> supportedMeterBand =
new ArrayList<Class <? extends MeterBand>>();
if(replyBody.getBandTypes().isOFPMBTDROP()){
supportedMeterBand.add(MeterBandDrop.class);
}
if(replyBody.getBandTypes().isOFPMBTDSCPREMARK()){
supportedMeterBand.add(MeterBandDscpRemark.class);
}
message.setMeterBandSupported(supportedMeterBand);
listDataObject.add(message.build());
return listDataObject;
}
case OFPMPTABLE: {
logger.debug("Received flow table statistics reponse from openflow {} switch",msg.getVersion()==1?"1.0":"1.3+");
FlowTableStatisticsUpdateBuilder message = new FlowTableStatisticsUpdateBuilder();
message.setId(node);
message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
message.setTransactionId(generateTransactionId(mpReply.getXid()));
MultipartReplyTableCase caseBody = (MultipartReplyTableCase)mpReply.getMultipartReplyBody();
MultipartReplyTable replyBody = caseBody.getMultipartReplyTable();
List<TableStats> swTablesStats = replyBody.getTableStats();
List<FlowTableAndStatisticsMap> salFlowStats = new ArrayList<FlowTableAndStatisticsMap>();
for(TableStats swTableStats : swTablesStats){
FlowTableAndStatisticsMapBuilder statisticsBuilder = new FlowTableAndStatisticsMapBuilder();
statisticsBuilder.setActiveFlows(new Counter32(swTableStats.getActiveCount()));
statisticsBuilder.setPacketsLookedUp(new Counter64(swTableStats.getLookupCount()));
statisticsBuilder.setPacketsMatched(new Counter64(swTableStats.getMatchedCount()));
statisticsBuilder.setTableId(new TableId(swTableStats.getTableId()));
salFlowStats.add(statisticsBuilder.build());
}
message.setFlowTableAndStatisticsMap(salFlowStats);
logger.debug("Converted flow table statistics : {}",message.build().toString());
listDataObject.add(message.build());
return listDataObject;
}
case OFPMPQUEUE: {
logger.debug("Received queue statistics multipart response");
QueueStatisticsUpdateBuilder message = new QueueStatisticsUpdateBuilder();
message.setId(node);
message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
message.setTransactionId(generateTransactionId(mpReply.getXid()));
MultipartReplyQueueCase caseBody = (MultipartReplyQueueCase)mpReply.getMultipartReplyBody();
MultipartReplyQueue replyBody = caseBody.getMultipartReplyQueue();
List<QueueIdAndStatisticsMap> statsMap =
new ArrayList<QueueIdAndStatisticsMap>();
for (QueueStats queueStats: replyBody.getQueueStats()){
QueueIdAndStatisticsMapBuilder statsBuilder =
new QueueIdAndStatisticsMapBuilder();
statsBuilder.setNodeConnectorId(
InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(sc.getFeatures().getDatapathId(),
queueStats.getPortNo(), ofVersion));
statsBuilder.setTransmissionErrors(new Counter64(queueStats.getTxErrors()));
statsBuilder.setTransmittedBytes(new Counter64(queueStats.getTxBytes()));
statsBuilder.setTransmittedPackets(new Counter64(queueStats.getTxPackets()));
DurationBuilder durationBuilder = new DurationBuilder();
durationBuilder.setSecond(new Counter32(queueStats.getDurationSec()));
durationBuilder.setNanosecond(new Counter32(queueStats.getDurationNsec()));
statsBuilder.setDuration(durationBuilder.build());
statsBuilder.setQueueId(new QueueId(queueStats.getQueueId()));
statsBuilder.setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(sc.getFeatures().getDatapathId(),
queueStats.getPortNo(), ofVersion));
statsMap.add(statsBuilder.build());
}
message.setQueueIdAndStatisticsMap(statsMap);
logger.debug("Converted queue statistics : {}",message.build().toString());
listDataObject.add(message.build());
return listDataObject;
}
default:
return listDataObject;
}
}
return listDataObject;
}
private static NodeId nodeIdFromDatapathId(final BigInteger datapathId) {
String current = datapathId.toString();
return new NodeId("openflow:" + current);
}
private static TransactionId generateTransactionId(final Long xid){
BigInteger bigIntXid = BigInteger.valueOf(xid);
return new TransactionId(bigIntXid);
}
/*
* Method returns the bitmap of actions supported by each group.
* TODO: My recommendation would be, its good to have a respective model of
* 'type bits', which will generate a class where all these flags will eventually
* be stored as boolean. It will be convenient for application to check the
* supported action, rather then doing bitmap operation.
* @param actionsSupported
* @return
*/
private static List<Long> getGroupActionsSupportBitmap(final List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType> actionsSupported){
List<Long> supportActionByGroups = new ArrayList<Long>();
for(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType supportedActions : actionsSupported){
long supportActionBitmap = 0;
supportActionBitmap |= supportedActions.isOFPATOUTPUT()?(1 << 0): 0;
supportActionBitmap |= supportedActions.isOFPATCOPYTTLOUT()?(1 << 11): 0;
supportActionBitmap |= supportedActions.isOFPATCOPYTTLIN()?(1 << 12): 0;
supportActionBitmap |= supportedActions.isOFPATSETMPLSTTL()?(1 << 15): 0;
supportActionBitmap |= supportedActions.isOFPATDECMPLSTTL()?(1 << 16): 0;
supportActionBitmap |= supportedActions.isOFPATPUSHVLAN()?(1 << 17): 0;
supportActionBitmap |= supportedActions.isOFPATPOPVLAN()?(1 << 18): 0;
supportActionBitmap |= supportedActions.isOFPATPUSHMPLS()?(1 << 19): 0;
supportActionBitmap |= supportedActions.isOFPATPOPMPLS()?(1 << 20): 0;
supportActionBitmap |= supportedActions.isOFPATSETQUEUE()?(1 << 21): 0;
supportActionBitmap |= supportedActions.isOFPATGROUP()?(1 << 22): 0;
supportActionBitmap |= supportedActions.isOFPATSETNWTTL()?(1 << 23): 0;
supportActionBitmap |= supportedActions.isOFPATDECNWTTL()?(1 << 24): 0;
supportActionBitmap |= supportedActions.isOFPATSETFIELD()?(1 << 25): 0;
supportActionBitmap |= supportedActions.isOFPATPUSHPBB()?(1 << 26): 0;
supportActionBitmap |= supportedActions.isOFPATPOPPBB()?(1 << 27): 0;
supportActionByGroups.add(Long.valueOf(supportActionBitmap));
}
return supportActionByGroups;
}
}