X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fstatistics-manager%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fmd%2Fstatistics%2Fmanager%2FFlowStatsTracker.java;h=1a14de6f5d5b9049e4199ce743fc7ba95ad913e3;hb=1d913b4ae95e8ce80645dd96df5b28750c3053e2;hp=abbc94ee2b40b9bb9a5069c0d015363e9e06726b;hpb=84c506752f2041f6133bd4514d87321fb9a311fe;p=controller.git diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java index abbc94ee2b..1a14de6f5d 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java @@ -7,6 +7,11 @@ */ package org.opendaylight.controller.md.statistics.manager; +import java.util.Collection; +import java.util.Map.Entry; + +import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent; +import org.opendaylight.controller.sal.binding.api.data.DataBrokerService; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; @@ -24,64 +29,50 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.O 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.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics; +import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Preconditions; -import com.google.common.util.concurrent.ListenableFuture; - -final class FlowStatsTracker extends AbstractStatsTracker { +final class FlowStatsTracker extends AbstractListeningStatsTracker { private static final Logger logger = LoggerFactory.getLogger(FlowStatsTracker.class); private final OpendaylightFlowStatisticsService flowStatsService; + private FlowTableStatsTracker flowTableStats; private int unaccountedFlowsCounter = 1; - FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, long lifetimeNanos) { - super(context, lifetimeNanos); - this.flowStatsService = Preconditions.checkNotNull(flowStatsService); + FlowStatsTracker(final OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context) { + super(context); + this.flowStatsService = flowStatsService; + } + FlowStatsTracker(final OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, final FlowTableStatsTracker flowTableStats) { + this(flowStatsService, context); + this.flowTableStats = flowTableStats; } @Override - protected void cleanupSingleStat(DataModificationTransaction trans, FlowStatsEntry item) { - InstanceIdentifier flowRef = getNodeIdentifierBuilder() - .augmentation(FlowCapableNode.class) - .child(Table.class, new TableKey(item.getTableId())) - .child(Flow.class,item.getFlow().getKey()) - .augmentation(FlowStatisticsData.class).toInstance(); + protected void cleanupSingleStat(final DataModificationTransaction trans, final FlowStatsEntry item) { + KeyedInstanceIdentifier flowRef = getNodeIdentifier() + .augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey(item.getTableId())) + .child(Flow.class, item.getFlow().getKey()); trans.removeOperationalData(flowRef); } @Override - protected FlowStatsEntry updateSingleStat(DataModificationTransaction trans, FlowAndStatisticsMapList map) { + protected FlowStatsEntry updateSingleStat(final DataModificationTransaction trans, final FlowAndStatisticsMapList map) { short tableId = map.getTableId(); - FlowBuilder flowBuilder = new FlowBuilder(); - FlowStatisticsDataBuilder flowStatisticsData = new FlowStatisticsDataBuilder(); - FlowBuilder flow = new FlowBuilder(); - flow.setContainerName(map.getContainerName()); - flow.setBufferId(map.getBufferId()); - flow.setCookie(map.getCookie()); - flow.setCookieMask(map.getCookieMask()); - flow.setFlags(map.getFlags()); - flow.setFlowName(map.getFlowName()); - flow.setHardTimeout(map.getHardTimeout()); - if(map.getFlowId() != null) + FlowBuilder flow = new FlowBuilder(map); + if(map.getFlowId() != null) { flow.setId(new FlowId(map.getFlowId().getValue())); - flow.setIdleTimeout(map.getIdleTimeout()); - flow.setInstallHw(map.isInstallHw()); - flow.setInstructions(map.getInstructions()); - if(map.getFlowId()!= null) + } + if(map.getFlowId()!= null) { flow.setKey(new FlowKey(new FlowId(map.getKey().getFlowId().getValue()))); - flow.setMatch(map.getMatch()); - flow.setOutGroup(map.getOutGroup()); - flow.setOutPort(map.getOutPort()); - flow.setPriority(map.getPriority()); - flow.setStrict(map.isStrict()); - flow.setTableId(tableId); + } Flow flowRule = flow.build(); @@ -98,22 +89,6 @@ final class FlowStatsTracker extends AbstractStatsTracker flowRef = getNodeIdentifierBuilder().augmentation(FlowCapableNode.class) .child(Table.class, new TableKey(tableId)) .child(Flow.class,newFlowKey).toInstance(); - flowBuilder.setKey(newFlowKey); - flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build()); + flow.setKey(newFlowKey); + flow.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build()); logger.debug("Flow {} is not present in config data store, augmenting statistics as an unaccounted flow", - flowBuilder.build()); + flow.build()); // Update entry with timestamp of latest response flow.setKey(newFlowKey); FlowStatsEntry flowStatsEntry = new FlowStatsEntry(tableId,flow.build()); - trans.putOperationalData(flowRef, flowBuilder.build()); + trans.putOperationalData(flowRef, flow.build()); return flowStatsEntry; } - public ListenableFuture requestAllFlowsAllTables() { - final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder(); - input.setNode(getNodeRef()); + @Override + protected InstanceIdentifier listenPath() { + return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Table.class).child(Flow.class).build(); + } - return requestHelper(flowStatsService.getAllFlowsStatisticsFromAllFlowTables(input.build())); + @Override + protected String statName() { + return "Flow"; } - public ListenableFuture requestAggregateFlows(final TableKey key) { - GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input = - new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder(); + @Override + public void request() { + // FIXME: it does not make sense to trigger this before sendAllFlowTablesStatisticsRequest() + // comes back -- we do not have any tables anyway. + final Collection tables = flowTableStats.getTables(); + logger.debug("Node {} supports {} table(s)", this.getNodeRef(), tables.size()); + for (final TableKey key : tables) { + logger.debug("Send aggregate stats request for flow table {} to node {}", key.getId(), this.getNodeRef()); + this.requestAggregateFlows(key); + } + + this.requestAllFlowsAllTables(); - input.setNode(getNodeRef()); - input.setTableId(new org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId(key.getId())); - return requestHelper(flowStatsService.getAggregateFlowStatisticsFromFlowTableForAllFlows(input.build())); } + public void requestAllFlowsAllTables() { + if (flowStatsService != null) { + final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder(); + input.setNode(getNodeRef()); - public ListenableFuture requestFlow(final Flow flow) { - final GetFlowStatisticsFromFlowTableInputBuilder input = - new GetFlowStatisticsFromFlowTableInputBuilder(flow); - input.setNode(getNodeRef()); + requestHelper(flowStatsService.getAllFlowsStatisticsFromAllFlowTables(input.build())); + } + } + + public void requestAggregateFlows(final TableKey key) { + if (flowStatsService != null) { + GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input = + new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder(); + + input.setNode(getNodeRef()); + input.setTableId(new org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId(key.getId())); + requestHelper(flowStatsService.getAggregateFlowStatisticsFromFlowTableForAllFlows(input.build())); + } + } + + public void requestFlow(final Flow flow) { + if (flowStatsService != null) { + final GetFlowStatisticsFromFlowTableInputBuilder input = + new GetFlowStatisticsFromFlowTableInputBuilder(flow); + input.setNode(getNodeRef()); + + requestHelper(flowStatsService.getFlowStatisticsFromFlowTable(input.build())); + } + } + + @Override + public void onDataChanged(final DataChangeEvent, DataObject> change) { + for (Entry, DataObject> e : change.getCreatedConfigurationData().entrySet()) { + if (Flow.class.equals(e.getKey().getTargetType())) { + final Flow flow = (Flow) e.getValue(); + logger.debug("Key {} triggered request for flow {}", e.getKey(), flow); + requestFlow(flow); + } else { + logger.debug("Ignoring key {}", e.getKey()); + } + } + + final DataModificationTransaction trans = startTransaction(); + for (InstanceIdentifier key : change.getRemovedConfigurationData()) { + if (Flow.class.equals(key.getTargetType())) { + @SuppressWarnings("unchecked") + final InstanceIdentifier flow = (InstanceIdentifier)key; + logger.debug("Key {} triggered remove of Flow from operational space.", key); + trans.removeOperationalData(flow); + } + } + trans.commit(); + } + + @Override + public void start(final DataBrokerService dbs) { + if (flowStatsService == null) { + logger.debug("No Flow Statistics service, not subscribing to flows on node {}", getNodeIdentifier()); + return; + } - return requestHelper(flowStatsService.getFlowStatisticsFromFlowTable(input.build())); + super.start(dbs); } }