MRI version bumpup for Aluminium
[netvirt.git] / vpnmanager / impl / src / main / java / org / opendaylight / netvirt / vpnmanager / VpnInterfaceOpListener.java
index 05b70943fd1bc1d4cae0e077ddfefd89606558a5..e4411246022feed950552a883a70a2220ee52e54 100644 (file)
@@ -7,40 +7,47 @@
  */
 package org.opendaylight.netvirt.vpnmanager;
 
-import com.google.common.base.Optional;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 import javax.inject.Singleton;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
-import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.Datastore.Operational;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadTransaction;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
-import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
+import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.serviceutils.tools.listener.AbstractAsyncDataTreeChangeListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesOp;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.Adjacency;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.AdjacencyKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public class VpnInterfaceOpListener extends AsyncDataTreeChangeListenerBase<VpnInterfaceOpDataEntry,
-                                                                     VpnInterfaceOpListener> {
+public class VpnInterfaceOpListener extends AbstractAsyncDataTreeChangeListener<VpnInterfaceOpDataEntry> {
     private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceOpListener.class);
     private final DataBroker dataBroker;
     private final ManagedNewTransactionRunner txRunner;
@@ -59,57 +66,55 @@ public class VpnInterfaceOpListener extends AsyncDataTreeChangeListenerBase<VpnI
     public VpnInterfaceOpListener(final DataBroker dataBroker, final VpnInterfaceManager vpnInterfaceManager,
         final VpnFootprintService vpnFootprintService, final JobCoordinator jobCoordinator,
                                   final VpnUtil vpnUtil) {
-        super(VpnInterfaceOpDataEntry.class, VpnInterfaceOpListener.class);
+        super(dataBroker, LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(VpnInterfaceOpData.class)
+                        .child(VpnInterfaceOpDataEntry.class),
+                org.opendaylight.infrautils.utils.concurrent.Executors
+                        .newListeningSingleThreadExecutor("VpnInterfaceOpListener", LOG));
         this.dataBroker = dataBroker;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.vpnInterfaceManager = vpnInterfaceManager;
         this.vpnFootprintService = vpnFootprintService;
         this.jobCoordinator = jobCoordinator;
         this.vpnUtil = vpnUtil;
+        start();
     }
 
-    @PostConstruct
     public void start() {
         LOG.info("{} start", getClass().getSimpleName());
-        registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
     }
 
     @Override
-    protected InstanceIdentifier<VpnInterfaceOpDataEntry> getWildCardPath() {
-        InstanceIdentifier<VpnInterfaceOpDataEntry> id = InstanceIdentifier.create(VpnInterfaceOpData.class
-                ).child(VpnInterfaceOpDataEntry.class);
-        return id;
+    @PreDestroy
+    public void close() {
+        super.close();
+        org.opendaylight.infrautils.utils.concurrent.Executors.shutdownAndAwaitTermination(getExecutorService());
     }
 
     @Override
-    protected VpnInterfaceOpListener getDataTreeChangeListener() {
-        return VpnInterfaceOpListener.this;
-    }
-
-
-    @Override
-    // Allow deprecated TransactionRunner calls for now
-    @SuppressWarnings("ForbidCertainMethod")
-    protected void remove(final InstanceIdentifier<VpnInterfaceOpDataEntry> identifier,
+    public void remove(final InstanceIdentifier<VpnInterfaceOpDataEntry> identifier,
             final VpnInterfaceOpDataEntry del) {
         final VpnInterfaceOpDataEntryKey key = identifier.firstKeyOf(VpnInterfaceOpDataEntry.class);
         final String interfaceName = key.getName();
         jobCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName,
-            () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
-                postProcessVpnInterfaceRemoval(identifier, del, tx);
+            () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> {
+                postProcessVpnInterfaceRemoval(identifier, del, tx, null);
                 LOG.info("remove: Removed vpn operational data for interface {} on dpn {} vpn {}", del.getName(),
                         del.getDpnId(), del.getVpnInstanceName());
             })));
     }
 
-    // Allow deprecated TransactionRunner calls for now
-    @SuppressWarnings("ForbidCertainMethod")
     private void postProcessVpnInterfaceRemoval(InstanceIdentifier<VpnInterfaceOpDataEntry> identifier,
-            VpnInterfaceOpDataEntry del, ReadWriteTransaction readWriteTxn) {
-        if (readWriteTxn == null) {
-            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(tx ->
-                            postProcessVpnInterfaceRemoval(identifier, del, tx)), LOG,
-                    "Error post-processing VPN interface removal");
+            VpnInterfaceOpDataEntry del, @Nullable TypedReadWriteTransaction<Operational> operTx,
+            @Nullable TypedReadTransaction<Configuration> confTx) throws InterruptedException {
+        if (confTx == null) {
+            txRunner.callWithNewReadOnlyTransactionAndClose(CONFIGURATION,
+                tx -> postProcessVpnInterfaceRemoval(identifier, del, operTx, tx));
+            return;
+        }
+        if (operTx == null) {
+            LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
+                tx -> postProcessVpnInterfaceRemoval(identifier, del, tx, confTx)), LOG,
+                "Error post-processing VPN interface removal");
             return;
         }
         final VpnInterfaceOpDataEntryKey key = identifier.firstKeyOf(VpnInterfaceOpDataEntry.class);
