Move queue/meter/flow listeners into their trackers 35/5335/3
authorRobert Varga <rovarga@cisco.com>
Fri, 14 Feb 2014 19:24:40 +0000 (20:24 +0100)
committerGerrit Code Review <gerrit@opendaylight.org>
Sat, 15 Feb 2014 02:10:38 +0000 (02:10 +0000)
This completes the move of triggers under a per-node registration. With
this structure we should have a complete control of what should be going
on for a switch.

Change-Id: Ia35c925947e044ff826c1f2560c040fe696aaed0
Signed-off-by: Robert Varga <rovarga@cisco.com>
15 files changed:
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractListeningStatsTracker.java [new file with mode: 0644]
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
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/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/StatisticsManagerActivator.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 [deleted file]

diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractListeningStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractListeningStatsTracker.java
new file mode 100644 (file)
index 0000000..4a58579
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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.DataBrokerService;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+
+abstract class AbstractListeningStatsTracker<I, K> extends AbstractStatsTracker<I, K> implements AutoCloseable, DataChangeListener {
+    private static final Logger logger = LoggerFactory.getLogger(AbstractListeningStatsTracker.class);
+    private ListenerRegistration<?> reg;
+
+    protected AbstractListeningStatsTracker(FlowCapableContext context, long lifetimeNanos) {
+        super(context, lifetimeNanos);
+    }
+
+    protected abstract InstanceIdentifier<?> listenPath();
+    protected abstract String statName();
+
+    public void start(final DataBrokerService dbs) {
+        Preconditions.checkState(reg == null);
+
+        reg = dbs.registerDataChangeListener(listenPath(), this);
+        logger.debug("{} Statistics tracker for node {} started", statName(), getNodeIdentifier());
+    }
+
+    @Override
+    public final void close() {
+        if (reg != null) {
+            try {
+                reg.close();
+            } catch (Exception e) {
+                logger.warn("Failed to stop {} Statistics tracker for node {}", statName(), getNodeIdentifier(), e);
+            }
+            reg = null;
+        }
+    }
+}
index 03ed6cb1f1420edcd3c502d26fccf37a56fd3fab..81fa7c87917e98af33da999da7b17949592a8fcc 100644 (file)
@@ -14,6 +14,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.concurrent.Future;
 
 import java.util.Map.Entry;
 import java.util.concurrent.Future;
 
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 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.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
@@ -27,7 +28,6 @@ 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.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 =
 
 abstract class AbstractStatsTracker<I, K> {
     private static final Function<RpcResult<? extends TransactionAware>, TransactionId> FUNCTION =
@@ -59,8 +59,12 @@ abstract class AbstractStatsTracker<I, K> {
         return context.getNodeIdentifier();
     }
 
         return context.getNodeIdentifier();
     }
 
-    protected static final <T extends TransactionAware> ListenableFuture<TransactionId> requestHelper(Future<RpcResult<T>> future) {
-        return Futures.transform(JdkFutureAdapters.listenInPoolThread(future), FUNCTION);
+    protected final <T extends TransactionAware> void requestHelper(Future<RpcResult<T>> future, StatsRequestType type) {
+        context.registerTransaction(Futures.transform(JdkFutureAdapters.listenInPoolThread(future), FUNCTION), type);
+    }
+
+    protected final DataModificationTransaction startTransaction() {
+        return context.startDataModification();
     }
 
     protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item);
     }
 
     protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item);
@@ -68,7 +72,7 @@ abstract class AbstractStatsTracker<I, K> {
 
     public final synchronized void updateStats(List<I> list) {
         final Long expiryTime = System.nanoTime() + lifetimeNanos;
 
     public final synchronized void updateStats(List<I> list) {
         final Long expiryTime = System.nanoTime() + lifetimeNanos;
-        final DataModificationTransaction trans = context.startDataModification();
+        final DataModificationTransaction trans = startTransaction();
 
         for (final I item : list) {
             trackedItems.put(updateSingleStat(trans, item), expiryTime);
 
         for (final I item : list) {
             trackedItems.put(updateSingleStat(trans, item), expiryTime);
index 9893c28f6cdfb54ea9b1199d688b7e2b0c083711..34ff87f4a4cf3b4d7e513fb92c5b9c4bdb45dafc 100644 (file)
@@ -7,11 +7,15 @@
  */
 package org.opendaylight.controller.md.statistics.manager;
 
  */
 package org.opendaylight.controller.md.statistics.manager;
 
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+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.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 com.google.common.util.concurrent.ListenableFuture;
+
 /**
  * Interface exposed to AbstractStatsTracker by its parent NodeStatisticsHandler.
  * While we could simply exist without this interface, its purpose is to document
 /**
  * Interface exposed to AbstractStatsTracker by its parent NodeStatisticsHandler.
  * While we could simply exist without this interface, its purpose is to document
@@ -21,4 +25,6 @@ interface FlowCapableContext {
     InstanceIdentifier<Node> getNodeIdentifier();
     NodeRef getNodeRef();
     DataModificationTransaction startDataModification();
     InstanceIdentifier<Node> getNodeIdentifier();
     NodeRef getNodeRef();
     DataModificationTransaction startDataModification();
+    void registerTransaction(ListenableFuture<TransactionId> future, StatsRequestType type);
+    void registerTableTransaction(ListenableFuture<TransactionId> future, Short tableId);
 }
 }
index abbc94ee2b40b9bb9a5069c0d015363e9e06726b..2cba58f27f851a4faf66e97ce8ac84830431646b 100644 (file)
@@ -7,6 +7,11 @@
  */
 package org.opendaylight.controller.md.statistics.manager;
 
  */
 package org.opendaylight.controller.md.statistics.manager;
 
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
@@ -24,23 +29,20 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.O
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
+import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 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> {
+final class FlowStatsTracker extends AbstractListeningStatsTracker<FlowAndStatisticsMapList, FlowStatsEntry> {
     private static final Logger logger = LoggerFactory.getLogger(FlowStatsTracker.class);
     private final OpendaylightFlowStatisticsService flowStatsService;
     private int unaccountedFlowsCounter = 1;
 
     FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, long lifetimeNanos) {
         super(context, lifetimeNanos);
     private static final Logger logger = LoggerFactory.getLogger(FlowStatsTracker.class);
     private final OpendaylightFlowStatisticsService flowStatsService;
     private int unaccountedFlowsCounter = 1;
 
     FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, long lifetimeNanos) {
         super(context, lifetimeNanos);
-        this.flowStatsService = Preconditions.checkNotNull(flowStatsService);
+        this.flowStatsService = flowStatsService;
     }
 
     @Override
     }
 
     @Override
@@ -192,27 +194,80 @@ final class FlowStatsTracker extends AbstractStatsTracker<FlowAndStatisticsMapLi
         return flowStatsEntry;
     }
 
         return flowStatsEntry;
     }
 
-    public ListenableFuture<TransactionId> requestAllFlowsAllTables() {
-        final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
-        input.setNode(getNodeRef());
+    @Override
+    protected InstanceIdentifier<?> listenPath() {
+        return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Table.class).child(Flow.class).build();
+    }
 
 
-        return requestHelper(flowStatsService.getAllFlowsStatisticsFromAllFlowTables(input.build()));
+    @Override
+    protected String statName() {
+        return "Flow";
     }
 
     }
 
-    public ListenableFuture<TransactionId> requestAggregateFlows(final TableKey key) {
-        GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input =
-                new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder();
+    public void requestAllFlowsAllTables() {
+        if (flowStatsService != null) {
+            final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
+            input.setNode(getNodeRef());
 
 
-        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()));
+            requestHelper(flowStatsService.getAllFlowsStatisticsFromAllFlowTables(input.build()), StatsRequestType.ALL_FLOW);
+        }
     }
 
     }
 
