BUG-6059: Moving Statistics Manager to DTCL 99/40199/8
authorShuva Kar <shuva.jyoti.kar@ericsson.com>
Sun, 12 Jun 2016 10:11:38 +0000 (15:41 +0530)
committerShuva Jyoti Kar <shuva.jyoti.kar@ericsson.com>
Thu, 14 Jul 2016 17:58:40 +0000 (17:58 +0000)
Change-Id: Icd82a0be1c905ffa7039575bf668ba00ece736e7
Signed-off-by: Shuva Kar <shuva.jyoti.kar@ericsson.com>
applications/statistics-manager/pom.xml
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/StatListeningCommiter.java
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/StatNodeRegistration.java
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatAbstractListenCommit.java
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitFlow.java
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitGroup.java
applications/statistics-manager/src/main/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatListenCommitMeter.java
applications/statistics-manager/src/test/java/org/opendaylight/openflowplugin/applications/statistics/manager/impl/StatAbstractListenCommitTest.java
applications/statistics-manager/src/test/java/test/mock/StatCollectorTest.java

index 25ea5e9d868045acdfd46345efb49defbedf7b17..c3f47f433ba674b5de6aa93118e1d0d46e2ba6f7 100644 (file)
       <groupId>org.opendaylight.openflowplugin.model</groupId>
       <artifactId>model-flow-statistics</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>openflowplugin-common</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.osgi</groupId>
       <artifactId>org.osgi.core</artifactId>
index 198e83976a7d8b6cab5ef0d0e948b33fb8caebb9..d40e4cbcf2a3aac58999e5913f0e43929685d8a6 100644 (file)
@@ -8,7 +8,7 @@
 
 package org.opendaylight.openflowplugin.applications.statistics.manager;
 
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -19,7 +19,7 @@ import org.opendaylight.yangtools.yang.binding.NotificationListener;
  * org.opendaylight.openflowplugin.applications.statistics.manager
  *
  * StatListeningCommiter
- * Definition Interface for {@link DataChangeListener} implementer class rule.
+ * Definition Interface for {@link DataTreeChangeListener} implementer class rule.
  * Interface represent a contract between Config/DataStore changes and
  * Operational/DataStore commits. All Operational/DataStore commit have
  * to by represent as RPC Device response Notification processing. So
@@ -29,7 +29,7 @@ import org.opendaylight.yangtools.yang.binding.NotificationListener;
  *
  * Created: Aug 27, 2014
  */
