NETVIRT-1000: protect TunnelEndPointChangeListener 18/65718/6
authorStephen Kitt <skitt@redhat.com>
Mon, 20 Nov 2017 13:28:23 +0000 (14:28 +0100)
committerSam Hague <shague@redhat.com>
Tue, 21 Nov 2017 19:13:34 +0000 (19:13 +0000)
This patch ensures that the write transactions in
TunnelEndPointChangeListener::add are always closed.

Change-Id: I79af37a9c046a405113c1fd408098b06fb59d028
Signed-off-by: Stephen Kitt <skitt@redhat.com>
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/TunnelEndPointChangeListener.java

index 103fd7f6e316535eccef39b6d0d9526fbf0372b6..1c52b40ca7184bd8e308e97c9696be85f5c44ef8 100644 (file)
@@ -11,14 +11,16 @@ package org.opendaylight.netvirt.vpnmanager;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import javax.annotation.PostConstruct;
 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.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.netvirt.vpnmanager.api.InterfaceUtils;
 import org.opendaylight.netvirt.vpnmanager.api.VpnHelper;
@@ -37,6 +39,7 @@ public class TunnelEndPointChangeListener
     private static final Logger LOG = LoggerFactory.getLogger(TunnelEndPointChangeListener.class);
 
     private final DataBroker broker;
+    private final ManagedNewTransactionRunner txRunner;
     private final VpnInterfaceManager vpnInterfaceManager;
     private final JobCoordinator jobCoordinator;
 
@@ -45,6 +48,7 @@ public class TunnelEndPointChangeListener
             final JobCoordinator jobCoordinator) {
         super(TunnelEndPoints.class, TunnelEndPointChangeListener.class);
         this.broker = broker;
+        this.txRunner = new ManagedNewTransactionRunnerImpl(broker);
         this.vpnInterfaceManager = vpnInterfaceManager;
         this.jobCoordinator = jobCoordinator;
     }
@@ -97,11 +101,6 @@ public class TunnelEndPointChangeListener
                         String vpnInterfaceName = vpnInterface.getInterfaceName();
                         jobCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterfaceName,
                             () -> {
-                                WriteTransaction writeConfigTxn = broker.newWriteOnlyTransaction();
-                                WriteTransaction writeOperTxn = broker.newWriteOnlyTransaction();
-                                WriteTransaction writeInvTxn = broker.newWriteOnlyTransaction();
-                                List<ListenableFuture<Void>> futures = new ArrayList<>();
-
                                 final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
                                         .rev140508.interfaces.state.Interface
                                         interfaceState =
@@ -109,15 +108,16 @@ public class TunnelEndPointChangeListener
                                 if (interfaceState == null) {
                                     LOG.debug("add: Cannot retrieve interfaceState for vpnInterfaceName {}, "
                                             + "cannot generate lPortTag and process adjacencies", vpnInterfaceName);
-                                    return futures;
+                                    return Collections.emptyList();
                                 }
                                 final int lPortTag = interfaceState.getIfIndex();
-                                vpnInterfaceManager.processVpnInterfaceAdjacencies(dpnId, lPortTag, vpnName, primaryRd,
-                                        vpnInterfaceName, vpnId, writeConfigTxn, writeOperTxn, writeInvTxn,
-                                        interfaceState);
-                                futures.add(writeOperTxn.submit());
-                                futures.add(writeConfigTxn.submit());
-                                futures.add(writeInvTxn.submit());
+                                List<ListenableFuture<Void>> futures = new ArrayList<>();
+                                futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
+                                    writeConfigTxn -> futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
+                                        writeOperTxn -> futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
+                                            writeInvTxn -> vpnInterfaceManager.processVpnInterfaceAdjacencies(
+                                                    dpnId, lPortTag, vpnName, primaryRd, vpnInterfaceName, vpnId,
+                                                    writeConfigTxn, writeOperTxn, writeInvTxn, interfaceState)))))));
                                 LOG.trace("add: Handled TEP {} add for VPN instance {} VPN interface {}",
                                         tep.getInterfaceName(), vpnName, vpnInterfaceName);
                                 return futures;