-    public ListenableFuture<TransactionId> requestFlow(final Flow flow) {
-        final GetFlowStatisticsFromFlowTableInputBuilder input =
-                new GetFlowStatisticsFromFlowTableInputBuilder(flow);
-        input.setNode(getNodeRef());
+    public void requestAggregateFlows(final TableKey key) {
+        if (flowStatsService != null) {
+            GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder input =
+                    new GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder();
+
+            input.setNode(getNodeRef());
+            input.setTableId(new org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId(key.getId()));
+            requestHelper(flowStatsService.getAggregateFlowStatisticsFromFlowTableForAllFlows(input.build()), StatsRequestType.ALL_FLOW);
+        }
+    }
+
+    public void requestFlow(final Flow flow) {
+        if (flowStatsService != null) {
+            final GetFlowStatisticsFromFlowTableInputBuilder input =
+                    new GetFlowStatisticsFromFlowTableInputBuilder(flow);
+            input.setNode(getNodeRef());
+
+            requestHelper(flowStatsService.getFlowStatisticsFromFlowTable(input.build()), StatsRequestType.ALL_FLOW);
+        }
+    }
+
+    @Override
+    public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+        for (Entry<InstanceIdentifier<?>, DataObject> e : change.getCreatedConfigurationData().entrySet()) {
+            if (Flow.class.equals(e.getKey().getTargetType())) {
+                final Flow flow = (Flow) e.getValue();
+                logger.debug("Key {} triggered request for flow {}", e.getKey(), flow);
+                requestFlow(flow);
+            } else {
+                logger.debug("Ignoring key {}", e.getKey());
+            }
+        }
+
+        final DataModificationTransaction trans = startTransaction();
+        for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
+            if (Flow.class.equals(key.getTargetType())) {
+                @SuppressWarnings("unchecked")
+                final InstanceIdentifier<Flow> flow = (InstanceIdentifier<Flow>)key;
+                final InstanceIdentifier<?> del = InstanceIdentifier.builder(flow)
+                        .augmentation(FlowStatisticsData.class).build();
+                logger.debug("Key {} triggered remove of augmentation {}", key, del);
+
+                trans.removeOperationalData(del);
+            }
+        }
+        trans.commit();
+    }
+
+    @Override
+    public void start(final DataBrokerService dbs) {
+        if (flowStatsService == null) {
+            logger.debug("No Flow Statistics service, not subscribing to flows on node {}", getNodeIdentifier());
+            return;
+        }
 
 
-        return requestHelper(flowStatsService.getFlowStatisticsFromFlowTable(input.build()));
+        super.start(dbs);
     }
 }
     }
 }
index 4136b3d0e4e466dab95ce1e0c91c319c86b49e45..20b1b84c49befe3b5a099b63261cf537ddcf234c 100644 (file)
@@ -11,6 +11,7 @@ import java.util.Collections;
 import java.util.Set;
 import java.util.concurrent.ConcurrentSkipListSet;
 
 import java.util.Set;
 import java.util.concurrent.ConcurrentSkipListSet;
 
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
@@ -23,12 +24,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev13
 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.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.flow.transaction.rev131103.TransactionId;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 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);
 final class FlowTableStatsTracker extends AbstractStatsTracker<FlowTableAndStatisticsMap, FlowTableAndStatisticsMap> {
     private final Set<TableKey> privateTables = new ConcurrentSkipListSet<>();
     private final Set<TableKey> tables = Collections.unmodifiableSet(privateTables);
@@ -36,7 +33,7 @@ final class FlowTableStatsTracker extends AbstractStatsTracker<FlowTableAndStati
 
     FlowTableStatsTracker(OpendaylightFlowTableStatisticsService flowTableStatsService, final FlowCapableContext context, long lifetimeNanos) {
         super(context, lifetimeNanos);
 
     FlowTableStatsTracker(OpendaylightFlowTableStatisticsService flowTableStatsService, final FlowCapableContext context, long lifetimeNanos) {
         super(context, lifetimeNanos);
-        this.flowTableStatsService = Preconditions.checkNotNull(flowTableStatsService);
+        this.flowTableStatsService = flowTableStatsService;
     }
 
     Set<TableKey> getTables() {
     }
 
     Set<TableKey> getTables() {
@@ -65,10 +62,12 @@ final class FlowTableStatsTracker extends AbstractStatsTracker<FlowTableAndStati
         return item;
     }
 
         return item;
     }
 
-    public ListenableFuture<TransactionId> request() {
-        final GetFlowTablesStatisticsInputBuilder input = new GetFlowTablesStatisticsInputBuilder();
-        input.setNode(getNodeRef());
+    public void request() {
+        if (flowTableStatsService != null) {
+            final GetFlowTablesStatisticsInputBuilder input = new GetFlowTablesStatisticsInputBuilder();
+            input.setNode(getNodeRef());
 
 
-        return requestHelper(flowTableStatsService.getFlowTablesStatistics(input.build()));
+            requestHelper(flowTableStatsService.getFlowTablesStatistics(input.build()), StatsRequestType.ALL_FLOW);
+        }
     }
 }
     }
 }
