Bug: 5287 19/36319/3
authorAjay <ajayl.bro@gmail.com>
Wed, 16 Mar 2016 20:03:29 +0000 (20:03 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 16 Mar 2016 23:43:45 +0000 (23:43 +0000)
Added support for multiple instances of data-change-counter
- Changed counter type to list in data-change-counter yang model
- Added counter-id field to module config yang model
- Removed singleton behavior for the module
- Updated TopologyDataChangeCounter to update count using corresponding counter-id
- Updated unit-tests

Change-Id: I15f43faa622c502dfa3837da1a3bed7f4e9c4c1b
Signed-off-by: Ajay <ajayl.bro@gmail.com>
data-change-counter-controller-config/src/main/resources/initial/50-topology-data-change-counter.xml
data-change-counter/src/main/java/org/opendaylight/controller/config/yang/bgpcep/data/change/counter/DataChangeCounterImplModule.java [changed mode: 0644->0755]
data-change-counter/src/main/java/org/opendaylight/controller/config/yang/bgpcep/data/change/counter/DataChangeCounterImplModuleFactory.java [changed mode: 0644->0755]
data-change-counter/src/main/java/org/opendaylight/protocol/data/change/counter/TopologyDataChangeCounter.java [changed mode: 0644->0755]
data-change-counter/src/main/yang/data-change-counter.yang
data-change-counter/src/main/yang/odl-data-change-counter-cfg.yang
data-change-counter/src/test/java/org/opendaylight/controller/config/yang/bgpcep/data/change/counter/DataChangeCounterImplModuleTest.java [changed mode: 0644->0755]
data-change-counter/src/test/java/org/opendaylight/protocol/data/change/counter/TopologyDataChangeCounterTest.java [changed mode: 0644->0755]

index 51276a92ab5027ba082fbf1236dcb87f783a61c0..896b66b37ce260f255041a4a1ccb0c0f417ae159 100644 (file)
@@ -10,7 +10,7 @@
 <snapshot>
     <required-capabilities>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
-        <capability>urn:opendaylight:params:xml:ns:yang:controller:bgpcep:data:change:counter?module=odl-data-change-counter-cfg&amp;revision=2014-08-15</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:bgpcep:data:change:counter?module=odl-data-change-counter-cfg&amp;revision=2016-03-15</capability>
     </required-capabilities>
     <configuration>
 
@@ -18,7 +18,8 @@
             <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
                 <module>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgpcep:data:change:counter">prefix:data-change-counter-impl</type>
-                    <name>data-change-counter-singleton</name>
+                    <name>data-change-counter</name>
+                    <counter-id>data-change-counter</counter-id>
                     <data-provider>
                         <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
                         <name>binding-data-broker</name>
old mode 100644 (file)
new mode 100755 (executable)
index 02fcd38..f057d65
@@ -36,12 +36,13 @@ public class DataChangeCounterImplModule extends org.opendaylight.controller.con
 
     @Override
     public void customValidation() {
+        JmxAttributeValidationException.checkNotNull(getCounterId(), "value is not set.", counterIdJmxAttribute);
         JmxAttributeValidationException.checkNotNull(getTopologyName(), "value is not set.", topologyNameJmxAttribute);
     }
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final TopologyDataChangeCounter counter = new TopologyDataChangeCounter(getDataProviderDependency());
+        final TopologyDataChangeCounter counter = new TopologyDataChangeCounter(getDataProviderDependency(), getCounterId());
         final InstanceIdentifier<Topology> topoIId = InstanceIdentifier.builder(NetworkTopology.class)
                 .child(Topology.class, new TopologyKey(new TopologyId(getTopologyName()))).build();
         final ListenerRegistration<DataChangeListener> registration = getDataProviderDependency().registerDataChangeListener(
old mode 100644 (file)
new mode 100755 (executable)
index 609e0fb..1cbb891
 */
 package org.opendaylight.controller.config.yang.bgpcep.data.change.counter;
 
-import static com.google.common.base.Preconditions.checkArgument;
-
-import org.opendaylight.controller.config.api.DependencyResolver;
-import org.osgi.framework.BundleContext;
-
 public class DataChangeCounterImplModuleFactory extends org.opendaylight.controller.config.yang.bgpcep.data.change.counter.AbstractDataChangeCounterImplModuleFactory {
-    public static final String SINGLETON_NAME = "data-change-counter-singleton";
-
-    @Override
-    public DataChangeCounterImplModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
-            DataChangeCounterImplModule oldModule, AutoCloseable oldInstance, BundleContext bundleContext) {
-        checkArgument(SINGLETON_NAME.equals(instanceName), "Illegal instance name '" + instanceName
-                + "', only allowed name is " + SINGLETON_NAME);
-        return super.instantiateModule(instanceName, dependencyResolver, oldModule,
-                oldInstance, bundleContext);
-    }
 
-    @Override
-    public DataChangeCounterImplModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
-            BundleContext bundleContext) {
-        checkArgument(SINGLETON_NAME.equals(instanceName), "Illegal instance name '" + instanceName
-                + "', only allowed name is " + SINGLETON_NAME);
-        return super.instantiateModule(instanceName, dependencyResolver, bundleContext);
-    }
 }
