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%2FNodeStatisticsHandler.java;h=db216237d01f7f8fe40523c2c62c6b6ecb88abde;hb=83e1c610eeefba667a19c243fbc1098072a8079d;hp=17f1ce2a7be482459d1fa78f6423f0bb952b4e92;hpb=7c1ced6aeaeca12da6786950c20a2133d9eb72e1;p=controller.git diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java index 17f1ce2a7b..db216237d0 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java @@ -7,8 +7,9 @@ */ package org.opendaylight.controller.md.statistics.manager; -import java.util.Collection; import java.util.List; +import java.util.Timer; +import java.util.TimerTask; import java.util.concurrent.TimeUnit; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; @@ -19,11 +20,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsData; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.aggregate.flow.statistics.AggregateFlowStatisticsBuilder; 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.OpendaylightFlowTableStatisticsService; 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.transaction.rev131103.TransactionAware; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeaturesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFeatures; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats; @@ -35,12 +41,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeaturesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterFeatures; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.AggregateFlowStatistics; +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService; 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.queue.statistics.rev131216.OpendaylightQueueStatisticsService; import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; @@ -55,10 +64,15 @@ import com.google.common.base.Preconditions; * * @author avishnoi@in.ibm.com */ -public final class NodeStatisticsHandler implements AutoCloseable { +public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableContext { private static final Logger logger = LoggerFactory.getLogger(NodeStatisticsHandler.class); + + private static final long STATS_COLLECTION_MILLIS = TimeUnit.SECONDS.toMillis(15); + private static final long FIRST_COLLECTION_MILLIS = TimeUnit.SECONDS.toMillis(5); private static final int NUMBER_OF_WAIT_CYCLES = 2; + private final MultipartMessageManager msgManager; + private final StatisticsRequestScheduler srScheduler; private final InstanceIdentifier targetNodeIdentifier; private final FlowStatsTracker flowStats; private final FlowTableStatsTracker flowTableStats; @@ -71,72 +85,112 @@ public final class NodeStatisticsHandler implements AutoCloseable { private final DataProviderService dps; private final NodeRef targetNodeRef; private final NodeKey targetNodeKey; - - public NodeStatisticsHandler(final DataProviderService dps, final NodeKey nodeKey) { + private final TimerTask task = new TimerTask() { + @Override + public void run() { + try{ + requestPeriodicStatistics(); + cleanStaleStatistics(); + }catch(Exception e){ + logger.warn("Exception occured while sending statistics request : {}",e); + } + } + }; + + public NodeStatisticsHandler(final DataProviderService dps, final NodeKey nodeKey, + final OpendaylightFlowStatisticsService flowStatsService, + final OpendaylightFlowTableStatisticsService flowTableStatsService, + final OpendaylightGroupStatisticsService groupStatsService, + final OpendaylightMeterStatisticsService meterStatsService, + final OpendaylightPortStatisticsService portStatsService, + final OpendaylightQueueStatisticsService queueStatsService, + final StatisticsRequestScheduler srScheduler) { this.dps = Preconditions.checkNotNull(dps); this.targetNodeKey = Preconditions.checkNotNull(nodeKey); + this.srScheduler = Preconditions.checkNotNull(srScheduler); this.targetNodeIdentifier = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).build(); this.targetNodeRef = new NodeRef(targetNodeIdentifier); - final long lifetimeNanos = TimeUnit.MILLISECONDS.toNanos(StatisticsProvider.STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES); - flowStats = new FlowStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); - flowTableStats = new FlowTableStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); - groupDescStats = new GroupDescStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); - groupStats = new GroupStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); - meterConfigStats = new MeterConfigStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); - meterStats = new MeterStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); - nodeConnectorStats = new NodeConnectorStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); - queueStats = new QueueStatsTracker(targetNodeIdentifier, dps, lifetimeNanos); + final long lifetimeNanos = TimeUnit.MILLISECONDS.toNanos(STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES); + + msgManager = new MultipartMessageManager(lifetimeNanos); + flowTableStats = new FlowTableStatsTracker(flowTableStatsService, this); + flowStats = new FlowStatsTracker(flowStatsService, this, flowTableStats); + groupDescStats = new GroupDescStatsTracker(groupStatsService, this); + groupStats = new GroupStatsTracker(groupStatsService, this); + meterConfigStats = new MeterConfigStatsTracker(meterStatsService, this); + meterStats = new MeterStatsTracker(meterStatsService, this); + nodeConnectorStats = new NodeConnectorStatsTracker(portStatsService, this); + queueStats = new QueueStatsTracker(queueStatsService, this); } public NodeKey getTargetNodeKey() { return targetNodeKey; } - public Collection getKnownTables() { - return flowTableStats.getTables(); - } - - public InstanceIdentifier getTargetNodeIdentifier() { + @Override + public InstanceIdentifier getNodeIdentifier() { return targetNodeIdentifier; } - public NodeRef getTargetNodeRef() { + @Override + public NodeRef getNodeRef() { return targetNodeRef; } - public synchronized void updateGroupDescStats(List list) { - groupDescStats.updateStats(list); + @Override + public DataModificationTransaction startDataModification() { + DataModificationTransaction dmt = dps.beginTransaction(); + dmt.registerListener(this.srScheduler); + return dmt; } - public synchronized void updateGroupStats(List list) { - groupStats.updateStats(list); + public synchronized void updateGroupDescStats(TransactionAware transaction, List list) { + if (msgManager.isExpectedTransaction(transaction)) { + groupDescStats.updateStats(list); + } } - public synchronized void updateMeterConfigStats(List list) { - meterConfigStats.updateStats(list); + public synchronized void updateGroupStats(TransactionAware transaction, List list) { + if (msgManager.isExpectedTransaction(transaction)) { + groupStats.updateStats(list); + } } - public synchronized void updateMeterStats(List list) { - meterStats.updateStats(list); + public synchronized void updateMeterConfigStats(TransactionAware transaction, List list) { + if (msgManager.isExpectedTransaction(transaction)) { + meterConfigStats.updateStats(list); + } } - public synchronized void updateQueueStats(List list) { - queueStats.updateStats(list); + public synchronized void updateMeterStats(TransactionAware transaction, List list) { + if (msgManager.isExpectedTransaction(transaction)) { + meterStats.updateStats(list); + } } - public synchronized void updateFlowTableStats(List list) { - flowTableStats.updateStats(list); + public synchronized void updateQueueStats(TransactionAware transaction, List list) { + if (msgManager.isExpectedTransaction(transaction)) { + queueStats.updateStats(list); + } } - public synchronized void updateNodeConnectorStats(List list) { - nodeConnectorStats.updateStats(list); + public synchronized void updateFlowTableStats(TransactionAware transaction, List list) { + if (msgManager.isExpectedTransaction(transaction)) { + flowTableStats.updateStats(list); + } } - public synchronized void updateAggregateFlowStats(Short tableId, AggregateFlowStatistics flowStats) { - if (tableId != null) { - final DataModificationTransaction trans = dps.beginTransaction(); + public synchronized void updateNodeConnectorStats(TransactionAware transaction, List list) { + if (msgManager.isExpectedTransaction(transaction)) { + nodeConnectorStats.updateStats(list); + } + } + public synchronized void updateAggregateFlowStats(TransactionAware transaction, AggregateFlowStatistics flowStats) { + final Short tableId = msgManager.isExpectedTableTransaction(transaction); + if (tableId != null) { + final DataModificationTransaction trans = this.startDataModification(); InstanceIdentifier tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey) .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance(); @@ -153,13 +207,18 @@ public final class NodeStatisticsHandler implements AutoCloseable { tableBuilder.addAugmentation(AggregateFlowStatisticsData.class, aggregateFlowStatisticsDataBuilder.build()); trans.putOperationalData(tableRef, tableBuilder.build()); - // FIXME: should we be tracking this data? trans.commit(); } } + public synchronized void updateFlowStats(TransactionAware transaction, List list) { + if (msgManager.isExpectedTransaction(transaction)) { + flowStats.updateStats(list); + } + } + public synchronized void updateGroupFeatures(GroupFeatures notification) { - final DataModificationTransaction trans = dps.beginTransaction(); + final DataModificationTransaction trans = this.startDataModification(); final NodeBuilder nodeData = new NodeBuilder(); nodeData.setKey(targetNodeKey); @@ -177,7 +236,7 @@ public final class NodeStatisticsHandler implements AutoCloseable { } public synchronized void updateMeterFeatures(MeterFeatures features) { - final DataModificationTransaction trans = dps.beginTransaction(); + final DataModificationTransaction trans = this.startDataModification(); final NodeBuilder nodeData = new NodeBuilder(); nodeData.setKey(targetNodeKey); @@ -194,28 +253,81 @@ public final class NodeStatisticsHandler implements AutoCloseable { trans.commit(); } - public synchronized void updateFlowStats(List list) { - flowStats.updateStats(list); - } - public synchronized void cleanStaleStatistics() { - final DataModificationTransaction trans = dps.beginTransaction(); - final long now = System.nanoTime(); + final DataModificationTransaction trans = this.startDataModification(); - flowStats.cleanup(trans, now); - groupDescStats.cleanup(trans, now); - groupStats.cleanup(trans, now); - meterConfigStats.cleanup(trans, now); - meterStats.cleanup(trans, now); - nodeConnectorStats.cleanup(trans, now); - queueStats.cleanup(trans, now); + flowStats.cleanup(trans); + groupDescStats.cleanup(trans); + groupStats.cleanup(trans); + meterConfigStats.cleanup(trans); + meterStats.cleanup(trans); + nodeConnectorStats.cleanup(trans); + queueStats.cleanup(trans); + msgManager.cleanStaleTransactionIds(); trans.commit(); } + public synchronized void requestPeriodicStatistics() { + logger.debug("Send requests for statistics collection to node : {}", targetNodeKey); + + this.srScheduler.addRequestToSchedulerQueue(flowTableStats); + + this.srScheduler.addRequestToSchedulerQueue(flowStats); + + this.srScheduler.addRequestToSchedulerQueue(nodeConnectorStats); + + this.srScheduler.addRequestToSchedulerQueue(groupStats); + + this.srScheduler.addRequestToSchedulerQueue(groupDescStats); + + this.srScheduler.addRequestToSchedulerQueue(meterStats); + + this.srScheduler.addRequestToSchedulerQueue(meterConfigStats); + + this.srScheduler.addRequestToSchedulerQueue(queueStats); + } + + public synchronized void start(final Timer timer) { + flowStats.start(dps); + groupDescStats.start(dps); + groupStats.start(dps); + meterConfigStats.start(dps); + meterStats.start(dps); + queueStats.start(dps); + + timer.schedule(task, (long) (Math.random() * FIRST_COLLECTION_MILLIS), STATS_COLLECTION_MILLIS); + + logger.debug("Statistics handler for node started with base interval {}ms", STATS_COLLECTION_MILLIS); + + requestPeriodicStatistics(); + } + @Override - public void close() { - // FIXME: cleanup any resources we hold (registrations, etc.) + public synchronized void close() { + task.cancel(); + flowStats.close(); + groupDescStats.close(); + groupStats.close(); + meterConfigStats.close(); + meterStats.close(); + queueStats.close(); + + //Clean up queued statistics request from scheduler queue + srScheduler.removeRequestsFromSchedulerQueue(this.getNodeRef()); + logger.debug("Statistics handler for {} shut down", targetNodeKey.getId()); } + + @Override + public void registerTransaction(TransactionId id) { + msgManager.recordExpectedTransaction(id); + logger.debug("Transaction {} for node {} sent successfully", id, targetNodeKey); + } + + @Override + public void registerTableTransaction(final TransactionId id, final Short table) { + msgManager.recordExpectedTableTransaction(id, table); + logger.debug("Transaction {} for node {} table {} sent successfully", id, targetNodeKey, table); + } }