index 90702e4818fad9504c2f73af6ab14f43154f4acc..663269e25ff1660622fc6a979e5eee0492f890f4 100644 (file)
@@ -7,9 +7,11 @@
  */
 package org.opendaylight.controller.md.statistics.manager;
 
  */
 package org.opendaylight.controller.md.statistics.manager;
 
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.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.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;
@@ -19,17 +21,18 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group
 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.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.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 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 GroupDescStatsTracker extends AbstractStatsTracker<GroupDescStats, GroupDescStats> {
+final class GroupDescStatsTracker extends AbstractListeningStatsTracker<GroupDescStats, GroupDescStats> {
+    private static final Logger logger = LoggerFactory.getLogger(GroupDescStatsTracker.class);
     private final OpendaylightGroupStatisticsService groupStatsService;
 
     public GroupDescStatsTracker(OpendaylightGroupStatisticsService groupStatsService, final FlowCapableContext context, final long lifetimeNanos) {
         super(context, lifetimeNanos);
     private final OpendaylightGroupStatisticsService groupStatsService;
 
     public GroupDescStatsTracker(OpendaylightGroupStatisticsService groupStatsService, final FlowCapableContext context, final long lifetimeNanos) {
         super(context, lifetimeNanos);
-        this.groupStatsService = Preconditions.checkNotNull(groupStatsService);
+        this.groupStatsService = groupStatsService;
     }
 
     @Override
     }
 
     @Override
@@ -58,10 +61,57 @@ final class GroupDescStatsTracker extends AbstractStatsTracker<GroupDescStats, G
         trans.removeOperationalData(groupRef);
     }
 
         trans.removeOperationalData(groupRef);
     }
 
-    public ListenableFuture<TransactionId> request() {
-        final GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder();
-        input.setNode(getNodeRef());
+    @Override
+    protected InstanceIdentifier<?> listenPath() {
+        return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Group.class).build();
+    }
+
+    @Override
+    protected String statName() {
+        return "Group Descriptor";
+    }
+
+    public void request() {
+        if (groupStatsService != null) {
+            final GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder();
+            input.setNode(getNodeRef());
+
+            requestHelper(groupStatsService.getGroupDescription(input.build()), StatsRequestType.GROUP_DESC);
+        }
+    }
+
+    @Override
+    public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+        for (InstanceIdentifier<?> key : change.getCreatedConfigurationData().keySet()) {
+            if (Group.class.equals(key.getTargetType())) {
+                logger.debug("Key {} triggered request", key);
+                request();
+            } else {
+                logger.debug("Ignoring key {}", key);
+            }
+        }
+
+        final DataModificationTransaction trans = startTransaction();
+        for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
+            if (Group.class.equals(key.getTargetType())) {
+                @SuppressWarnings("unchecked")
+                InstanceIdentifier<Group> group = (InstanceIdentifier<Group>)key;
+                InstanceIdentifier<?> del = InstanceIdentifier.builder(group).augmentation(NodeGroupDescStats.class).toInstance();
+                logger.debug("Key {} triggered remove of augmentation {}", key, del);
+
+                trans.removeOperationalData(del);
+            }
+        }
+        trans.commit();
+    }
+
+    @Override
+    public void start(final DataBrokerService dbs) {
+        if (groupStatsService == null) {
+            logger.debug("No Group Statistics service, not subscribing to groups on node {}", getNodeIdentifier());
+            return;
+        }
 
 
-        return requestHelper(groupStatsService.getGroupDescription(input.build()));
+        super.start(dbs);
     }
 }
     }
 }
index 40f526e13ce9d132dbf2555cd8ae4b987194461d..e9488abc1e10d0d30cf48932af7466ce518a0e18 100644 (file)
@@ -7,9 +7,11 @@
  */
 package org.opendaylight.controller.md.statistics.manager;
 
  */
 package org.opendaylight.controller.md.statistics.manager;
 
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.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.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;
@@ -19,12 +21,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group
 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.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.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 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.base.Preconditions;
-import com.google.common.util.concurrent.ListenableFuture;
 
 
-final class GroupStatsTracker extends AbstractStatsTracker<GroupStats, GroupStats> {
+final class GroupStatsTracker extends AbstractListeningStatsTracker<GroupStats, GroupStats> {
+    private static final Logger logger = LoggerFactory.getLogger(GroupStatsTracker.class);
     private final OpendaylightGroupStatisticsService groupStatsService;
 
     GroupStatsTracker(OpendaylightGroupStatisticsService groupStatsService, FlowCapableContext context, long lifetimeNanos) {
     private final OpendaylightGroupStatisticsService groupStatsService;
 
     GroupStatsTracker(OpendaylightGroupStatisticsService groupStatsService, FlowCapableContext context, long lifetimeNanos) {
@@ -58,10 +63,46 @@ final class GroupStatsTracker extends AbstractStatsTracker<GroupStats, GroupStat
         return item;
     }
 
         return item;
     }
 
-    public ListenableFuture<TransactionId> request() {
+    @Override
+    protected InstanceIdentifier<?> listenPath() {
+        return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Group.class).build();
+    }
+
+    @Override
+    protected String statName() {
+        return "Group";
+    }
+
+    public void request() {
         final GetAllGroupStatisticsInputBuilder input = new GetAllGroupStatisticsInputBuilder();
         input.setNode(getNodeRef());
 
         final GetAllGroupStatisticsInputBuilder input = new GetAllGroupStatisticsInputBuilder();
         input.setNode(getNodeRef());
 
-        return requestHelper(groupStatsService.getAllGroupStatistics(input.build()));
+        requestHelper(groupStatsService.getAllGroupStatistics(input.build()), StatsRequestType.ALL_GROUP);
+    }
+
+    @Override
+    public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+        final DataModificationTransaction trans = startTransaction();
+        for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
+            if (Group.class.equals(key.getTargetType())) {
+                @SuppressWarnings("unchecked")
+                InstanceIdentifier<Group> group = (InstanceIdentifier<Group>)key;
+                InstanceIdentifier<?> del = InstanceIdentifier.builder(group).augmentation(NodeGroupStatistics.class).toInstance();
+                logger.debug("Key {} triggered remove of augmentation {}", key, del);
+
+                trans.removeOperationalData(del);
+            }
+        }
+        trans.commit();
+    }
+
+    @Override
+    public void start(final DataBrokerService dbs) {
+        if (groupStatsService == null) {
+            logger.debug("No Group Statistics service, not subscribing to groups on node {}", getNodeIdentifier());
+            return;
+        }
+
+        super.start(dbs);
     }
 }
     }
 }