old mode 100644 (file)
new mode 100755 (executable)
index a324c05..572fdcf
@@ -19,8 +19,10 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev140815.DataChangeCounter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev140815.DataChangeCounterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev160315.DataChangeCounter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev160315.data.change.counter.Counter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev160315.data.change.counter.CounterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev160315.data.change.counter.CounterKey;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -30,42 +32,45 @@ public class TopologyDataChangeCounter implements DataChangeListener, Transactio
 
     private static final Logger LOG = LoggerFactory.getLogger(TopologyDataChangeCounter.class);
 
-    protected static final InstanceIdentifier<DataChangeCounter> IID = InstanceIdentifier
-            .builder(DataChangeCounter.class).build();
-
     private final DataBroker dataBroker;
+    private final String counterId;
+    private final InstanceIdentifier<Counter> counterInstanceId;
     private final BindingTransactionChain chain;
     private final AtomicLong count;
 
-    public TopologyDataChangeCounter(final DataBroker dataBroker) {
+    public TopologyDataChangeCounter(final DataBroker dataBroker, final String counterId) {
         this.dataBroker = dataBroker;
         this.chain = this.dataBroker.createTransactionChain(this);
+        this.counterId = counterId;
+        this.counterInstanceId = InstanceIdentifier.builder(DataChangeCounter.class)
+                .child(Counter.class, new CounterKey(this.counterId)).build();
         this.count = new AtomicLong(0);
         putCount(this.count.get());
-        LOG.debug("Data change counter initiated");
+        LOG.debug("Data change counter {} initiated", this.counterId);
     }
 
     @Override
     public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
         putCount(this.count.incrementAndGet());
-        LOG.debug("Data change #{}", this.count.get());
+        LOG.debug("Data change #{} for counter {}", this.count.get(), this.counterId);
     }
 
     public void close() {
         final WriteTransaction wTx = this.dataBroker.newWriteOnlyTransaction();
-        wTx.delete(LogicalDatastoreType.OPERATIONAL, IID);
+        wTx.delete(LogicalDatastoreType.OPERATIONAL, this.counterInstanceId);
         try {
             wTx.submit().checkedGet();
         } catch (TransactionCommitFailedException except) {
-            LOG.warn("Error on remove  data change counter{}", IID.toString(), except);
+            LOG.warn("Error on remove data change counter {}", this.counterId, except);
         }
         this.chain.close();
-        LOG.debug("Data change counter removed");
+        LOG.debug("Data change counter {} removed", this.counterId);
     }
 
     private void putCount(final long count) {
         final WriteTransaction wTx = this.chain.newWriteOnlyTransaction();
-        wTx.put(LogicalDatastoreType.OPERATIONAL, IID, new DataChangeCounterBuilder().setCount(count).build());
+        Counter counter = new CounterBuilder().setId(this.counterId).setCount(count).build();
+        wTx.put(LogicalDatastoreType.OPERATIONAL, this.counterInstanceId, counter);
         wTx.submit();
     }
 