@@ -119,8 +124,8 @@ public class VpnInterfaceOpListener extends AsyncDataTreeChangeListenerBase<VpnI
             LOG.info("postProcessVpnInterfaceRemoval: interface name {} vpnName {} dpn {}", interfaceName, vpnName,
                     del.getDpnId());
             //decrement the vpn interface count in Vpn Instance Op Data
-            Optional<VpnInstance> vpnInstance = readWriteTxn.read(LogicalDatastoreType.CONFIGURATION,
-                    VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName)).checkedGet();
+            Optional<VpnInstance> vpnInstance =
+                confTx.read(VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName)).get();
 
             if (vpnInstance.isPresent()) {
                 String rd = vpnInstance.get().getVrfId();
@@ -128,9 +133,9 @@ public class VpnInterfaceOpListener extends AsyncDataTreeChangeListenerBase<VpnI
                 VpnInstanceOpDataEntry vpnInstOp = vpnUtil.getVpnInstanceOpData(rd);
 
                 AdjacenciesOp adjs = del.augmentation(AdjacenciesOp.class);
-                List<Adjacency> adjList = adjs != null ? adjs.getAdjacency() : null;
+                Map<AdjacencyKey, Adjacency> adjMap = adjs != null ? adjs.getAdjacency() : null;
 
-                if (vpnInstOp != null && adjList != null && adjList.size() > 0) {
+                if (vpnInstOp != null && adjMap != null && adjMap.size() > 0) {
                 /*
                  * When a VPN Interface is removed by FibManager (aka VrfEntryListener and its cohorts),
                  * one adjacency or two adjacency (in case of dual-stack)
@@ -145,20 +150,18 @@ public class VpnInterfaceOpListener extends AsyncDataTreeChangeListenerBase<VpnI
                  * vpnInterface from it.
                  */
                     List<Prefixes> prefixToInterface = new ArrayList<>();
-                    for (Adjacency adjacency : adjs.getAdjacency()) {
+                    for (Adjacency adjacency : adjs.getAdjacency().values()) {
                         List<Prefixes> prefixToInterfaceLocal = new ArrayList<>();
-                        Optional<Prefixes> prefix = SingleTransactionDataBroker.syncReadOptional(dataBroker,
-                                LogicalDatastoreType.OPERATIONAL,
-                                VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
-                                        VpnUtil.getIpPrefix(adjacency.getIpAddress())));
+                        Optional<Prefixes> prefix = operTx.read(
+                            VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+                                VpnUtil.getIpPrefix(adjacency.getIpAddress()))).get();
                         if (prefix.isPresent()) {
                             prefixToInterfaceLocal.add(prefix.get());
                         }
                         if (prefixToInterfaceLocal.isEmpty() && adjacency.getNextHopIpList() != null) {
                             for (String nh : adjacency.getNextHopIpList()) {
-                                prefix = SingleTransactionDataBroker.syncReadOptional(dataBroker,
-                                        LogicalDatastoreType.OPERATIONAL, VpnUtil.getPrefixToInterfaceIdentifier(
-                                                vpnInstOp.getVpnId(), VpnUtil.getIpPrefix(nh)));
+                                prefix = operTx.read(VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+                                    VpnUtil.getIpPrefix(nh))).get();
                                 if (prefix.isPresent()) {
                                     prefixToInterfaceLocal.add(prefix.get());
                                 }
@@ -182,9 +185,8 @@ public class VpnInterfaceOpListener extends AsyncDataTreeChangeListenerBase<VpnI
                  */
                     for (Prefixes pref : prefixToInterface) {
                         if (VpnUtil.isMatchedPrefixToInterface(pref, del)) {
-                            readWriteTxn.delete(LogicalDatastoreType.OPERATIONAL,
-                                    VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
-                                                                                pref.getIpAddress()));
+                            operTx.delete(
+                                VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), pref.getIpAddress()));
                         }
                     }
                 }
@@ -201,7 +203,7 @@ public class VpnInterfaceOpListener extends AsyncDataTreeChangeListenerBase<VpnI
                         del.getDpnId());
             }
             notifyTaskIfRequired(interfaceName);
-        } catch (ReadFailedException e) {
+        } catch (InterruptedException | ExecutionException e) {
             LOG.error("postProcessVpnInterfaceRemoval: Failed to read data store for interface {} vpn {}",
                     interfaceName, vpnName);
         }
@@ -217,13 +219,13 @@ public class VpnInterfaceOpListener extends AsyncDataTreeChangeListenerBase<VpnI
     }
 
     @Override
-    protected void update(final InstanceIdentifier<VpnInterfaceOpDataEntry> identifier,
+    public void update(final InstanceIdentifier<VpnInterfaceOpDataEntry> identifier,
             final VpnInterfaceOpDataEntry original, final VpnInterfaceOpDataEntry update) {
         LOG.info("update: interface {} vpn {}", original.getName(), original.getVpnInstanceName());
     }
 
     @Override
-    protected void add(InstanceIdentifier<VpnInterfaceOpDataEntry> identifier, VpnInterfaceOpDataEntry add) {
+    public void add(InstanceIdentifier<VpnInterfaceOpDataEntry> identifier, VpnInterfaceOpDataEntry add) {
         LOG.info("add: interface {} vpn {}. Ignoring", add.getName(), add.getVpnInstanceName());
     }
 }