index 150728db16e95e59dc021d97bcc1b60af67cc209..a32fc220ecebb8e099ba82ab951f7a5d65678b9b 100644 (file)
@@ -7,29 +7,32 @@
  */
 package org.opendaylight.controller.md.statistics.manager;
 
  */
 package org.opendaylight.controller.md.statistics.manager;
 
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.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.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.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.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.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.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 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 MeterConfigStatsTracker extends AbstractStatsTracker<MeterConfigStats, MeterConfigStats> {
+final class MeterConfigStatsTracker extends AbstractListeningStatsTracker<MeterConfigStats, MeterConfigStats> {
+    private static final Logger logger = LoggerFactory.getLogger(MeterConfigStatsTracker.class);
     private final OpendaylightMeterStatisticsService meterStatsService;
 
     protected MeterConfigStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context, long lifetimeNanos) {
         super(context, lifetimeNanos);
     private final OpendaylightMeterStatisticsService meterStatsService;
 
     protected MeterConfigStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context, long lifetimeNanos) {
         super(context, lifetimeNanos);
-        this.meterStatsService = Preconditions.checkNotNull(meterStatsService);
+        this.meterStatsService = meterStatsService;
     }
 
     @Override
     }
 
     @Override
@@ -60,10 +63,50 @@ final class MeterConfigStatsTracker extends AbstractStatsTracker<MeterConfigStat
         return item;
     }
 
         return item;
     }
 
-    public ListenableFuture<TransactionId> request() {
-        GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder();
-        input.setNode(getNodeRef());
+    public void request() {
+        if (meterStatsService != null) {
+            GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder();
+            input.setNode(getNodeRef());
+
+            requestHelper(meterStatsService.getAllMeterConfigStatistics(input.build()), StatsRequestType.METER_CONFIG);
+        }
+    }
+
+    @Override
+    public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+        final DataModificationTransaction trans = startTransaction();
+
+        for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
+            if (Meter.class.equals(key.getTargetType())) {
+                @SuppressWarnings("unchecked")
+                InstanceIdentifier<Meter> meter = (InstanceIdentifier<Meter>)key;
+
+                InstanceIdentifier<?> nodeMeterStatisticsAugmentation =
+                        InstanceIdentifier.builder(meter).augmentation(NodeMeterConfigStats.class).toInstance();
+                trans.removeOperationalData(nodeMeterStatisticsAugmentation);
+            }
+        }
+
+        trans.commit();
+    }
+
+    @Override
+    protected InstanceIdentifier<?> listenPath() {
+        return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Meter.class).build();
+    }
+
+    @Override
+    protected String statName() {
+        return "Meter Config";
+    }
+
+    @Override
+    public void start(final DataBrokerService dbs) {
+        if (meterStatsService == null) {
+            logger.debug("No Meter Statistics service, not subscribing to meter on node {}", getNodeIdentifier());
+            return;
+        }
 
 
-        return requestHelper(meterStatsService.getAllMeterConfigStatistics(input.build()));
+        super.start(dbs);
     }
 }
     }
 }
index 807e82c9efd24772a19b1727c832c2c3a2755cf9..1e1ed6b91686746a959b3d605e3e47e1a9aa6e7b 100644 (file)
@@ -7,29 +7,32 @@
  */
 package org.opendaylight.controller.md.statistics.manager;
 
  */
 package org.opendaylight.controller.md.statistics.manager;
 
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.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.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.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.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.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.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 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 MeterStatsTracker extends AbstractStatsTracker<MeterStats, MeterStats> {
+final class MeterStatsTracker extends AbstractListeningStatsTracker<MeterStats, MeterStats> {
+    private static final Logger logger = LoggerFactory.getLogger(MeterStatsTracker.class);
     private final OpendaylightMeterStatisticsService meterStatsService;
 
     MeterStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context, long lifetimeNanos) {
         super(context, lifetimeNanos);
     private final OpendaylightMeterStatisticsService meterStatsService;
 
     MeterStatsTracker(OpendaylightMeterStatisticsService meterStatsService, final FlowCapableContext context, long lifetimeNanos) {
         super(context, lifetimeNanos);
-        this.meterStatsService = Preconditions.checkNotNull(meterStatsService);
+        this.meterStatsService = meterStatsService;
     }
 
     @Override
     }
 
     @Override
@@ -59,10 +62,54 @@ final class MeterStatsTracker extends AbstractStatsTracker<MeterStats, MeterStat
         return item;
     }
 
         return item;
     }
 
-    public ListenableFuture<TransactionId> request() {
-        GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder();
-        input.setNode(getNodeRef());
+    public void request() {
+        if (meterStatsService != null) {
+            GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder();
+            input.setNode(getNodeRef());
+
+            requestHelper(meterStatsService.getAllMeterStatistics(input.build()), StatsRequestType.ALL_METER);
+        }
+    }
+
+    @Override
+    public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+        for (InstanceIdentifier<?> key : change.getCreatedConfigurationData().keySet()) {
+            if (Meter.class.equals(key.getTargetType())) {
+                request();
+            }
+        }
+
+        final DataModificationTransaction trans = startTransaction();
+        for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
+            if (Meter.class.equals(key.getTargetType())) {
+                @SuppressWarnings("unchecked")
+                InstanceIdentifier<Meter> meter = (InstanceIdentifier<Meter>)key;
+
+                InstanceIdentifier<?> nodeMeterStatisticsAugmentation =
+                        InstanceIdentifier.builder(meter).augmentation(NodeMeterStatistics.class).toInstance();
+                trans.removeOperationalData(nodeMeterStatisticsAugmentation);
+            }
+        }
+        trans.commit();
+    }
+
+    @Override
+    protected InstanceIdentifier<?> listenPath() {
+        return getNodeIdentifierBuilder().augmentation(FlowCapableNode.class).child(Meter.class).build();
+    }
+
+    @Override
+    protected String statName() {
+        return "Meter";
+    }
+
+    @Override
+    public void start(final DataBrokerService dbs) {
+        if (meterStatsService == null) {
+            logger.debug("No Meter Statistics service, not subscribing to meters on node {}", getNodeIdentifier());
+            return;
+        }
 
 
-        return requestHelper(meterStatsService.getAllMeterStatistics(input.build()));
+        super.start(dbs);
     }
 }
     }
 }