index c60cf6bcc8ac15d478d0d145fa7d9ea4de951219..28d0e25e2e2d5ba0bc74aec244152e81f04dd938 100644 (file)
@@ -17,16 +17,29 @@ module data-change-counter {
         accompanies this distribution, and is available at
         http://www.eclipse.org/legal/epl-v10.html";
 
+    revision "2016-03-15" {
+        description
+            "Updated to support multiple instances.";
+    }
     revision "2014-08-15" {
         description
             "Initial revision.";
     }
 
     container data-change-counter {
-        leaf count {
-            type uint32;
-            description
-                "The number of data changes.";
+        config false;
+
+        list counter {
+            leaf id {
+                type string;
+            }
+            key id;
+
+            leaf count {
+                type uint32;
+                description
+                    "The number of data changes.";
+            }
         }
     }
- }
\ No newline at end of file
+ }
index 5383e917489f4ae3a64f1cab88052c937ca87658..a1a66c0444cfac6673a607fe3f8051b12adb0072 100644 (file)
@@ -22,6 +22,10 @@ module odl-data-change-counter-cfg {
         accompanies this distribution, and is available at
         http://www.eclipse.org/legal/epl-v10.html";
 
+    revision "2016-03-15" {
+        description
+            "Updated to support multiple instances";
+    }
     revision "2014-08-15" {
         description
             "Initial revision";
@@ -36,6 +40,10 @@ module odl-data-change-counter-cfg {
         case data-change-counter-impl {
             when "/config:modules/config:module/config:type = 'data-change-counter-impl'";
 
+            leaf counter-id {
+                type string;
+            }
+
             leaf topology-name {
                 type string;
             }
@@ -50,4 +58,4 @@ module odl-data-change-counter-cfg {
             }
         }
     }
-}
\ No newline at end of file
+}
old mode 100644 (file)
new mode 100755 (executable)
index bf6f688..7b7b320
@@ -32,7 +32,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev140815.DataChangeCounter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev160315.DataChangeCounter;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.osgi.framework.BundleContext;
@@ -40,9 +40,11 @@ import org.osgi.framework.BundleContext;
 public class DataChangeCounterImplModuleTest extends AbstractConfigTest {
 
     private static final String FACTORY_NAME = DataChangeCounterImplModuleFactory.NAME;
-    private static final String INSTANCE_NAME = DataChangeCounterImplModuleFactory.SINGLETON_NAME;
+    private static final String INSTANCE_NAME = "data-change-counter";
     private static final String DATA_BROKER_INSTANCE_NAME = "data-broker-instance";
 
+    private static final String COUNTER_ID = "counter";
+    private static final String NEW_COUNTER_ID = "new-counter";
     private static final String TOPOLOGY_NAME = "test";
     private static final String NEW_TOPOLOGY_NAME = "new-test";
 
@@ -72,14 +74,14 @@ public class DataChangeCounterImplModuleTest extends AbstractConfigTest {
 
     @Test
     public void testCreateBean() throws Exception {
-        final CommitStatus status = createInstance(TOPOLOGY_NAME);
+        final CommitStatus status = createInstance(COUNTER_ID, TOPOLOGY_NAME);
         assertBeanCount(1, FACTORY_NAME);
         assertStatus(status, 2, 0, 0);
     }
 
     @Test
     public void testReusingOldInstance() throws Exception {
-        createInstance(TOPOLOGY_NAME);
+        createInstance(COUNTER_ID, TOPOLOGY_NAME);
         final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
         assertBeanCount(1, FACTORY_NAME);
         final CommitStatus status = transaction.commit();
@@ -89,10 +91,11 @@ public class DataChangeCounterImplModuleTest extends AbstractConfigTest {
 
     @Test
     public void testReconfigureBean() throws Exception {
-        createInstance(TOPOLOGY_NAME);
+        createInstance(COUNTER_ID, TOPOLOGY_NAME);
         final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
         final DataChangeCounterImplModuleMXBean mxBean = transaction.newMXBeanProxy(transaction.lookupConfigBean(FACTORY_NAME, INSTANCE_NAME),
                 DataChangeCounterImplModuleMXBean.class);
+        mxBean.setCounterId(NEW_COUNTER_ID);
         mxBean.setTopologyName(NEW_TOPOLOGY_NAME);
         final CommitStatus status = transaction.commit();
         assertBeanCount(1, FACTORY_NAME);
@@ -101,14 +104,16 @@ public class DataChangeCounterImplModuleTest extends AbstractConfigTest {
         final ConfigTransactionJMXClient transaction2 = this.configRegistryClient.createTransaction();
         final DataChangeCounterImplModuleMXBean mxBean2 = transaction2.newMXBeanProxy(transaction2.lookupConfigBean(FACTORY_NAME, INSTANCE_NAME),
                 DataChangeCounterImplModuleMXBean.class);
+        Assert.assertEquals(NEW_COUNTER_ID, mxBean2.getCounterId());
         Assert.assertEquals(NEW_TOPOLOGY_NAME, mxBean2.getTopologyName());
     }
 
-    private CommitStatus createInstance(final String topologyName) throws Exception {
+    private CommitStatus createInstance(final String counterId, final String topologyName) throws Exception {
         final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
         final ObjectName on = transaction.createModule(FACTORY_NAME, INSTANCE_NAME);
         final ObjectName dbOn = transaction.createModule(MockDataBrokerModuleFct.INSTANCE_NAME, DATA_BROKER_INSTANCE_NAME);
         final DataChangeCounterImplModuleMXBean mxBean = transaction.newMXBeanProxy(on, DataChangeCounterImplModuleMXBean.class);
+        mxBean.setCounterId(counterId);
         mxBean.setTopologyName(topologyName);
         mxBean.setDataProvider(dbOn);
         return transaction.commit();
old mode 100644 (file)
new mode 100755 (executable)
index bfc042f..4f3219d
@@ -18,30 +18,71 @@ import org.junit.Test;
 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
 import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev140815.DataChangeCounter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev160315.DataChangeCounter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev160315.data.change.counter.Counter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.data.change.counter.rev160315.data.change.counter.CounterKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public class TopologyDataChangeCounterTest extends AbstractDataBrokerTest {
 
+    private static final String COUNTER_ID1 = "counter1";
+    private static final String COUNTER_ID2 = "counter2";
+
     @Test
     public void testDataChangeCounter() throws InterruptedException, ExecutionException {
-        final TopologyDataChangeCounter counter = new TopologyDataChangeCounter(getDataBroker());
-        final Optional<Long> count = getCount();
+        final TopologyDataChangeCounter counter = new TopologyDataChangeCounter(getDataBroker(), COUNTER_ID1);
+        final Optional<Long> count = getCount(COUNTER_ID1);
         assertTrue(count.isPresent());
         assertEquals(0, count.get().longValue());
 
         counter.onDataChanged(null);
-        final Optional<Long> countAfterDataChange = getCount();
+        final Optional<Long> countAfterDataChange = getCount(COUNTER_ID1);
         assertTrue(countAfterDataChange.isPresent());
         assertEquals(1, countAfterDataChange.get().longValue());
 
         counter.close();
-        final Optional<Long> countAfterClose = getCount();
+        final Optional<Long> countAfterClose = getCount(COUNTER_ID1);
         assertFalse(countAfterClose.isPresent());
     }
 
-    private Optional<Long> getCount() throws InterruptedException, ExecutionException {
+    @Test
+    public void testDataChangeCounterTwoInstances() throws InterruptedException, ExecutionException {
+        final TopologyDataChangeCounter counter1 = new TopologyDataChangeCounter(getDataBroker(), COUNTER_ID1);
+        final Optional<Long> count1 = getCount(COUNTER_ID1);
+        assertTrue(count1.isPresent());
+        assertEquals(0, count1.get().longValue());
+
+        final TopologyDataChangeCounter counter2 = new TopologyDataChangeCounter(getDataBroker(), COUNTER_ID2);
+        final Optional<Long> count2 = getCount(COUNTER_ID2);
+        assertTrue(count2.isPresent());
+        assertEquals(0, count2.get().longValue());
+
+        counter1.onDataChanged(null);
+        final Optional<Long> countAfterDataChange1 = getCount(COUNTER_ID1);
+        assertTrue(countAfterDataChange1.isPresent());
+        assertEquals(1, countAfterDataChange1.get().longValue());
+        // Check that counter2 does not get incremented
+        final Optional<Long> countAfterDataChange2 = getCount(COUNTER_ID2);
+        assertTrue(countAfterDataChange2.isPresent());
+        assertEquals(0, countAfterDataChange2.get().longValue());
+
+        counter1.close();
+        final Optional<Long> countAfterClose1 = getCount(COUNTER_ID1);
+        assertFalse(countAfterClose1.isPresent());
+        // Check that counter2 does not get deleted
+        final Optional<Long> countAfterClose2 = getCount(COUNTER_ID2);
+        assertTrue(countAfterClose2.isPresent());
+
+        counter2.close();
+        final Optional<Long> countAfterClose3 = getCount(COUNTER_ID2);
+        assertFalse(countAfterClose3.isPresent());
+    }
+
+    private Optional<Long> getCount(String counterId) throws InterruptedException, ExecutionException {
         final ReadTransaction rTx = getDataBroker().newReadOnlyTransaction();
-        final Optional<DataChangeCounter> dataMaybe = rTx.read(LogicalDatastoreType.OPERATIONAL, TopologyDataChangeCounter.IID).get();
+        final InstanceIdentifier<Counter> counterInstanceId = InstanceIdentifier.builder(DataChangeCounter.class)
+                .child(Counter.class, new CounterKey(counterId)).build();
+        final Optional<Counter> dataMaybe = rTx.read(LogicalDatastoreType.OPERATIONAL, counterInstanceId).get();
         if (dataMaybe.isPresent()) {
             return Optional.of(dataMaybe.get().getCount());
         }