Move statistics request functions into trackers 23/5323/5
authorRobert Varga <rovarga@cisco.com>
Fri, 14 Feb 2014 19:24:05 +0000 (20:24 +0100)
committerGerrit Code Review <gerrit@opendaylight.org>
Sat, 15 Feb 2014 02:10:31 +0000 (02:10 +0000)
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 <rovarga@cisco.com>
14 files changed:
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowCapableContext.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupDescStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/GroupStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterConfigStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MeterStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MultipartMessageManager.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeConnectorStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateHandler.java

index aa7720cf106844be6e440d0493b7bffbb24f244e..03ed6cb1f1420edcd3c502d26fccf37a56fd3fab 100644 (file)
@@ -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<I, K> {
+    private static final Function<RpcResult<? extends TransactionAware>, TransactionId> FUNCTION =
+            new Function<RpcResult<? extends TransactionAware>, TransactionId>() {
+        @Override
+        public TransactionId apply(RpcResult<? extends TransactionAware> input) {
+            return input.getResult().getTransactionId();
+        }
+    };
+
     private final Map<K, Long> trackedItems = new HashMap<>();
-    private final InstanceIdentifier<Node> nodeIdentifier;
-    private final DataProviderService dps;
+    private final FlowCapableContext context;
     private final long lifetimeNanos;
 
-    protected AbstractStatsTracker(final InstanceIdentifier<Node> 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<Node> getNodeIdentifierBuilder() {
-        return InstanceIdentifier.builder(nodeIdentifier);
+        return InstanceIdentifier.builder(getNodeIdentifier());
+    }
+
+    protected final NodeRef getNodeRef() {
+        return context.getNodeRef();
+    }
+
+    protected final InstanceIdentifier<Node> getNodeIdentifier() {
+        return context.getNodeIdentifier();
+    }
+
+    protected static final <T extends TransactionAware> ListenableFuture<TransactionId> requestHelper(Future<RpcResult<T>> future) {
+        return Futures.transform(JdkFutureAdapters.listenInPoolThread(future), FUNCTION);
     }
 
-    final synchronized void updateStats(List<I> list) {
+    protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item);
+    protected abstract K updateSingleStat(DataModificationTransaction trans, I item);
+
+    public final synchronized void updateStats(List<I> 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<I, K> {
         trans.commit();
     }
 
-
-    final synchronized void cleanup(final DataModificationTransaction trans, long now) {
+    public final synchronized void cleanup(final DataModificationTransaction trans, long now) {
         for (Iterator<Entry<K, Long>> it = trackedItems.entrySet().iterator();it.hasNext();){
             Entry<K, Long> e = it.next();
             if (now > e.getValue()) {
@@ -58,7 +86,4 @@ abstract class AbstractStatsTracker<I, K> {
             }
         }
     }
-
-    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 (file)
index 0000000..9893c28
--- /dev/null
@@ -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<Node> getNodeIdentifier();
+    NodeRef getNodeRef();
+    DataModificationTransaction startDataModification();
+}
index e1854375a5aa889ab52ae9d441ccabd46b66c9a5..abbc94ee2b40b9bb9a5069c0d015363e9e06726b 100644 (file)
@@ -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<FlowAndStatisticsMapList, FlowStatsEntry> {
     private static final Logger logger = LoggerFactory.getLogger(FlowStatsTracker.class);
+    private final OpendaylightFlowStatisticsService flowStatsService;
     private int unaccountedFlowsCounter = 1;
 
-    FlowStatsTracker(InstanceIdentifier<Node> 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<FlowAndStatisticsMapLi
         trans.putOperationalData(flowRef, flowBuilder.build());
         return flowStatsEntry;
     }
+
+    public ListenableFuture<TransactionId> requestAllFlowsAllTables() {
+        final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
+        input.setNode(getNodeRef());
+
+        return requestHelper(flowStatsService.getAllFlowsStatisticsFromAllFlowTables(input.build()));
+    }
+
+    public ListenableFuture<TransactionId> 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<TransactionId> requestFlow(final Flow flow) {
+        final GetFlowStatisticsFromFlowTableInputBuilder input =
+                new GetFlowStatisticsFromFlowTableInputBuilder(flow);
+        input.setNode(getNodeRef());
+
+        return requestHelper(flowStatsService.getFlowStatisticsFromFlowTable(input.build()));
+    }
 }
index 2544d5580571cb63a2e1e613a772cb4a6d934de1..4136b3d0e4e466dab95ce1e0c91c319c86b49e45 100644 (file)
@@ -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<FlowTableAndStatisticsMap, FlowTableAndStatisticsMap> {
     private final Set<TableKey> privateTables = new ConcurrentSkipListSet<>();
     private final Set<TableKey> tables = Collections.unmodifiableSet(privateTables);
+    private final OpendaylightFlowTableStatisticsService flowTableStatsService;
 
-    FlowTableStatsTracker(InstanceIdentifier<Node> 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<TableKey> getTables() {
@@ -58,4 +64,11 @@ final class FlowTableStatsTracker extends AbstractStatsTracker<FlowTableAndStati
         trans.putOperationalData(tableRef, tableBuilder.build());
         return item;
     }
+
+    public ListenableFuture<TransactionId> request() {
+        final GetFlowTablesStatisticsInputBuilder input = new GetFlowTablesStatisticsInputBuilder();
+        input.setNode(getNodeRef());
+
+        return requestHelper(flowTableStatsService.getFlowTablesStatistics(input.build()));
+    }
 }
index 928bf4ea55741df9b46d418670c807fdcca98dc9..90702e4818fad9504c2f73af6ab14f43154f4acc 100644 (file)
@@ -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<GroupDescStats, GroupDescStats> {
-    public GroupDescStatsTracker(final InstanceIdentifier<Node> 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<GroupDescStats, G
                 .child(Group.class, new GroupKey(item.getGroupId())).augmentation(NodeGroupDescStats.class).build();
         trans.removeOperationalData(groupRef);
     }
+
+    public ListenableFuture<TransactionId> request() {
+        final GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder();
+        input.setNode(getNodeRef());
+
+        return requestHelper(groupStatsService.getGroupDescription(input.build()));
+    }
 }
index a5498f5a306cd60c78446e1ee0c278755dcfde14..40f526e13ce9d132dbf2555cd8ae4b987194461d 100644 (file)
@@ -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<GroupStats, GroupStats> {
+    private final OpendaylightGroupStatisticsService groupStatsService;
 
-    GroupStatsTracker(InstanceIdentifier<Node> 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<GroupStats, GroupStat
         return item;
     }
 
+    public ListenableFuture<TransactionId> request() {
+        final GetAllGroupStatisticsInputBuilder input = new GetAllGroupStatisticsInputBuilder();
+        input.setNode(getNodeRef());
+
+        return requestHelper(groupStatsService.getAllGroupStatistics(input.build()));
+    }
 }
index dcb0b403dcf5f3082aa2e3b863d514052a380368..150728db16e95e59dc021d97bcc1b60af67cc209 100644 (file)
@@ -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<MeterConfigStats, MeterConfigStats> {
-    protected MeterConfigStatsTracker(InstanceIdentifier<Node> 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<MeterConfigStat
         return item;
     }
 
+    public ListenableFuture<TransactionId> request() {
+        GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder();
+        input.setNode(getNodeRef());
+
+        return requestHelper(meterStatsService.getAllMeterConfigStatistics(input.build()));
+    }
 }
index 381db8a39ffa3a464b32049a2a5aa67d20fabc39..807e82c9efd24772a19b1727c832c2c3a2755cf9 100644 (file)
@@ -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<MeterStats, MeterStats> {
+    private final OpendaylightMeterStatisticsService meterStatsService;
 
-    MeterStatsTracker(InstanceIdentifier<Node> 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<MeterStats, MeterStat
         trans.putOperationalData(meterRef, meterBuilder.build());
         return item;
     }
+
+    public ListenableFuture<TransactionId> request() {
+        GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder();
+        input.setNode(getNodeRef());
+
+        return requestHelper(meterStatsService.getAllMeterStatistics(input.build()));
+    }
 }
index 0ce551a17c5f4f0ab94577f863abc4f09d2339ac..e52a718a4e26c389af1c990b874fa8e81468682e 100644 (file)
@@ -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<TxIdEntry,Long> txIdToRequestTypeMap = new HashMap<>();
+    private final Map<TxIdEntry,Long> 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<TxIdEntry,Short> txIdTotableIdMap = new HashMap<>();
+    private final Map<TxIdEntry,Short> 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<TxIdEntry> it = txIdToRequestTypeMap.keySet().iterator();it.hasNext();){
index 2a8b180a51c1b62cbafd1395ebcf2c6e80acddee..83d9da13f05c83eb7a3971e5152b0116ba78f7ac 100644 (file)
@@ -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<NodeConnectorStatisticsAndPortNumberMap, NodeConnectorStatisticsAndPortNumberMap> {
     private static final Logger logger = LoggerFactory.getLogger(NodeConnectorStatsTracker.class);
+    private final OpendaylightPortStatisticsService portStatsService;
 
-    NodeConnectorStatsTracker(InstanceIdentifier<Node> 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<NodeConnector
 
         return item;
     }
+
+    public ListenableFuture<TransactionId> request() {
+        final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder();
+        input.setNode(getNodeRef());
+
+        return requestHelper(portStatsService.getAllNodeConnectorsStatistics(input.build()));
+    }
 }
index 5d5d17230fda1d9efa458deddc3d5fbb44626c86..413c01b1bc132a625b454b9c5e9bd0193d849e4b 100644 (file)
@@ -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<Node> 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<TableKey> getKnownTables() {
-        return flowTableStats.getTables();
-    }
-
-    public InstanceIdentifier<Node> getTargetNodeIdentifier() {
+    @Override
+    public InstanceIdentifier<Node> 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<GroupDescStats> 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<RpcResult<GetFlowTablesStatisticsOutput>> 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<TableKey> 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<RpcResult<GetFlowStatisticsFromFlowTableOutput>> 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<RpcResult<GetGroupDescriptionOutput>> 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<RpcResult<GetAllMeterConfigStatisticsOutput>> 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<RpcResult<GetQueueStatisticsFromGivenPortOutput>> 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<RpcResult<GetAllMeterStatisticsOutput>> 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<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> 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<TableKey> 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<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> 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<RpcResult<GetAllQueuesStatisticsFromAllPortsOutput>> 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<RpcResult<GetAllNodeConnectorsStatisticsOutput>> 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<RpcResult<GetAllGroupStatisticsOutput>> response =
-                groupStatsService.getAllGroupStatistics(input.build());
+    private void registerTransaction(final ListenableFuture<TransactionId> future, final StatsRequestType type) {
+        Futures.addCallback(future, new FutureCallback<TransactionId>() {
+            @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<TransactionId> future, final Short id) {
+        Futures.addCallback(future, new FutureCallback<TransactionId>() {
+            @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);
+            }
+        });
     }
 }
index c2bde6ae6034d98bb8f2c93a371c442b31dd5c4f..a9db771fa610c856a7bd85fa617e1d574a607f4d 100644 (file)
@@ -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<QueueIdAndStatisticsMap, QueueStatsEntry> {
     private static final Logger logger = LoggerFactory.getLogger(QueueStatsTracker.class);
+    private final OpendaylightQueueStatisticsService queueStatsService;
 
-    QueueStatsTracker(InstanceIdentifier<Node> 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<QueueIdAndStatisticsM
         trans.putOperationalData(queueRef, queueBuilder.build());
         return queueEntry;
     }
+
+    public ListenableFuture<TransactionId> request() {
+        GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder();
+        input.setNode(getNodeRef());
+
+        return requestHelper(queueStatsService.getAllQueuesStatisticsFromAllPorts(input.build()));
+    }
+
+    public ListenableFuture<TransactionId> request(NodeConnectorId nodeConnectorId, QueueId queueId) {
+        GetQueueStatisticsFromGivenPortInputBuilder input = new GetQueueStatisticsFromGivenPortInputBuilder();
+
+        input.setNode(getNodeRef());
+        input.setNodeConnectorId(nodeConnectorId);
+        input.setQueueId(queueId);
+
+        return requestHelper(queueStatsService.getQueueStatisticsFromGivenPort(input.build()));
+    }
 }
index 9ab1e9c5d1a453a4fc24746a96d2862e5db620a9..842cdaf29273de408c01ab4257a7c6d6697e3355 100644 (file)
@@ -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);
index 0459bc851200756dba7c18bb199d49fafd340889..e22bd0874fb2e94db636b88c482682e32655c41e 100644 (file)
@@ -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<NodeConnector> 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());
             }
         }