index 83d9da13f05c83eb7a3971e5152b0116ba78f7ac..8ae6bbd4de1df39e4730df3044c1e56d14f240d8 100644 (file)
@@ -7,8 +7,8 @@
  */
 package org.opendaylight.controller.md.statistics.manager;
 
  */
 package org.opendaylight.controller.md.statistics.manager;
 
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-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.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;
@@ -22,16 +22,13 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 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(final OpendaylightPortStatisticsService portStatsService, final FlowCapableContext context, long lifetimeNanos) {
         super(context, lifetimeNanos);
 final class NodeConnectorStatsTracker extends AbstractStatsTracker<NodeConnectorStatisticsAndPortNumberMap, NodeConnectorStatisticsAndPortNumberMap> {
     private static final Logger logger = LoggerFactory.getLogger(NodeConnectorStatsTracker.class);
     private final OpendaylightPortStatisticsService portStatsService;
 
     NodeConnectorStatsTracker(final OpendaylightPortStatisticsService portStatsService, final FlowCapableContext context, long lifetimeNanos) {
         super(context, lifetimeNanos);
-        this.portStatsService = Preconditions.checkNotNull(portStatsService);
+        this.portStatsService = portStatsService;
     }
 
     @Override
     }
 
     @Override
@@ -77,10 +74,12 @@ final class NodeConnectorStatsTracker extends AbstractStatsTracker<NodeConnector
         return item;
     }
 
         return item;
     }
 
-    public ListenableFuture<TransactionId> request() {
-        final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder();
-        input.setNode(getNodeRef());
+    public void request() {
+        if (portStatsService != null) {
+            final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder();
+            input.setNode(getNodeRef());
 
 
-        return requestHelper(portStatsService.getAllNodeConnectorsStatistics(input.build()));
+            requestHelper(portStatsService.getAllNodeConnectorsStatistics(input.build()), StatsRequestType.ALL_PORT);
+        }
     }
 }
     }
 }
index 413c01b1bc132a625b454b9c5e9bd0193d849e4b..691b9c0b15f58a9d6a01d05e7146c8a69251e332 100644 (file)
@@ -18,7 +18,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.Fl
 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.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.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.OpendaylightFlowStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsDataBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
@@ -28,7 +27,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev13
 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.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.NodeGroupFeatures;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.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;
@@ -36,7 +34,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFeatures;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
 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.GroupFeatures;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 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.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
@@ -102,41 +99,14 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo
 
         final long lifetimeNanos = TimeUnit.MILLISECONDS.toNanos(StatisticsProvider.STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES);
 
 
         final long lifetimeNanos = TimeUnit.MILLISECONDS.toNanos(StatisticsProvider.STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES);
 
-        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;
-        }
+        flowStats = new FlowStatsTracker(flowStatsService, this, lifetimeNanos);
+        flowTableStats = new FlowTableStatsTracker(flowTableStatsService, this, lifetimeNanos);
+        groupDescStats = new GroupDescStatsTracker(groupStatsService, this, lifetimeNanos);
+        groupStats = new GroupStatsTracker(groupStatsService, this, lifetimeNanos);
+        meterConfigStats = new MeterConfigStatsTracker(meterStatsService, this, lifetimeNanos);
+        meterStats = new MeterStatsTracker(meterStatsService, this, lifetimeNanos);
+        nodeConnectorStats = new NodeConnectorStatsTracker(portStatsService, this, lifetimeNanos);
+        queueStats = new QueueStatsTracker(queueStatsService, this, lifetimeNanos);
     }
 
     public NodeKey getTargetNodeKey() {
     }
 
     public NodeKey getTargetNodeKey() {
@@ -285,88 +255,51 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo
     public synchronized void requestPeriodicStatistics() {
         logger.debug("Send requests for statistics collection to node : {}", targetNodeKey);
 
     public synchronized void requestPeriodicStatistics() {
         logger.debug("Send requests for statistics collection to node : {}", targetNodeKey);
 
-        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());
-            }
-
-            registerTransaction(flowStats.requestAllFlowsAllTables(), StatsRequestType.ALL_FLOW);
-        }
+        flowTableStats.request();
 
 
-        if (nodeConnectorStats != null) {
-            registerTransaction(nodeConnectorStats.request(), StatsRequestType.ALL_PORT);
+        // 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);
+            flowStats.requestAggregateFlows(key);
         }
 
         }
 
-        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);
-        }
+        flowStats.requestAllFlowsAllTables();
+        nodeConnectorStats.request();
+        groupStats.request();
+        groupDescStats.request();
+        meterStats.request();
+        meterConfigStats.request();
+        queueStats.request();
     }
 
     public synchronized void start() {
     }
 
     public synchronized void start() {
+        flowStats.start(dps);
+        groupDescStats.start(dps);
+        groupStats.start(dps);
+        meterConfigStats.start(dps);
+        meterStats.start(dps);
+        queueStats.start(dps);
+
         requestPeriodicStatistics();
     }
 
     @Override
     public synchronized void close() {
         requestPeriodicStatistics();
     }
 
     @Override
     public synchronized void close() {
-        // FIXME: cleanup any resources we hold (registrations, etc.)
-        logger.debug("Statistics handler for {} shut down", targetNodeKey.getId());
-    }
-
-    synchronized void sendFlowStatsFromTableRequest(Flow flow) {
-        if (flowStats == null) {
-            logger.debug("No Flow statistics service, not sending a request");
-            return;
-        }
-
-        registerTransaction(flowStats.requestFlow(flow), StatsRequestType.ALL_FLOW);
-    }
-
-    synchronized void sendGroupDescriptionRequest() {
-        if (groupStats == null) {
-            logger.debug("No Group Descriptor statistics service, not sending a request");
-            return;
-        }
-
-        registerTransaction(groupDescStats.request(), StatsRequestType.GROUP_DESC);
-    }
+        flowStats.close();
+        groupDescStats.close();
+        groupStats.close();
+        meterConfigStats.close();
+        meterStats.close();
+        queueStats.close();
 
 
-    synchronized void sendMeterConfigStatisticsRequest() {
-        if (meterConfigStats == null) {
-            logger.debug("No Meter Config statistics service, not sending a request");
-            return;
-        }
-
-        registerTransaction(meterConfigStats.request(), StatsRequestType.METER_CONFIG);
-    }
-
-    synchronized void sendQueueStatsFromGivenNodeConnector(NodeConnectorId nodeConnectorId, QueueId queueId) {
-        if (queueStats == null) {
-            logger.debug("No Queue statistics service, not sending a request");
-            return;
-        }
-
-        registerTransaction(queueStats.request(nodeConnectorId, queueId), StatsRequestType.ALL_QUEUE_STATS);
+        logger.debug("Statistics handler for {} shut down", targetNodeKey.getId());
     }
 
     }
 
