Fix: Internal tunnels missing after karaf restart in all 3 CICs 60/91760/2
authorApurba Mukherjee <apurba.mukherjee@ericsson.com>
Wed, 29 Jul 2020 14:11:46 +0000 (19:41 +0530)
committerNishchya Gupta <nishchyag@altencalsoftlabs.com>
Fri, 28 Aug 2020 10:25:24 +0000 (15:55 +0530)
NPE in DPNTEPsInfoCache due to CDTCN registration and invocation
happened before DPNTEPsInfoCache constructor could finish initializing
instance variables.

Change-Id: Id80a9f6ec12d693332dc4cfcecbb9f4c0e39f7e6
Signed-off-by: Apurba Mukherjee <apurba.mukherjee@ericsson.com>
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/cache/DPNTEPsInfoCache.java
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/mdsalutil/cache/DataObjectCache.java
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/mdsalutil/cache/InstanceIdDataObjectCache.java

index 9b025503f21c2b284948d33f72f0a9d7fce2fde5..9d33cd42bb97385213ddc6f4879f8322348594c0 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.infrautils.caches.CacheProvider;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.infrautils.utils.concurrent.NamedSimpleReentrantLock.Acquired;
 import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
@@ -56,12 +57,14 @@ public class DPNTEPsInfoCache extends InstanceIdDataObjectCache<DPNTEPsInfo> {
     public DPNTEPsInfoCache(final DataBroker dataBroker, final CacheProvider cacheProvider,
                             final DirectTunnelUtils directTunnelUtils, final JobCoordinator coordinator,
                             final UnprocessedNodeConnectorEndPointCache unprocessedNodeConnectorEndPointCache) {
-        super(DPNTEPsInfo.class, dataBroker, LogicalDatastoreType.CONFIGURATION,
-                InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class).build(), cacheProvider);
+        super(DPNTEPsInfo.class, dataBroker, LogicalDatastoreType.CONFIGURATION, cacheProvider);
         this.directTunnelUtils = directTunnelUtils;
         this.coordinator = coordinator;
         this.unprocessedNodeConnectorEndPointCache = unprocessedNodeConnectorEndPointCache;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+        listenerRegistration = dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(
+                LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(DpnEndpoints.class)
+                .child(DPNTEPsInfo.class).build()), dataObjectListener);
     }
 
     @Override
index d396f8e29e45234a4843e54ca5b2185b57e5b4d4..9997fa79d0ba2e6a5e7aea693571a6e3296fdb81 100644 (file)
@@ -50,8 +50,9 @@ public class DataObjectCache<K, V extends DataObject> implements AutoCloseable {
 
     private final SingleTransactionDataBroker broker;
     private final LoadingCache<K, Optional<V>> cache;
-    private final ListenerRegistration<?> listenerRegistration;
     private final AtomicBoolean isClosed = new AtomicBoolean();
+    protected ListenerRegistration<?> listenerRegistration;
+    protected ClusteredDataTreeChangeListener<V> dataObjectListener;
 
     /**
      * Constructor.
@@ -59,15 +60,23 @@ public class DataObjectCache<K, V extends DataObject> implements AutoCloseable {
      * @param dataObjectClass the DataObject class to cache
      * @param dataBroker the DataBroker
      * @param datastoreType the LogicalDatastoreType
-     * @param listenerRegistrationPath the yang path for which register the listener
      * @param cacheProvider the CacheProvider used to instantiate the Cache
      * @param keyFunction the function used to convert or extract the key instance on change notification
      * @param instanceIdFunction the function used to convert a key instance to an InstanceIdentifier on read
      */
     public DataObjectCache(Class<V> dataObjectClass, DataBroker dataBroker, LogicalDatastoreType datastoreType,
-            InstanceIdentifier<V> listenerRegistrationPath, CacheProvider cacheProvider,
-            BiFunction<InstanceIdentifier<V>, V, K> keyFunction,
-            Function<K, InstanceIdentifier<V>> instanceIdFunction) {
+                           InstanceIdentifier<V> listetenerRegistrationPath, CacheProvider cacheProvider,
+                           BiFunction<InstanceIdentifier<V>, V, K> keyFunction,
+                           Function<K, InstanceIdentifier<V>> instanceIdFunction) {
+        this(dataObjectClass, dataBroker, datastoreType, cacheProvider, keyFunction, instanceIdFunction);
+        listenerRegistration = dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(
+                datastoreType, listetenerRegistrationPath), dataObjectListener);
+
+    }
+
+    public DataObjectCache(Class<V> dataObjectClass, DataBroker dataBroker, LogicalDatastoreType datastoreType,
+                           CacheProvider cacheProvider, BiFunction<InstanceIdentifier<V>, V, K> keyFunction,
+                           Function<K, InstanceIdentifier<V>> instanceIdFunction) {
         Objects.requireNonNull(keyFunction);
         Objects.requireNonNull(instanceIdFunction);
         this.broker = new SingleTransactionDataBroker(Objects.requireNonNull(dataBroker));
@@ -80,7 +89,7 @@ public class DataObjectCache<K, V extends DataObject> implements AutoCloseable {
             }
         });
 
-        ClusteredDataTreeChangeListener<V> dataObjectListener = changes -> {
+        dataObjectListener = changes -> {
             for (DataTreeModification<V> dataTreeModification : changes) {
                 DataObjectModification<V> rootNode = dataTreeModification.getRootNode();
                 InstanceIdentifier<V> path = dataTreeModification.getRootPath().getRootIdentifier();
@@ -101,16 +110,15 @@ public class DataObjectCache<K, V extends DataObject> implements AutoCloseable {
                 }
             }
         };
-
-        listenerRegistration = dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(
-                datastoreType, listenerRegistrationPath), dataObjectListener);
     }
 
     @Override
     @PreDestroy
     public void close() {
         if (isClosed.compareAndSet(false, true)) {
-            listenerRegistration.close();
+            if (listenerRegistration != null) {
+                listenerRegistration.close();
+            }
             cache.cleanUp();
         } else {
             LOG.warn("Lifecycled object already closed; ignoring extra close()");
index 3e1a7f9926f0a4edbc5798f9329249525c4c92ae..e2692c91f89e96dda76698fb7d40f8741150217d 100644 (file)
@@ -25,4 +25,9 @@ public class InstanceIdDataObjectCache<V extends DataObject> extends DataObjectC
         super(dataObjectClass, dataBroker, datastoreType, listenerRegistrationPath, cacheProvider,
             (iid, value) -> iid, iid -> iid);
     }
+
+    public InstanceIdDataObjectCache(Class<V> dataObjectClass, DataBroker dataBroker,
+                                     LogicalDatastoreType datastoreType, CacheProvider cacheProvider) {
+        super(dataObjectClass, dataBroker, datastoreType, cacheProvider, (iid, value) -> iid, iid -> iid);
+    }
 }