From 84c506752f2041f6133bd4514d87321fb9a311fe Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Fri, 14 Feb 2014 20:24:05 +0100 Subject: [PATCH] Move statistics request functions into trackers This moves the gory details of specific requests into their respective trackers. It also makes the request pipeline asynchronous. Change-Id: I56ad175bc75b1af18263ae294cb3ffc118557abd Signed-off-by: Robert Varga --- .../manager/AbstractStatsTracker.java | 53 ++- .../manager/FlowCapableContext.java | 24 ++ .../statistics/manager/FlowStatsTracker.java | 40 ++- .../manager/FlowTableStatsTracker.java | 21 +- .../manager/GroupDescStatsTracker.java | 22 +- .../statistics/manager/GroupStatsTracker.java | 20 +- .../manager/MeterConfigStatsTracker.java | 21 +- .../statistics/manager/MeterStatsTracker.java | 21 +- .../manager/MultipartMessageManager.java | 10 +- .../manager/NodeConnectorStatsTracker.java | 21 +- .../manager/NodeStatisticsHandler.java | 319 +++++++----------- .../statistics/manager/QueueStatsTracker.java | 35 +- .../manager/StatisticsProvider.java | 9 +- .../manager/StatisticsUpdateHandler.java | 30 +- 14 files changed, 370 insertions(+), 276 deletions(-) create mode 100644 opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowCapableContext.java diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java index aa7720cf10..03ed6cb1f1 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java @@ -12,34 +12,63 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.Future; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; -import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +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.inventory.rev130819.NodeRef; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; +import org.opendaylight.yangtools.yang.common.RpcResult; +import com.google.common.base.Function; import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.JdkFutureAdapters; +import com.google.common.util.concurrent.ListenableFuture; abstract class AbstractStatsTracker { + private static final Function, TransactionId> FUNCTION = + new Function, TransactionId>() { + @Override + public TransactionId apply(RpcResult input) { + return input.getResult().getTransactionId(); + } + }; + private final Map trackedItems = new HashMap<>(); - private final InstanceIdentifier nodeIdentifier; - private final DataProviderService dps; + private final FlowCapableContext context; private final long lifetimeNanos; - protected AbstractStatsTracker(final InstanceIdentifier nodeIdentifier, final DataProviderService dps, long lifetimeNanos) { - this.nodeIdentifier = Preconditions.checkNotNull(nodeIdentifier); - this.dps = Preconditions.checkNotNull(dps); + protected AbstractStatsTracker(final FlowCapableContext context, final long lifetimeNanos) { + this.context = Preconditions.checkNotNull(context); this.lifetimeNanos = lifetimeNanos; } protected final InstanceIdentifierBuilder getNodeIdentifierBuilder() { - return InstanceIdentifier.builder(nodeIdentifier); + return InstanceIdentifier.builder(getNodeIdentifier()); + } + + protected final NodeRef getNodeRef() { + return context.getNodeRef(); + } + + protected final InstanceIdentifier getNodeIdentifier() { + return context.getNodeIdentifier(); + } + + protected static final ListenableFuture requestHelper(Future> future) { + return Futures.transform(JdkFutureAdapters.listenInPoolThread(future), FUNCTION); } - final synchronized void updateStats(List list) { + protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item); + protected abstract K updateSingleStat(DataModificationTransaction trans, I item); + + public final synchronized void updateStats(List list) { final Long expiryTime = System.nanoTime() + lifetimeNanos; - final DataModificationTransaction trans = dps.beginTransaction(); + final DataModificationTransaction trans = context.startDataModification(); for (final I item : list) { trackedItems.put(updateSingleStat(trans, item), expiryTime); @@ -48,8 +77,7 @@ abstract class AbstractStatsTracker { trans.commit(); } - - final synchronized void cleanup(final DataModificationTransaction trans, long now) { + public final synchronized void cleanup(final DataModificationTransaction trans, long now) { for (Iterator> it = trackedItems.entrySet().iterator();it.hasNext();){ Entry e = it.next(); if (now > e.getValue()) { @@ -58,7 +86,4 @@ abstract class AbstractStatsTracker { } } } - - protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item); - protected abstract K updateSingleStat(DataModificationTransaction trans, I item); } diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowCapableContext.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowCapableContext.java new file mode 100644 index 0000000000..9893c28f6c --- /dev/null +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowCapableContext.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. 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.controller.md.statistics.manager; + +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Interface exposed to AbstractStatsTracker by its parent NodeStatisticsHandler. + * While we could simply exist without this interface, its purpose is to document + * the contract between the two classes. + */ +interface FlowCapableContext { + InstanceIdentifier getNodeIdentifier(); + NodeRef getNodeRef(); + DataModificationTransaction startDataModification(); +} 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 e1854375a5..abbc94ee2b 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 @@ -8,7 +8,6 @@ package org.opendaylight.controller.md.statistics.manager; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; -import org.opendaylight.controller.sal.binding.api.data.DataProviderService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; @@ -18,21 +17,30 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService; 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.inventory.rev130819.nodes.Node; +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.InstanceIdentifier; 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 { private static final Logger logger = LoggerFactory.getLogger(FlowStatsTracker.class); + private final OpendaylightFlowStatisticsService flowStatsService; private int unaccountedFlowsCounter = 1; - FlowStatsTracker(InstanceIdentifier nodeIdentifier, DataProviderService dps, long lifetimeNanos) { - super(nodeIdentifier, dps, lifetimeNanos); + FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, long lifetimeNanos) { + super(context, lifetimeNanos); + this.flowStatsService = Preconditions.checkNotNull(flowStatsService); } @Override @@ -183,4 +191,28 @@ final class FlowStatsTracker extends AbstractStatsTracker requestAllFlowsAllTables() { + final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder(); + input.setNode(getNodeRef()); + + return requestHelper(flowStatsService.getAllFlowsStatisticsFromAllFlowTables(input.build())); + } + + public ListenableFuture requestAggregateFlows(final TableKey key) { + GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input = + new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder(); + + 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 ListenableFuture requestFlow(final Flow flow) { + final GetFlowStatisticsFromFlowTableInputBuilder input = + new GetFlowStatisticsFromFlowTableInputBuilder(flow); + input.setNode(getNodeRef()); + + return requestHelper(flowStatsService.getFlowStatisticsFromFlowTable(input.build())); + } } diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java index 2544d55805..4136b3d0e4 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java @@ -12,25 +12,31 @@ import java.util.Set; import java.util.concurrent.ConcurrentSkipListSet; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; -import org.opendaylight.controller.sal.binding.api.data.DataProviderService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder; +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.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatisticsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ListenableFuture; + final class FlowTableStatsTracker extends AbstractStatsTracker { private final Set privateTables = new ConcurrentSkipListSet<>(); private final Set tables = Collections.unmodifiableSet(privateTables); + private final OpendaylightFlowTableStatisticsService flowTableStatsService; - FlowTableStatsTracker(InstanceIdentifier nodeIdentifier, DataProviderService dps, long lifetimeNanos) { - super(nodeIdentifier, dps, lifetimeNanos); + FlowTableStatsTracker(OpendaylightFlowTableStatisticsService flowTableStatsService, final FlowCapableContext context, long lifetimeNanos) { + super(context, lifetimeNanos); + this.flowTableStatsService = Preconditions.checkNotNull(flowTableStatsService); } Set getTables() { @@ -58,4 +64,11 @@ final class FlowTableStatsTracker extends AbstractStatsTracker request() { + final GetFlowTablesStatisticsInputBuilder input = new GetFlowTablesStatisticsInputBuilder(); + input.setNode(getNodeRef()); + + return requestHelper(flowTableStatsService.getFlowTablesStatistics(input.build())); + } } diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupDescStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupDescStatsTracker.java index 928bf4ea55..90702e4818 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupDescStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupDescStatsTracker.java @@ -8,21 +8,28 @@ package org.opendaylight.controller.md.statistics.manager; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; -import org.opendaylight.controller.sal.binding.api.data.DataProviderService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStats; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.desc.GroupDescBuilder; 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.groups.Group; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ListenableFuture; + final class GroupDescStatsTracker extends AbstractStatsTracker { - public GroupDescStatsTracker(final InstanceIdentifier targetNodeIdentifier, final DataProviderService dps, final long lifetimeNanos) { - super(targetNodeIdentifier, dps, lifetimeNanos); + private final OpendaylightGroupStatisticsService groupStatsService; + + public GroupDescStatsTracker(OpendaylightGroupStatisticsService groupStatsService, final FlowCapableContext context, final long lifetimeNanos) { + super(context, lifetimeNanos); + this.groupStatsService = Preconditions.checkNotNull(groupStatsService); } @Override @@ -50,4 +57,11 @@ final class GroupDescStatsTracker extends AbstractStatsTracker request() { + final GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder(); + input.setNode(getNodeRef()); + + return requestHelper(groupStatsService.getGroupDescription(input.build())); + } } diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupStatsTracker.java index a5498f5a30..40f526e13c 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupStatsTracker.java @@ -8,22 +8,28 @@ package org.opendaylight.controller.md.statistics.manager; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; -import org.opendaylight.controller.sal.binding.api.data.DataProviderService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatisticsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatisticsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ListenableFuture; + final class GroupStatsTracker extends AbstractStatsTracker { + private final OpendaylightGroupStatisticsService groupStatsService; - GroupStatsTracker(InstanceIdentifier nodeIdentifier, DataProviderService dps, long lifetimeNanos) { - super(nodeIdentifier, dps, lifetimeNanos); + GroupStatsTracker(OpendaylightGroupStatisticsService groupStatsService, FlowCapableContext context, long lifetimeNanos) { + super(context, lifetimeNanos); + this.groupStatsService = Preconditions.checkNotNull(groupStatsService); } @Override @@ -52,4 +58,10 @@ final class GroupStatsTracker extends AbstractStatsTracker request() { + final GetAllGroupStatisticsInputBuilder input = new GetAllGroupStatisticsInputBuilder(); + input.setNode(getNodeRef()); + + return requestHelper(groupStatsService.getAllGroupStatistics(input.build())); + } } diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterConfigStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterConfigStatsTracker.java index dcb0b403dc..150728db16 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterConfigStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterConfigStatsTracker.java @@ -8,21 +8,28 @@ package org.opendaylight.controller.md.statistics.manager; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; -import org.opendaylight.controller.sal.binding.api.data.DataProviderService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStats; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStatsBuilder; +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.meter.MeterConfigStatsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ListenableFuture; + final class MeterConfigStatsTracker extends AbstractStatsTracker { - protected MeterConfigStatsTracker(InstanceIdentifier nodeIdentifier, DataProviderService dps, long lifetimeNanos) { - super(nodeIdentifier, dps, lifetimeNanos); + private final OpendaylightMeterStatisticsService meterStatsService; + + protected MeterConfigStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context, long lifetimeNanos) { + super(context, lifetimeNanos); + this.meterStatsService = Preconditions.checkNotNull(meterStatsService); } @Override @@ -53,4 +60,10 @@ final class MeterConfigStatsTracker extends AbstractStatsTracker request() { + GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder(); + input.setNode(getNodeRef()); + + return requestHelper(meterStatsService.getAllMeterConfigStatistics(input.build())); + } } diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterStatsTracker.java index 381db8a39f..807e82c9ef 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterStatsTracker.java @@ -8,22 +8,28 @@ package org.opendaylight.controller.md.statistics.manager; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; -import org.opendaylight.controller.sal.binding.api.data.DataProviderService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatisticsBuilder; +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.meter.MeterStatisticsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ListenableFuture; + final class MeterStatsTracker extends AbstractStatsTracker { + private final OpendaylightMeterStatisticsService meterStatsService; - MeterStatsTracker(InstanceIdentifier nodeIdentifier, DataProviderService dps, long lifetimeNanos) { - super(nodeIdentifier, dps, lifetimeNanos); + MeterStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context, long lifetimeNanos) { + super(context, lifetimeNanos); + this.meterStatsService = Preconditions.checkNotNull(meterStatsService); } @Override @@ -52,4 +58,11 @@ final class MeterStatsTracker extends AbstractStatsTracker request() { + GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder(); + input.setNode(getNodeRef()); + + return requestHelper(meterStatsService.getAllMeterStatistics(input.build())); + } } diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MultipartMessageManager.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MultipartMessageManager.java index 0ce551a17c..e52a718a4e 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MultipartMessageManager.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MultipartMessageManager.java @@ -7,9 +7,9 @@ */ package org.opendaylight.controller.md.statistics.manager; -import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware; @@ -32,12 +32,12 @@ public class MultipartMessageManager { * by Statistics Manager. Statistics Manager won't entertain any multipart * response for which it didn't send the request. */ - private final Map txIdToRequestTypeMap = new HashMap<>(); + private final Map txIdToRequestTypeMap = new ConcurrentHashMap<>(); /* * Map to keep track of the request tx id for flow table statistics request. * Because flow table statistics multi part response do not contains the table id. */ - private final Map txIdTotableIdMap = new HashMap<>(); + private final Map txIdTotableIdMap = new ConcurrentHashMap<>(); private static final class TxIdEntry { private final StatsRequestType requestType; @@ -126,7 +126,7 @@ public class MultipartMessageManager { StatisticsProvider.STATS_COLLECTION_MILLIS*NUMBER_OF_WAIT_CYCLES); } - public enum StatsRequestType{ + public enum StatsRequestType { ALL_FLOW, AGGR_FLOW, ALL_PORT, @@ -138,7 +138,7 @@ public class MultipartMessageManager { METER_CONFIG } - public void cleanStaleTransactionIds(){ + public void cleanStaleTransactionIds() { final long now = System.nanoTime(); for (Iterator it = txIdToRequestTypeMap.keySet().iterator();it.hasNext();){ diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeConnectorStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeConnectorStatsTracker.java index 2a8b180a51..83d9da13f0 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeConnectorStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeConnectorStatsTracker.java @@ -8,24 +8,30 @@ package org.opendaylight.controller.md.statistics.manager; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; -import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData; import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService; import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatisticsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ListenableFuture; + final class NodeConnectorStatsTracker extends AbstractStatsTracker { private static final Logger logger = LoggerFactory.getLogger(NodeConnectorStatsTracker.class); + private final OpendaylightPortStatisticsService portStatsService; - NodeConnectorStatsTracker(InstanceIdentifier nodeIdentifier, DataProviderService dps, long lifetimeNanos) { - super(nodeIdentifier, dps, lifetimeNanos); + NodeConnectorStatsTracker(final OpendaylightPortStatisticsService portStatsService, final FlowCapableContext context, long lifetimeNanos) { + super(context, lifetimeNanos); + this.portStatsService = Preconditions.checkNotNull(portStatsService); } @Override @@ -70,4 +76,11 @@ final class NodeConnectorStatsTracker extends AbstractStatsTracker request() { + final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder(); + input.setNode(getNodeRef()); + + return requestHelper(portStatsService.getAllNodeConnectorsStatistics(input.build())); + } } 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 5d5d17230f..413c01b1bc 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 @@ -9,8 +9,6 @@ package org.opendaylight.controller.md.statistics.manager; import java.util.Collection; import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType; @@ -23,26 +21,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; 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.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutput; 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.GetFlowTablesStatisticsInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsOutput; 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.flow.types.queue.rev130925.QueueId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutput; 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; @@ -56,10 +42,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutput; 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; @@ -68,22 +50,18 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter 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.GetAllNodeConnectorsStatisticsInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.GetAllNodeConnectorsStatisticsOutput; 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.GetAllQueuesStatisticsFromAllPortsInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortOutput; 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.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; /** * This class handles the lifecycle of per-node statistics. It receives data @@ -92,17 +70,10 @@ 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 int NUMBER_OF_WAIT_CYCLES = 2; - private final OpendaylightFlowStatisticsService flowStatsService; - private final OpendaylightFlowTableStatisticsService flowTableStatsService; - private final OpendaylightGroupStatisticsService groupStatsService; - private final OpendaylightMeterStatisticsService meterStatsService; - private final OpendaylightPortStatisticsService portStatsService; - private final OpendaylightQueueStatisticsService queueStatsService; - private final MultipartMessageManager msgManager = new MultipartMessageManager(); private final InstanceIdentifier targetNodeIdentifier; private final FlowStatsTracker flowStats; @@ -129,40 +100,64 @@ public final class NodeStatisticsHandler implements AutoCloseable { this.targetNodeIdentifier = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).build(); this.targetNodeRef = new NodeRef(targetNodeIdentifier); - this.flowStatsService = flowStatsService; - this.flowTableStatsService = flowTableStatsService; - this.groupStatsService = groupStatsService; - this.meterStatsService = meterStatsService; - this.portStatsService = portStatsService; - this.queueStatsService = queueStatsService; - 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); + + if (flowStatsService != null) { + flowStats = new FlowStatsTracker(flowStatsService, this, lifetimeNanos); + } else { + flowStats = null; + } + if (flowTableStatsService != null) { + flowTableStats = new FlowTableStatsTracker(flowTableStatsService, this, lifetimeNanos); + } else { + flowTableStats = null; + } + + if (groupStatsService != null) { + groupDescStats = new GroupDescStatsTracker(groupStatsService, this, lifetimeNanos); + groupStats = new GroupStatsTracker(groupStatsService, this, lifetimeNanos); + } else { + groupDescStats = null; + groupStats = null; + } + if (meterStatsService != null) { + meterConfigStats = new MeterConfigStatsTracker(meterStatsService, this, lifetimeNanos); + meterStats = new MeterStatsTracker(meterStatsService, this, lifetimeNanos); + } else { + meterConfigStats = null; + meterStats = null; + } + if (portStatsService != null) { + nodeConnectorStats = new NodeConnectorStatsTracker(portStatsService, this, lifetimeNanos); + } else { + nodeConnectorStats = null; + } + if (queueStatsService != null) { + queueStats = new QueueStatsTracker(queueStatsService, this, lifetimeNanos); + } else { + queueStats = null; + } } 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; } + @Override + public DataModificationTransaction startDataModification() { + return dps.beginTransaction(); + } + public synchronized void updateGroupDescStats(TransactionAware transaction, Boolean more, List list) { if (msgManager.isExpectedTransaction(transaction, more)) { groupDescStats.updateStats(list); @@ -290,37 +285,38 @@ public final class NodeStatisticsHandler implements AutoCloseable { public synchronized void requestPeriodicStatistics() { logger.debug("Send requests for statistics collection to node : {}", targetNodeKey); - try{ - if(flowTableStatsService != null){ - final GetFlowTablesStatisticsInputBuilder input = new GetFlowTablesStatisticsInputBuilder(); - input.setNode(targetNodeRef); - - Future> response = flowTableStatsService.getFlowTablesStatistics(input.build()); - recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_FLOW_TABLE); + if (flowTableStats != null){ + registerTransaction(flowTableStats.request(), StatsRequestType.ALL_FLOW); + } + if (flowStats != null){ + // 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)", targetNodeKey, tables.size()); + for (final TableKey key : tables) { + logger.debug("Send aggregate stats request for flow table {} to node {}", key.getId(), targetNodeKey); + registerTableTransaction(flowStats.requestAggregateFlows(key), key.getId()); } - if(flowStatsService != null){ - // FIXME: it does not make sense to trigger this before sendAllFlowTablesStatisticsRequest() - // comes back -- we do not have any tables anyway. - sendAggregateFlowsStatsFromAllTablesRequest(); - sendAllFlowsStatsFromAllTablesRequest(); - } - if(portStatsService != null){ - sendAllNodeConnectorsStatisticsRequest(); - } - if(groupStatsService != null){ - sendAllGroupStatisticsRequest(); - sendGroupDescriptionRequest(); - } - if(meterStatsService != null){ - sendAllMeterStatisticsRequest(); - sendMeterConfigStatisticsRequest(); - } - if(queueStatsService != null){ - sendAllQueueStatsFromAllNodeConnector(); - } - } catch(Exception e) { - logger.error("Exception occured while sending statistics requests", e); + registerTransaction(flowStats.requestAllFlowsAllTables(), StatsRequestType.ALL_FLOW); + } + + if (nodeConnectorStats != null) { + registerTransaction(nodeConnectorStats.request(), StatsRequestType.ALL_PORT); + } + + if (groupStats != null) { + registerTransaction(groupStats.request(), StatsRequestType.ALL_GROUP); + } + sendGroupDescriptionRequest(); + + if (meterStats != null) { + registerTransaction(meterStats.request(), StatsRequestType.ALL_METER); + } + sendMeterConfigStatisticsRequest(); + + if(queueStats != null) { + registerTransaction(queueStats.request(), StatsRequestType.ALL_QUEUE_STATS); } } @@ -334,132 +330,69 @@ public final class NodeStatisticsHandler implements AutoCloseable { logger.debug("Statistics handler for {} shut down", targetNodeKey.getId()); } - synchronized void sendFlowStatsFromTableRequest(Flow flow) throws InterruptedException, ExecutionException{ - final GetFlowStatisticsFromFlowTableInputBuilder input = - new GetFlowStatisticsFromFlowTableInputBuilder(flow); - - input.setNode(targetNodeRef); - - Future> response = - flowStatsService.getFlowStatisticsFromFlowTable(input.build()); - - recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_FLOW); - } - - synchronized void sendGroupDescriptionRequest() throws InterruptedException, ExecutionException{ - final GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder(); - - input.setNode(targetNodeRef); - - Future> response = - groupStatsService.getGroupDescription(input.build()); - - recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.GROUP_DESC); - } - - synchronized void sendMeterConfigStatisticsRequest() throws InterruptedException, ExecutionException{ - - GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder(); - - input.setNode(targetNodeRef); - - Future> response = - meterStatsService.getAllMeterConfigStatistics(input.build()); - - recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.METER_CONFIG); - } - - synchronized void sendQueueStatsFromGivenNodeConnector(NodeConnectorId nodeConnectorId, QueueId queueId) throws InterruptedException, ExecutionException { - GetQueueStatisticsFromGivenPortInputBuilder input = new GetQueueStatisticsFromGivenPortInputBuilder(); - - input.setNode(targetNodeRef); - input.setNodeConnectorId(nodeConnectorId); - input.setQueueId(queueId); - Future> response = - queueStatsService.getQueueStatisticsFromGivenPort(input.build()); - - recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_QUEUE_STATS);; - } - - private void sendAllMeterStatisticsRequest() throws InterruptedException, ExecutionException{ - - GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder(); - - input.setNode(targetNodeRef); - - Future> response = - meterStatsService.getAllMeterStatistics(input.build()); - - recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_METER); - } - - private void sendAllFlowsStatsFromAllTablesRequest() throws InterruptedException, ExecutionException{ - final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder(); - input.setNode(targetNodeRef); - - Future> response = flowStatsService.getAllFlowsStatisticsFromAllFlowTables(input.build()); + synchronized void sendFlowStatsFromTableRequest(Flow flow) { + if (flowStats == null) { + logger.debug("No Flow statistics service, not sending a request"); + return; + } - recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_FLOW); + registerTransaction(flowStats.requestFlow(flow), StatsRequestType.ALL_FLOW); } - private void sendAggregateFlowsStatsFromAllTablesRequest() throws InterruptedException, ExecutionException{ - final Collection tables = getKnownTables(); - logger.debug("Node {} supports {} table(s)", targetNodeKey, tables.size()); - - for (TableKey key : tables) { - sendAggregateFlowsStatsFromTableRequest(key.getId().shortValue()); + synchronized void sendGroupDescriptionRequest() { + if (groupStats == null) { + logger.debug("No Group Descriptor statistics service, not sending a request"); + return; } - } - private void sendAggregateFlowsStatsFromTableRequest(Short tableId) throws InterruptedException, ExecutionException{ - logger.debug("Send aggregate stats request for flow table {} to node {}",tableId, targetNodeKey); - GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input = - new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder(); - - input.setNode(new NodeRef(InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).toInstance())); - input.setTableId(new org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId(tableId)); - Future> response = - flowStatsService.getAggregateFlowStatisticsFromFlowTableForAllFlows(input.build()); - - recordExpectedTableTransaction(response.get().getResult().getTransactionId(), tableId); + registerTransaction(groupDescStats.request(), StatsRequestType.GROUP_DESC); } - private void sendAllQueueStatsFromAllNodeConnector() throws InterruptedException, ExecutionException { - GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder(); - - input.setNode(targetNodeRef); - - Future> response = - queueStatsService.getAllQueuesStatisticsFromAllPorts(input.build()); + synchronized void sendMeterConfigStatisticsRequest() { + if (meterConfigStats == null) { + logger.debug("No Meter Config statistics service, not sending a request"); + return; + } - recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_QUEUE_STATS); + registerTransaction(meterConfigStats.request(), StatsRequestType.METER_CONFIG); } - private void sendAllNodeConnectorsStatisticsRequest() throws InterruptedException, ExecutionException{ - final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder(); - - input.setNode(targetNodeRef); + synchronized void sendQueueStatsFromGivenNodeConnector(NodeConnectorId nodeConnectorId, QueueId queueId) { + if (queueStats == null) { + logger.debug("No Queue statistics service, not sending a request"); + return; + } - Future> response = - portStatsService.getAllNodeConnectorsStatistics(input.build()); - recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_PORT); + registerTransaction(queueStats.request(nodeConnectorId, queueId), StatsRequestType.ALL_QUEUE_STATS); } - private void sendAllGroupStatisticsRequest() throws InterruptedException, ExecutionException{ - final GetAllGroupStatisticsInputBuilder input = new GetAllGroupStatisticsInputBuilder(); - input.setNode(targetNodeRef); - - Future> response = - groupStatsService.getAllGroupStatistics(input.build()); + private void registerTransaction(final ListenableFuture future, final StatsRequestType type) { + Futures.addCallback(future, new FutureCallback() { + @Override + public void onSuccess(TransactionId result) { + msgManager.recordExpectedTransaction(result, type); + logger.debug("Transaction {} for node {} sent successfully", result, targetNodeKey); + } - recordExpectedTransaction(response.get().getResult().getTransactionId(), StatsRequestType.ALL_GROUP); + @Override + public void onFailure(Throwable t) { + logger.warn("Failed to send statistics request for node {}", targetNodeKey, t); + } + }); } - private void recordExpectedTransaction(TransactionId transactionId, StatsRequestType reqType) { - msgManager.recordExpectedTransaction(transactionId, reqType); - } + private void registerTableTransaction(final ListenableFuture future, final Short id) { + Futures.addCallback(future, new FutureCallback() { + @Override + public void onSuccess(TransactionId result) { + msgManager.recordExpectedTableTransaction(result, StatsRequestType.AGGR_FLOW, id); + logger.debug("Transaction {} for node {} table {} sent successfully", result, targetNodeKey, id); + } - private void recordExpectedTableTransaction(TransactionId transactionId, Short tableId) { - msgManager.recordExpectedTableTransaction(transactionId, StatsRequestType.AGGR_FLOW, tableId); + @Override + public void onFailure(Throwable t) { + logger.warn("Failed to send table statistics request for node {} table {}", targetNodeKey, id, t); + } + }); } } diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java index c2bde6ae60..a9db771fa6 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java @@ -8,28 +8,36 @@ package org.opendaylight.controller.md.statistics.manager; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; -import org.opendaylight.controller.sal.binding.api.data.DataProviderService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData; import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService; import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatisticsBuilder; 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; import org.slf4j.LoggerFactory; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ListenableFuture; + final class QueueStatsTracker extends AbstractStatsTracker { private static final Logger logger = LoggerFactory.getLogger(QueueStatsTracker.class); + private final OpendaylightQueueStatisticsService queueStatsService; - QueueStatsTracker(InstanceIdentifier nodeIdentifier, - DataProviderService dps, long lifetimeNanos) { - super(nodeIdentifier, dps, lifetimeNanos); + QueueStatsTracker(OpendaylightQueueStatisticsService queueStatsService, final FlowCapableContext context, long lifetimeNanos) { + super(context, lifetimeNanos); + this.queueStatsService = Preconditions.checkNotNull(queueStatsService); } @Override @@ -72,4 +80,21 @@ final class QueueStatsTracker extends AbstractStatsTracker request() { + GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder(); + input.setNode(getNodeRef()); + + return requestHelper(queueStatsService.getAllQueuesStatisticsFromAllPorts(input.build())); + } + + public ListenableFuture request(NodeConnectorId nodeConnectorId, QueueId queueId) { + GetQueueStatisticsFromGivenPortInputBuilder input = new GetQueueStatisticsFromGivenPortInputBuilder(); + + input.setNode(getNodeRef()); + input.setNodeConnectorId(nodeConnectorId); + input.setQueueId(queueId); + + return requestHelper(queueStatsService.getQueueStatisticsFromGivenPort(input.build())); + } } diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java index 9ab1e9c5d1..842cdaf292 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java @@ -12,7 +12,6 @@ import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import org.opendaylight.controller.sal.binding.api.NotificationProviderService; @@ -178,28 +177,28 @@ public class StatisticsProvider implements AutoCloseable { return dps.beginTransaction(); } - public void sendFlowStatsFromTableRequest(NodeKey node, Flow flow) throws InterruptedException, ExecutionException { + public void sendFlowStatsFromTableRequest(NodeKey node, Flow flow) { final NodeStatisticsHandler h = getStatisticsHandler(node.getId()); if (h != null) { h.sendFlowStatsFromTableRequest(flow); } } - public void sendGroupDescriptionRequest(NodeKey node) throws InterruptedException, ExecutionException{ + public void sendGroupDescriptionRequest(NodeKey node) { final NodeStatisticsHandler h = getStatisticsHandler(node.getId()); if (h != null) { h.sendGroupDescriptionRequest(); } } - public void sendMeterConfigStatisticsRequest(NodeKey node) throws InterruptedException, ExecutionException { + public void sendMeterConfigStatisticsRequest(NodeKey node) { final NodeStatisticsHandler h = getStatisticsHandler(node.getId()); if (h != null) { h.sendMeterConfigStatisticsRequest(); } } - public void sendQueueStatsFromGivenNodeConnector(NodeKey node,NodeConnectorId nodeConnectorId, QueueId queueId) throws InterruptedException, ExecutionException { + public void sendQueueStatsFromGivenNodeConnector(NodeKey node,NodeConnectorId nodeConnectorId, QueueId queueId) { final NodeStatisticsHandler h = getStatisticsHandler(node.getId()); if (h != null) { h.sendQueueStatsFromGivenNodeConnector(nodeConnectorId, queueId); diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateHandler.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateHandler.java index 0459bc8512..e22bd0874f 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateHandler.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateHandler.java @@ -9,7 +9,6 @@ package org.opendaylight.controller.md.statistics.manager; import java.util.Map; import java.util.Set; -import java.util.concurrent.ExecutionException; import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent; import org.opendaylight.controller.sal.binding.api.data.DataChangeListener; @@ -30,8 +29,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111. import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Following are two main responsibilities of the class @@ -45,8 +42,6 @@ import org.slf4j.LoggerFactory; * */ public class StatisticsUpdateHandler implements DataChangeListener { - - private static final Logger suhLogger = LoggerFactory.getLogger(StatisticsUpdateHandler.class); private final StatisticsProvider statisticsManager; public StatisticsUpdateHandler(final StatisticsProvider manager){ @@ -62,36 +57,19 @@ public class StatisticsUpdateHandler implements DataChangeListener { NodeKey nodeII = dataObjectInstance.firstKeyOf(Node.class, NodeKey.class); if(dataObject instanceof Flow){ Flow flow = (Flow) dataObject; - try { - this.statisticsManager.sendFlowStatsFromTableRequest(nodeII, flow); - } catch (InterruptedException | ExecutionException e) { - suhLogger.warn("Following exception occured while sending flow statistics request newly added flow: {}", e); - } + this.statisticsManager.sendFlowStatsFromTableRequest(nodeII, flow); } if(dataObject instanceof Meter){ - try { - this.statisticsManager.sendMeterConfigStatisticsRequest(nodeII); - } catch (InterruptedException | ExecutionException e) { - suhLogger.warn("Following exception occured while sending meter statistics request for newly added meter: {}", e); - } + this.statisticsManager.sendMeterConfigStatisticsRequest(nodeII); } if(dataObject instanceof Group){ - try { - this.statisticsManager.sendGroupDescriptionRequest(nodeII); - } catch (InterruptedException | ExecutionException e) { - suhLogger.warn("Following exception occured while sending group description request for newly added group: {}", e); - } + this.statisticsManager.sendGroupDescriptionRequest(nodeII); } if(dataObject instanceof Queue){ Queue queue = (Queue) dataObject; InstanceIdentifier nodeConnectorII = dataObjectInstance.firstIdentifierOf(NodeConnector.class); NodeConnectorKey nodeConnectorKey = InstanceIdentifier.keyOf(nodeConnectorII); - try { - this.statisticsManager.sendQueueStatsFromGivenNodeConnector(nodeII, - nodeConnectorKey.getId(), queue.getQueueId()); - } catch (InterruptedException | ExecutionException e) { - suhLogger.warn("Following exception occured while sending queue statistics request for newly added group: {}", e); - } + this.statisticsManager.sendQueueStatsFromGivenNodeConnector(nodeII, nodeConnectorKey.getId(), queue.getQueueId()); } } -- 2.36.6