-public interface StatListeningCommiter<T extends DataObject, N extends NotificationListener> extends DataChangeListener, StatNotifyCommiter<N> {
+public interface StatListeningCommiter<T extends DataObject, N extends NotificationListener> extends DataTreeChangeListener<T>, StatNotifyCommiter<N> {
 
 
     /**
index 4defa148c678efd4af9c072074cde564e4c0f41b..0a6e51e976bec3f00ea3396813978f3637ba8f7a 100644 (file)
@@ -20,7 +20,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
  *
  * StatNodeRegistration
  * Class represents {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode}
- * {@link org.opendaylight.controller.md.sal.binding.api.DataChangeListener} in Operational/DataStore for ADD / REMOVE
+ * {@link org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener} in Operational/DataStore for ADD / REMOVE
  * actions which are represented connect / disconnect OF actions. Connect functionality are expecting
  *
  * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
index 0b95b2b9b4d4324ba16930a2af27e497c374206b..5a96bf79aec249f18e38612c9baf52a1aa35d112 100644 (file)
@@ -10,25 +10,27 @@ package org.opendaylight.openflowplugin.applications.statistics.manager.impl;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+
+import java.util.Collection;
 import java.util.Map;
+import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+
+import org.opendaylight.controller.md.sal.binding.api.*;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.openflowplugin.applications.statistics.manager.StatListeningCommiter;
 import org.opendaylight.openflowplugin.applications.statistics.manager.StatNodeRegistration;
 import org.opendaylight.openflowplugin.applications.statistics.manager.StatisticsManager;
+import org.opendaylight.openflowplugin.common.wait.SimpleTaskRetryLooper;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 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.slf4j.LoggerFactory;
 
@@ -48,7 +50,7 @@ public abstract class StatAbstractListenCommit<T extends DataObject, N extends N
 
     private static final Logger LOG = LoggerFactory.getLogger(StatAbstractListenCommit.class);
 
-    private ListenerRegistration<DataChangeListener> listenerRegistration;
+    private ListenerRegistration<StatAbstractListenCommit<T, N>> listenerRegistration;
 
     protected final Map<InstanceIdentifier<Node>, Map<InstanceIdentifier<T>, Integer>> mapNodesForDelete = new ConcurrentHashMap<>();
     protected final Map<InstanceIdentifier<Node>, Integer> mapNodeFeautureRepeater = new ConcurrentHashMap<>();
@@ -62,29 +64,45 @@ public abstract class StatAbstractListenCommit<T extends DataObject, N extends N
     private ReadOnlyTransaction currentReadTx;
     private volatile boolean currentReadTxStale;
 
+    private static final int STARTUP_LOOP_TICK = 500;
+    private static final int STARTUP_LOOP_MAX_RETRIES = 8;
+
+    private final DataTreeIdentifier<T> treeId =
+            new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, getWildCardedRegistrationPath());
+
     /* Constructor has to make a registration */
     public StatAbstractListenCommit(final StatisticsManager manager, final DataBroker db,
             final NotificationProviderService nps, final Class<T> clazz, final StatNodeRegistration nodeRegistrationManager) {
         super(manager,nps, nodeRegistrationManager);
         this.clazz = Preconditions.checkNotNull(clazz, "Referenced Class can not be null");
         Preconditions.checkArgument(db != null, "DataBroker can not be null!");
-        listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
-                getWildCardedRegistrationPath(), this, DataChangeScope.BASE);
         this.dataBroker = db;
         this.nodeRegistrationManager = nodeRegistrationManager;
+
+        SimpleTaskRetryLooper looper = new SimpleTaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
+        try{
+            listenerRegistration =  looper.loopUntilNoException(new Callable<ListenerRegistration<StatAbstractListenCommit<T, N>>>() {
+                @Override
+                public ListenerRegistration<StatAbstractListenCommit<T, N>> call() throws Exception {
+                    return db.registerDataTreeChangeListener(treeId,StatAbstractListenCommit.this);
+                }
+            });
+        }catch(final Exception ex){
+            LOG.debug(" StatAbstractListenCommit DataChange listener registration failed {}", ex.getMessage());
+            throw new IllegalStateException("Notification supplier startup fail! System needs restart.", ex);
+        }
     }
 
     /**
      * Method returns WildCarded Path which is used for registration as a listening path changes in
-     * {@link org.opendaylight.controller.md.sal.binding.api.DataChangeListener}
+     * {@link org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener}
      * @return
      */
     protected abstract InstanceIdentifier<T> getWildCardedRegistrationPath();
 
     @Override
-    public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
-        Preconditions.checkNotNull(changeEvent,"Async ChangeEvent can not be null!");
-
+    public void onDataTreeChanged(Collection<DataTreeModification<T>> changes) {
+        Preconditions.checkNotNull(changes, "Changes must not be null!");
         /*
          * If we have opened read transaction for configuration data store, we need to mark it as stale.
          *
index 63f08c79dd9d173f8c7d8069705b6db4e62ff6af..84a0d91490160b738419efb165ca6ea4124aec3e 100644 (file)
@@ -72,7 +72,7 @@ import org.slf4j.LoggerFactory;
  * org.opendaylight.openflowplugin.applications.statistics.manager.impl
  *
  * StatListenCommitFlow
- * Class is a NotifyListener for FlowStatistics and DataChangeListener for Config/DataStore for Flow node.
+ * Class is a NotifyListener for FlowStatistics and DataTreeChangeListener for Config/DataStore for Flow node.
  * All expected (registered) FlowStatistics will be builded and commit to Operational/DataStore.
  * DataChangeEven should call create/delete Flow in Operational/DS create process needs to pair
  * Device Flow HashCode and FlowId from Config/DS
index c68acd76c302ac3522a9e8e529e10c0e067a1ed7..a89ea181f0449c36d1e9c4c7298ee47800d9b402 100644 (file)
@@ -64,7 +64,7 @@ import com.google.common.base.Preconditions;
  * org.opendaylight.openflowplugin.applications.statistics.manager.impl
  *
  * StatListenCommitGroup
- * Class is a NotifyListener for GroupStatistics and DataChangeListener for Config/DataStore for Group node.
+ * Class is a NotifyListener for GroupStatistics and DataTreeChangeListener for Config/DataStore for Group node.
  * All expected (registered) GroupStatistics will be builded and commit to Operational/DataStore.
  * DataChangeEven should call create/delete Group in Operational/DS
  *
index 3e97bc050d77633d6b47c0e583d2a89c00e2726d..127e2c6a7451281b66e0b2f5523d227763d2a922 100644 (file)
@@ -65,7 +65,7 @@ import com.google.common.base.Preconditions;
  * org.opendaylight.openflowplugin.applications.statistics.manager.impl
  *
  * StatListenCommitMeter
- * Class is a NotifyListener for MeterStatistics and DataChangeListener for Config/DataStore for Meter node.
+ * Class is a NotifyListener for MeterStatistics and DataTreeChangeListener for Config/DataStore for Meter node.
  * All expected (registered) MeterStatistics will be builded and commit to Operational/DataStore.
  * DataChangeEven should call create/delete Meter in Operational/DS
  *
index 195dbcee75cd9193bfae705cd833041f4d2a0aab..93b150741df31089dc95249726ae05e274001df8 100644 (file)
@@ -26,7 +26,7 @@ import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
@@ -36,6 +36,9 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
 
+import java.util.ArrayList;
+
+
 /**
  * Unit tests for StatAbstractListenCommit.
  *
@@ -153,7 +156,7 @@ public class StatAbstractListenCommitTest {
                     @Override
                     public CheckedFuture<Optional<DataObject>, ReadFailedException> answer(
                             InvocationOnMock unused) {
-                        statCommit.onDataChanged(mock(AsyncDataChangeEvent.class));
+                        statCommit.onDataTreeChanged(new ArrayList<>());
                         return Futures.immediateCheckedFuture(expected1);
                     }
                 };
index 48a993e6bd455260456c345e15f1ebbc4a716b91..d0546fa0ed1d319db7067a0286e55734cf872bd4 100644 (file)
@@ -4,13 +4,12 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 import com.google.common.base.Optional;
+
+import java.util.Collection;
 import java.util.concurrent.ExecutionException;
 import org.junit.Test;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.*;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
@@ -64,8 +63,8 @@ public class StatCollectorTest extends StatisticsManagerTest {
         final InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
                 .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(flow.getTableId()));
 
-        getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
-                tableII.child(Flow.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+        getDataBroker().registerDataTreeChangeListener( new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                tableII.child(Flow.class)), new ChangeListener());
 
         synchronized (waitObject) {
             waitObject.wait();
@@ -89,8 +88,8 @@ public class StatCollectorTest extends StatisticsManagerTest {
 
         final InstanceIdentifier<Group> groupII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
                 .augmentation(FlowCapableNode.class).child(Group.class, getGroup().getKey());
-        getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
-                groupII.augmentation(NodeGroupStatistics.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+        getDataBroker().registerDataTreeChangeListener( new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                groupII.augmentation(NodeGroupStatistics.class)), new ChangeListener());
 
         synchronized (waitObject) {
             waitObject.wait();
@@ -123,8 +122,8 @@ public class StatCollectorTest extends StatisticsManagerTest {
 
         final InstanceIdentifier<Group> groupII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
                 .augmentation(FlowCapableNode.class).child(Group.class, getGroup().getKey());
-        getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
-                groupII.augmentation(NodeGroupStatistics.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+        getDataBroker().registerDataTreeChangeListener( new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                groupII.augmentation(NodeGroupStatistics.class)), new ChangeListener());
 
         synchronized (waitObject) {
             waitObject.wait();
@@ -157,8 +156,8 @@ public class StatCollectorTest extends StatisticsManagerTest {
 
         final InstanceIdentifier<Meter> meterII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
                 .augmentation(FlowCapableNode.class).child(Meter.class, getMeter().getKey());
-        getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
-                meterII.augmentation(NodeMeterStatistics.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+        getDataBroker().registerDataTreeChangeListener( new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                meterII.augmentation(NodeMeterStatistics.class)), new ChangeListener());
 
         synchronized (waitObject) {
             waitObject.wait();
@@ -206,8 +205,8 @@ public class StatCollectorTest extends StatisticsManagerTest {
         writeTx.put(LogicalDatastoreType.OPERATIONAL, queueII, qBuilder.build());
         assertCommit(writeTx.submit());
 
-        getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
-                queueII.augmentation(FlowCapableNodeConnectorQueueStatisticsData.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+        getDataBroker().registerDataTreeChangeListener( new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                queueII.augmentation(FlowCapableNodeConnectorQueueStatisticsData.class)), new ChangeListener());
 
         synchronized (waitObject) {
             waitObject.wait();
@@ -238,9 +237,8 @@ public class StatCollectorTest extends StatisticsManagerTest {
         writeTx.put(LogicalDatastoreType.OPERATIONAL, nodeConnectorII, ncBuilder.build());
         assertCommit(writeTx.submit());
 
-        getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
-                nodeConnectorII.augmentation(FlowCapableNodeConnectorStatisticsData.class),
-                new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+        getDataBroker().registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                nodeConnectorII.augmentation(FlowCapableNodeConnectorStatisticsData.class)), new ChangeListener());
 
         synchronized (waitObject) {
             waitObject.wait();
@@ -269,8 +267,8 @@ public class StatCollectorTest extends StatisticsManagerTest {
         final InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
                 .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId.getValue()));
 
-        getDataBroker().registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
-                tableII.augmentation(FlowTableStatisticsData.class), new ChangeListener(), AsyncDataBroker.DataChangeScope.BASE);
+        getDataBroker().registerDataTreeChangeListener( new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+                tableII.augmentation(FlowTableStatisticsData.class)), new ChangeListener());
 
         synchronized (waitObject) {
             waitObject.wait();
@@ -286,13 +284,14 @@ public class StatCollectorTest extends StatisticsManagerTest {
                 flowTableStatisticsDataOptional.get().getFlowTableStatistics().getPacketsLookedUp());
     }
 
-    public class ChangeListener implements DataChangeListener {
+    public class ChangeListener<T extends DataObject> implements DataTreeChangeListener<T> {
 
         @Override
-        public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+        public void onDataTreeChanged(final Collection<DataTreeModification<T>> changes){
             synchronized (waitObject) {
                 waitObject.notify();
             }
         }
+
     }
 }