Handling RACE conditions in bind/unbind service
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / renderer / ovs / statehelpers / OvsInterfaceTopologyStateUpdateHelper.java
index b1119d20c2844ac95d35599e1f9e6872132cf031..b1c0a7d33af363736e1973a4aff7e7a09d169ca0 100644 (file)
@@ -8,6 +8,9 @@
 package org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers;
 
 import com.google.common.util.concurrent.ListenableFuture;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
@@ -17,19 +20,14 @@ import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.IfmClusterUtils;
 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceBfdStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge._interface.info.BridgeEntry;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-
 public class OvsInterfaceTopologyStateUpdateHelper {
     private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceTopologyStateUpdateHelper.class);
 
@@ -66,50 +64,43 @@ public class OvsInterfaceTopologyStateUpdateHelper {
     }
 
     public static List<ListenableFuture<Void>> updateTunnelState(final DataBroker dataBroker,
-                                                                 final OvsdbTerminationPointAugmentation terminationPointNew) {
-        final Interface interfaceState = InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(terminationPointNew.getName(), dataBroker);
-        final Interface.OperStatus interfaceOperStatus = getTunnelOpState(terminationPointNew.getInterfaceBfdStatus());
-        InterfaceManagerCommonUtils.addBfdStateToCache(terminationPointNew.getName(), interfaceOperStatus);
-        if(interfaceState != null && interfaceState.getOperStatus() != Interface.OperStatus.Unknown) {
-            IfmClusterUtils.runOnlyInLeaderNode(new Runnable() {
-                @Override
-                public void run() {
-                    DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
-                    jobCoordinator.enqueueJob(terminationPointNew.getName(), new Callable<List<ListenableFuture<Void>>>() {
-                        @Override
-                        public List<ListenableFuture<Void>> call() throws Exception {
-                            // update opstate of interface if TEP has gone down/up as a result of BFD monitoring
-                            final List<ListenableFuture<Void>> futures = new ArrayList<ListenableFuture<Void>>();
-                            LOG.debug("updating tunnel state for interface {}", terminationPointNew.getName());
-                            WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
-                            InterfaceManagerCommonUtils.updateOpState(transaction, terminationPointNew.getName(), interfaceOperStatus);
-                            futures.add(transaction.submit());
-                            return futures;
-                        }
-                    });
+                                                                 OvsdbTerminationPointAugmentation terminationPointNew) {
+        final Interface.OperStatus interfaceBfdStatus = getTunnelOpState(terminationPointNew.getInterfaceBfdStatus());
+        final String interfaceName = terminationPointNew.getName();
+        InterfaceManagerCommonUtils.addBfdStateToCache(interfaceName, interfaceBfdStatus);
+        IfmClusterUtils.runOnlyInLeaderNode(() -> {
+            DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
+            jobCoordinator.enqueueJob(interfaceName, () -> {
+                // update opstate of interface if TEP has gone down/up as a result of BFD monitoring
+                final List<ListenableFuture<Void>> futures = new ArrayList<>();
+                final Interface interfaceState = InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(
+                    terminationPointNew.getName(), dataBroker);
+                if (interfaceState != null && interfaceState.getOperStatus() != Interface.OperStatus.Unknown &&
+                    interfaceState.getOperStatus() != interfaceBfdStatus) {
+                    LOG.debug("updating tunnel state for interface {}", interfaceName);
+                    WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
+                    InterfaceManagerCommonUtils.updateOpState(transaction, interfaceName,
+                        interfaceBfdStatus);
+                    futures.add(transaction.submit());
                 }
+                return futures;
             });
-        }
+        }, IfmClusterUtils.INTERFACE_CONFIG_ENTITY);
         return null;
     }
 
-    private static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus
-    getTunnelOpState(List<InterfaceBfdStatus> tunnelBfdStatus) {
-        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus
-                livenessState = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
+    private static Interface.OperStatus getTunnelOpState(List<InterfaceBfdStatus> tunnelBfdStatus) {
+        Interface.OperStatus livenessState = Interface.OperStatus.Down;
         if (tunnelBfdStatus != null && !tunnelBfdStatus.isEmpty()) {
             for (InterfaceBfdStatus bfdState : tunnelBfdStatus) {
                 if (bfdState.getBfdStatusKey().equalsIgnoreCase(SouthboundUtils.BFD_OP_STATE)) {
                     String bfdOpState = bfdState.getBfdStatusValue();
-                    if (bfdOpState.equalsIgnoreCase(SouthboundUtils.BFD_STATE_UP)) {
-                        livenessState = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Up;
-                    } else {
-                        livenessState = org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down;
-                    }
+                    livenessState = SouthboundUtils.BFD_STATE_UP.equalsIgnoreCase(bfdOpState) ?
+                         Interface.OperStatus.Up : Interface.OperStatus.Down;
                     break;
                 }
             }
         }
         return livenessState;
     }
-}
\ No newline at end of file
+}