-    private void registerTransaction(final ListenableFuture<TransactionId> future, final StatsRequestType type) {
+    @Override
+    public void registerTransaction(final ListenableFuture<TransactionId> future, final StatsRequestType type) {
         Futures.addCallback(future, new FutureCallback<TransactionId>() {
             @Override
             public void onSuccess(TransactionId result) {
         Futures.addCallback(future, new FutureCallback<TransactionId>() {
             @Override
             public void onSuccess(TransactionId result) {
@@ -381,7 +314,8 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo
         });
     }
 
         });
     }
 
-    private void registerTableTransaction(final ListenableFuture<TransactionId> future, final Short id) {
+    @Override
+    public void registerTableTransaction(final ListenableFuture<TransactionId> future, final Short id) {
         Futures.addCallback(future, new FutureCallback<TransactionId>() {
             @Override
             public void onSuccess(TransactionId result) {
         Futures.addCallback(future, new FutureCallback<TransactionId>() {
             @Override
             public void onSuccess(TransactionId result) {
index a9db771fa610c856a7bd85fa617e1d574a607f4d..2ea9ecc96d8a49bdc36f48f068749e74c6b00148 100644 (file)
@@ -7,9 +7,13 @@
  */
 package org.opendaylight.controller.md.statistics.manager;
 
  */
 package org.opendaylight.controller.md.statistics.manager;
 
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 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.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;
@@ -24,20 +28,18 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.
 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.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.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 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> {
+final class QueueStatsTracker extends AbstractListeningStatsTracker<QueueIdAndStatisticsMap, QueueStatsEntry> {
     private static final Logger logger = LoggerFactory.getLogger(QueueStatsTracker.class);
     private final OpendaylightQueueStatisticsService queueStatsService;
 
     QueueStatsTracker(OpendaylightQueueStatisticsService queueStatsService, final FlowCapableContext context, long lifetimeNanos) {
         super(context, lifetimeNanos);
     private static final Logger logger = LoggerFactory.getLogger(QueueStatsTracker.class);
     private final OpendaylightQueueStatisticsService queueStatsService;
 
     QueueStatsTracker(OpendaylightQueueStatisticsService queueStatsService, final FlowCapableContext context, long lifetimeNanos) {
         super(context, lifetimeNanos);
-        this.queueStatsService = Preconditions.checkNotNull(queueStatsService);
+        this.queueStatsService = queueStatsService;
     }
 
     @Override
     }
 
     @Override
@@ -81,20 +83,73 @@ final class QueueStatsTracker extends AbstractStatsTracker<QueueIdAndStatisticsM
         return queueEntry;
     }
 
         return queueEntry;
     }
 
-    public ListenableFuture<TransactionId> request() {
-        GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder();
-        input.setNode(getNodeRef());
+    public void request() {
+        if (queueStatsService != null) {
+            GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder();
+            input.setNode(getNodeRef());
+
+            requestHelper(queueStatsService.getAllQueuesStatisticsFromAllPorts(input.build()), StatsRequestType.ALL_QUEUE_STATS);
+        }
+    }
+
+    public void request(NodeConnectorId nodeConnectorId, QueueId queueId) {
+        if (queueStatsService != null) {
+            GetQueueStatisticsFromGivenPortInputBuilder input = new GetQueueStatisticsFromGivenPortInputBuilder();
+
+            input.setNode(getNodeRef());
+            input.setNodeConnectorId(nodeConnectorId);
+            input.setQueueId(queueId);
 
 
-        return requestHelper(queueStatsService.getAllQueuesStatisticsFromAllPorts(input.build()));
+            requestHelper(queueStatsService.getQueueStatisticsFromGivenPort(input.build()), StatsRequestType.ALL_QUEUE_STATS);
+        }
     }
 
     }
 
-    public ListenableFuture<TransactionId> request(NodeConnectorId nodeConnectorId, QueueId queueId) {
-        GetQueueStatisticsFromGivenPortInputBuilder input = new GetQueueStatisticsFromGivenPortInputBuilder();
+    @Override
+    public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+        for (Entry<InstanceIdentifier<?>, DataObject> e : change.getCreatedConfigurationData().entrySet()) {
+            if (Queue.class.equals(e.getKey().getTargetType())) {
+                final Queue queue = (Queue) e.getValue();
+                final NodeConnectorKey key = e.getKey().firstKeyOf(NodeConnector.class, NodeConnectorKey.class);
+                logger.debug("Key {} triggered request for connector {} queue {}", key.getId(), queue.getQueueId());
+                request(key.getId(), queue.getQueueId());
+            } else {
+                logger.debug("Ignoring key {}", e.getKey());
+            }
+        }
+
+        final DataModificationTransaction trans = startTransaction();
+        for (InstanceIdentifier<?> key : change.getRemovedConfigurationData()) {
+            if (Queue.class.equals(key.getTargetType())) {
+                @SuppressWarnings("unchecked")
+                final InstanceIdentifier<Queue> queue = (InstanceIdentifier<Queue>)key;
+                final InstanceIdentifier<?> del = InstanceIdentifier.builder(queue)
+                        .augmentation(FlowCapableNodeConnectorQueueStatisticsData.class).build();
+                logger.debug("Key {} triggered remove of augmentation {}", key, del);
+
+                trans.removeOperationalData(del);
+            }
+        }
+        trans.commit();
+    }
 
 
-        input.setNode(getNodeRef());
-        input.setNodeConnectorId(nodeConnectorId);
-        input.setQueueId(queueId);
+    @Override
+    protected InstanceIdentifier<?> listenPath() {
+        return getNodeIdentifierBuilder().child(NodeConnector.class)
+                .augmentation(FlowCapableNodeConnector.class).child(Queue.class).build();
+    }
+
+    @Override
+    protected String statName() {
+        return "Queue";
+    }
+
+    @Override
+    public void start(final DataBrokerService dbs) {
+        if (queueStatsService == null) {
+            logger.debug("No Queue Statistics service, not subscribing to queues on node {}", getNodeIdentifier());
+            return;
+        }
 
 
-        return requestHelper(queueStatsService.getQueueStatisticsFromGivenPort(input.build()));
+        super.start(dbs);
     }
 }
     }
 }
index b59482e96b0feb8f75890b5d51d185cb459f5ef6..5bcbef119a8c332442d405681dd018dc1368c9c7 100644 (file)
@@ -11,7 +11,6 @@ package org.opendaylight.controller.md.statistics.manager;
 import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.osgi.framework.BundleContext;
 
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.osgi.framework.BundleContext;
 
@@ -20,12 +19,11 @@ public class StatisticsManagerActivator extends AbstractBindingAwareProvider {
 
     @Override
     public void onSessionInitiated(ProviderContext session) {
 
     @Override
     public void onSessionInitiated(ProviderContext session) {
-        final DataBrokerService dbs = session.getSALService(DataBrokerService.class);
         final DataProviderService dps = session.getSALService(DataProviderService.class);
         final NotificationProviderService nps = session.getSALService(NotificationProviderService.class);
 
         statsProvider = new StatisticsProvider(dps);
         final DataProviderService dps = session.getSALService(DataProviderService.class);
         final NotificationProviderService nps = session.getSALService(NotificationProviderService.class);
 
         statsProvider = new StatisticsProvider(dps);
-        statsProvider.start(dbs, nps, session);
+        statsProvider.start(nps, session);
     }
 
     @Override
     }
 
     @Override
index 842cdaf29273de408c01ab4257a7c6d6697e3355..8ffa5d673269f06954c70cffd483d5fa893e540d 100644 (file)
@@ -16,25 +16,14 @@ import java.util.concurrent.TimeUnit;
 
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
 
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
 import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
-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.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.FlowCapableNodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-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.table.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
@@ -42,7 +31,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.O
 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.slf4j.Logger;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.slf4j.Logger;
@@ -83,8 +71,6 @@ public class StatisticsProvider implements AutoCloseable {
 
     private OpendaylightQueueStatisticsService queueStatsService;
 
 
     private OpendaylightQueueStatisticsService queueStatsService;
 
-    private StatisticsUpdateHandler statsUpdateHandler;
-
     public StatisticsProvider(final DataProviderService dataService) {
         this.dps = Preconditions.checkNotNull(dataService);
     }
     public StatisticsProvider(final DataProviderService dataService) {
         this.dps = Preconditions.checkNotNull(dataService);
     }
@@ -95,7 +81,7 @@ public class StatisticsProvider implements AutoCloseable {
 
     private ListenerRegistration<DataChangeListener> flowCapableTrackerRegistration;
 
 
     private ListenerRegistration<DataChangeListener> flowCapableTrackerRegistration;
 
-    public void start(final DataBrokerService dbs, final NotificationProviderService nps, final RpcConsumerRegistry rpcRegistry) {
+    public void start(final NotificationProviderService nps, final RpcConsumerRegistry rpcRegistry) {
 
         // Get Group/Meter statistics service instances
         groupStatsService = rpcRegistry.getRpcService(OpendaylightGroupStatisticsService.class);
 
         // Get Group/Meter statistics service instances
         groupStatsService = rpcRegistry.getRpcService(OpendaylightGroupStatisticsService.class);
@@ -112,12 +98,9 @@ public class StatisticsProvider implements AutoCloseable {
         final InstanceIdentifier<FlowCapableNode> fcnId = InstanceIdentifier.builder(Nodes.class)
                 .child(Node.class).augmentation(FlowCapableNode.class).build();
         spLogger.debug("Registering FlowCapable tracker to {}", fcnId);
         final InstanceIdentifier<FlowCapableNode> fcnId = InstanceIdentifier.builder(Nodes.class)
                 .child(Node.class).augmentation(FlowCapableNode.class).build();
         spLogger.debug("Registering FlowCapable tracker to {}", fcnId);
-        this.flowCapableTrackerRegistration = dbs.registerDataChangeListener(fcnId,
+        this.flowCapableTrackerRegistration = dps.registerDataChangeListener(fcnId,
                 new FlowCapableTracker(this, fcnId));
 
                 new FlowCapableTracker(this, fcnId));
 
-        statsUpdateHandler = new StatisticsUpdateHandler(StatisticsProvider.this);
-        registerDataStoreUpdateListener(dbs);
-
         timer.schedule(new TimerTask() {
             @Override
             public void run() {
         timer.schedule(new TimerTask() {
             @Override
             public void run() {
@@ -142,69 +125,6 @@ public class StatisticsProvider implements AutoCloseable {
         spLogger.info("Statistics Provider started.");
     }
 
         spLogger.info("Statistics Provider started.");
     }
 
-    private void registerDataStoreUpdateListener(DataBrokerService dbs) {
-        // FIXME: the below should be broken out into StatisticsUpdateHandler
-
-        //Register for flow updates
-        InstanceIdentifier<? extends DataObject> pathFlow = InstanceIdentifier.builder(Nodes.class).child(Node.class)
-                                                                    .augmentation(FlowCapableNode.class)
-                                                                    .child(Table.class)
-                                                                    .child(Flow.class).toInstance();
-        dbs.registerDataChangeListener(pathFlow, statsUpdateHandler);
-
-        //Register for meter updates
-        InstanceIdentifier<? extends DataObject> pathMeter = InstanceIdentifier.builder(Nodes.class).child(Node.class)
-                                                    .augmentation(FlowCapableNode.class)
-                                                    .child(Meter.class).toInstance();
-
-        dbs.registerDataChangeListener(pathMeter, statsUpdateHandler);
-
-        //Register for group updates
-        InstanceIdentifier<? extends DataObject> pathGroup = InstanceIdentifier.builder(Nodes.class).child(Node.class)
-                                                    .augmentation(FlowCapableNode.class)
-                                                    .child(Group.class).toInstance();
-        dbs.registerDataChangeListener(pathGroup, statsUpdateHandler);
-
-        //Register for queue updates
-        InstanceIdentifier<? extends DataObject> pathQueue = InstanceIdentifier.builder(Nodes.class).child(Node.class)
-                                                                    .child(NodeConnector.class)
-                                                                    .augmentation(FlowCapableNodeConnector.class)
-                                                                    .child(Queue.class).toInstance();
-        dbs.registerDataChangeListener(pathQueue, statsUpdateHandler);
-    }
-
-    protected DataModificationTransaction startChange() {
-        return dps.beginTransaction();
-    }
-
-    public void sendFlowStatsFromTableRequest(NodeKey node, Flow flow) {
-        final NodeStatisticsHandler h = getStatisticsHandler(node.getId());
-        if (h != null) {
-            h.sendFlowStatsFromTableRequest(flow);
-        }
-    }
-
-    public void sendGroupDescriptionRequest(NodeKey node) {
-        final NodeStatisticsHandler h = getStatisticsHandler(node.getId());
-        if (h != null) {
-            h.sendGroupDescriptionRequest();
-        }
-    }
-
-    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) {
-        final NodeStatisticsHandler h = getStatisticsHandler(node.getId());
-        if (h != null) {
-            h.sendQueueStatsFromGivenNodeConnector(nodeConnectorId, queueId);
-        }
-    }
-
     /**
      * Get the handler for a particular node.
      *
     /**
      * Get the handler for a particular node.
      *
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
deleted file mode 100644 (file)
index e22bd08..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright IBM Corporation, 2013.  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 java.util.Map;
-import java.util.Set;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
-import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
-import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-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.FlowStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-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.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
-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;
-
-/**
- * Following are two main responsibilities of the class
- * 1) Listen for the create changes in config data store for tree nodes (Flow,Group,Meter,Queue)
- * and send statistics request to the switch to fetch the statistics
- *
- * 2)Listen for the remove changes in config data store for tree nodes (Flow,Group,Meter,Queue)
- * and remove the relative statistics data from operational data store.
- *
- * @author avishnoi@in.ibm.com
- *
- */
-public class StatisticsUpdateHandler implements DataChangeListener {
-    private final StatisticsProvider statisticsManager;
-
-    public StatisticsUpdateHandler(final StatisticsProvider manager){
-        this.statisticsManager = manager;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
-        Map<InstanceIdentifier<?>, DataObject> additions = change.getCreatedConfigurationData();
-        for (InstanceIdentifier<? extends DataObject> dataObjectInstance : additions.keySet()) {
-            DataObject dataObject = additions.get(dataObjectInstance);
-            NodeKey nodeII = dataObjectInstance.firstKeyOf(Node.class, NodeKey.class);
-            if(dataObject instanceof Flow){
-                Flow flow = (Flow) dataObject;
-                this.statisticsManager.sendFlowStatsFromTableRequest(nodeII, flow);
-            }
-            if(dataObject instanceof Meter){
-                this.statisticsManager.sendMeterConfigStatisticsRequest(nodeII);
-            }
-            if(dataObject instanceof Group){
-                this.statisticsManager.sendGroupDescriptionRequest(nodeII);
-            }
-            if(dataObject instanceof Queue){
-                Queue queue = (Queue) dataObject;
-                InstanceIdentifier<NodeConnector> nodeConnectorII = dataObjectInstance.firstIdentifierOf(NodeConnector.class);
-                NodeConnectorKey nodeConnectorKey = InstanceIdentifier.keyOf(nodeConnectorII);
-                this.statisticsManager.sendQueueStatsFromGivenNodeConnector(nodeII, nodeConnectorKey.getId(), queue.getQueueId());
-            }
-        }
-
-        DataModificationTransaction it = this.statisticsManager.startChange();
-        Set<InstanceIdentifier<? extends DataObject>> removals = change.getRemovedConfigurationData();
-        for (InstanceIdentifier<? extends DataObject> dataObjectInstance : removals) {
-            DataObject dataObject = change.getOriginalConfigurationData().get(dataObjectInstance);
-
-            if(dataObject instanceof Flow){
-                InstanceIdentifier<Flow> flowII = (InstanceIdentifier<Flow>)dataObjectInstance;
-                InstanceIdentifier<?> flowAugmentation =
-                        InstanceIdentifier.builder(flowII).augmentation(FlowStatisticsData.class).toInstance();
-                it.removeOperationalData(flowAugmentation);
-            }
-            if(dataObject instanceof Meter){
-                InstanceIdentifier<Meter> meterII = (InstanceIdentifier<Meter>)dataObjectInstance;
-
-                InstanceIdentifier<?> nodeMeterConfigStatsAugmentation =
-                        InstanceIdentifier.builder(meterII).augmentation(NodeMeterConfigStats.class).toInstance();
-                it.removeOperationalData(nodeMeterConfigStatsAugmentation);
-
-                InstanceIdentifier<?> nodeMeterStatisticsAugmentation =
-                        InstanceIdentifier.builder(meterII).augmentation(NodeMeterStatistics.class).toInstance();
-                it.removeOperationalData(nodeMeterStatisticsAugmentation);
-            }
-
-            if(dataObject instanceof Group){
-                InstanceIdentifier<Group> groupII = (InstanceIdentifier<Group>)dataObjectInstance;
-
-                InstanceIdentifier<?> nodeGroupDescStatsAugmentation =
-                        InstanceIdentifier.builder(groupII).augmentation(NodeGroupDescStats.class).toInstance();
-                it.removeOperationalData(nodeGroupDescStatsAugmentation);
-
-                InstanceIdentifier<?> nodeGroupStatisticsAugmentation =
-                        InstanceIdentifier.builder(groupII).augmentation(NodeGroupStatistics.class).toInstance();
-                it.removeOperationalData(nodeGroupStatisticsAugmentation);
-            }
-
-            if(dataObject instanceof Queue){
-                InstanceIdentifier<Queue> queueII = (InstanceIdentifier<Queue>)dataObjectInstance;
-
-                InstanceIdentifier<?> nodeConnectorQueueStatisticsDataAugmentation =
-                        InstanceIdentifier.builder(queueII).augmentation(FlowCapableNodeConnectorQueueStatisticsData.class).toInstance();
-                it.removeOperationalData(nodeConnectorQueueStatisticsDataAugmentation);
-            }
-        }
-        it.commit();
-    }
-}