Handling RACE conditions in bind/unbind service 25/52925/7
authorFaseela K <faseela.k@ericsson.com>
Tue, 7 Mar 2017 08:24:29 +0000 (13:54 +0530)
committerFaseela K <faseela.k@ericsson.com>
Fri, 10 Mar 2017 06:47:06 +0000 (12:17 +0530)
There are race conditions seen while binding/unbinding services,
due to the configlistener and statelistener being executed parallelly.
Avoiding this by adding a new service_binding_entity, and processing
service binding only on the entity owner.

Removing batching of interface-child-info as it is causing issues in
clustered tests

Change-Id: I35ed95fe99878fcbde757cd61880400832b30220
Signed-off-by: Faseela K <faseela.k@ericsson.com>
14 files changed:
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/InterfacemgrProvider.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/commons/InterfaceManagerCommonUtils.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/listeners/InterfaceConfigListener.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/listeners/InterfaceInventoryStateListener.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/listeners/InterfaceStateListener.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/listeners/TerminationPointStateListener.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/renderer/ovs/confighelpers/OvsInterfaceConfigAddHelper.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/renderer/ovs/confighelpers/OvsVlanMemberConfigAddHelper.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/renderer/ovs/statehelpers/OvsInterfaceTopologyStateUpdateHelper.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/renderer/ovs/utilities/IfmClusterUtils.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/renderer/ovs/utilities/SouthboundUtils.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/servicebindings/flowbased/listeners/FlowBasedServicesConfigListener.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/servicebindings/flowbased/listeners/FlowBasedServicesInterfaceStateListener.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/servicebindings/flowbased/utilities/FlowBasedServicesUtils.java

index 9e3153e89a939ca4f3ef24fe23baec8523512fbe..fdd5958d7a7fe28ba982f667ba76fa4ea3b967c3 100644 (file)
@@ -556,13 +556,13 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
 
     @Override
     public void updateInterfaceParentRef(String interfaceName, String parentInterface) {
-        // This should generally be called by EOS Owner for IFACE_ENTITY - runOnlyInLeaderNode()
+        // This should generally be called by EOS Owner for INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
         updateInterfaceParentRef(interfaceName, parentInterface, true);
     }
 
     @Override
     public void updateInterfaceParentRef(String interfaceName, String parentInterface, boolean readInterfaceBeforeWrite) {
-        // This should generally be called by EOS Owner for IFACE_ENTITY - runOnlyInLeaderNode()
+        // This should generally be called by EOS Owner for INTERFACE_CONFIG_ENTITY - runOnlyInLeaderNode()
         if (interfaceName == null) {
             return;
         }
index 255dd8cfec1e8a41fa434560da8a9aa6bb78e34e..222dabe79134c79e7f64c1d5d9fedb0e12f1858f 100644 (file)
@@ -13,7 +13,6 @@ import com.google.common.util.concurrent.ListenableFuture;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -255,14 +254,19 @@ public class InterfaceManagerCommonUtils {
         MDSALUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, interfaceId, interfaceData);
     }
 
-    public static void createInterfaceChildEntry(String parentInterface, String childInterface) {
+    public static void createInterfaceChildEntry(String parentInterface, String childInterface,
+                                                 Optional<WriteTransaction> txOptional) {
         InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentInterface);
         InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(childInterface);
         InstanceIdentifier<InterfaceChildEntry> intfId = InterfaceMetaUtils
                 .getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
         InterfaceChildEntryBuilder entryBuilder = new InterfaceChildEntryBuilder().setKey(interfaceChildEntryKey)
                 .setChildInterface(childInterface);
-        BatchingUtils.write(intfId, entryBuilder.build(), BatchingUtils.EntityType.DEFAULT_CONFIG);
+        if(!txOptional.isPresent()) {
+            BatchingUtils.write(intfId, entryBuilder.build(), BatchingUtils.EntityType.DEFAULT_CONFIG);
+        } else {
+            txOptional.get().put(LogicalDatastoreType.CONFIGURATION, intfId, entryBuilder.build(), true);
+        }
     }
 
     public static void deleteInterfaceChildEntry(String parentInterface, String childInterface) {
@@ -472,7 +476,7 @@ public class InterfaceManagerCommonUtils {
 
         LOG.info("Creating child interface {} of type {} bound on parent-interface {}",
                 childInterface, l2vlanMode, parentInterface);
-        createInterfaceChildEntry(parentInterface, childInterface);
+        createInterfaceChildEntry(parentInterface, childInterface, Optional.of(tx) );
         return true;
     }
 
index e06721dbf0b2a4ad8d290add42d3aa20c7eb20e1..c9246d9bcbf86f564adea3e99f990122d421e246 100644 (file)
@@ -103,7 +103,7 @@ public class InterfaceConfigListener extends AsyncClusteredDataTreeChangeListene
             String synchronizationKey = isTunnelInterface ?
                     parentRefs.getDatapathNodeIdentifier().toString() : parentRefs.getParentInterface();
             coordinator.enqueueJob(synchronizationKey, configWorker, IfmConstants.JOB_MAX_RETRIES);
-        });
+        }, IfmClusterUtils.INTERFACE_CONFIG_ENTITY);
     }
 
     @Override
@@ -130,7 +130,7 @@ public class InterfaceConfigListener extends AsyncClusteredDataTreeChangeListene
                     interfaceOld.getName() : parentRefs.getParentInterface();
             coordinator.enqueueJob(synchronizationKey, configWorker, IfmConstants.JOB_MAX_RETRIES);
 
-        });
+        }, IfmClusterUtils.INTERFACE_CONFIG_ENTITY);
     }
 
     @Override
@@ -155,7 +155,7 @@ public class InterfaceConfigListener extends AsyncClusteredDataTreeChangeListene
             String synchronizationKey = isTunnelInterface ?
                     interfaceNew.getName() : parentRefs.getParentInterface();
             coordinator.enqueueJob(synchronizationKey, configWorker, IfmConstants.JOB_MAX_RETRIES);
-        });
+        }, IfmClusterUtils.INTERFACE_CONFIG_ENTITY);
     }
 
     private class RendererConfigAddWorker implements Callable<List<ListenableFuture<Void>>> {
index cd2a08e041f9d0334e9e2c7fb06c88a34d916f9f..5ffe9c0a272f600ecbb5b720bb2c8d4f358af6ca 100644 (file)
@@ -88,7 +88,7 @@ public class InterfaceInventoryStateListener extends AsyncClusteredDataTreeChang
             String portName = InterfaceManagerCommonUtils.getPortNameForInterface(nodeConnectorId, flowCapableNodeConnectorOld.getName());
 
             remove(nodeConnectorId, null, flowCapableNodeConnectorOld, portName, true);
-        });
+        }, IfmClusterUtils.INTERFACE_CONFIG_ENTITY);
     }
 
     @Override
@@ -103,7 +103,7 @@ public class InterfaceInventoryStateListener extends AsyncClusteredDataTreeChang
             InterfaceStateUpdateWorker portStateUpdateWorker = new InterfaceStateUpdateWorker(key, fcNodeConnectorOld,
                     fcNodeConnectorNew, portName);
             coordinator.enqueueJob(portName, portStateUpdateWorker, IfmConstants.JOB_MAX_RETRIES);
-        });
+        }, IfmClusterUtils.INTERFACE_CONFIG_ENTITY);
     }
 
     @Override
@@ -131,7 +131,7 @@ public class InterfaceInventoryStateListener extends AsyncClusteredDataTreeChang
             InterfaceStateAddWorker ifStateAddWorker = new InterfaceStateAddWorker(idManager, nodeConnectorId,
                     fcNodeConnectorNew, portName);
             coordinator.enqueueJob(portName, ifStateAddWorker, IfmConstants.JOB_MAX_RETRIES);
-        });
+        }, IfmClusterUtils.INTERFACE_CONFIG_ENTITY);
     }
 
     private void remove(NodeConnectorId nodeConnectorIdNew, NodeConnectorId nodeConnectorIdOld,
index 6489b243720101a51782edbed02ea0da0d6c4a73..10160c509e2cd1a47439abd1c941048d14abab11 100644 (file)
@@ -69,7 +69,7 @@ public class InterfaceStateListener extends AsyncClusteredDataTreeChangeListener
                 }
                 return futures;
             });
-        });
+        }, IfmClusterUtils.INTERFACE_CONFIG_ENTITY);
     }
 
     @Override
index 29730e9d6f09bab1aedc1aa6bdc4b7e1d57462df..5e31916b218804ea530cf1db55ac904f603be540 100644 (file)
@@ -104,7 +104,7 @@ public class TerminationPointStateListener extends AsyncClusteredDataTreeChangeL
                         tpNew.getName(), newInterfaceName, parentRefName);
                 interfaceMgrProvider.updateInterfaceParentRef(newInterfaceName, parentRefName);
             }
-        });
+        }, IfmClusterUtils.INTERFACE_CONFIG_ENTITY);
     }
 
     @Override
index 34813d31b2c3b4109a1c5ff4b70c3826ec84c709..23bbb3949c98c12dd12c9df6f91d754ef20ee6fd 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.genius.interfacemanager.renderer.ovs.confighelpers;
 
+import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.math.BigInteger;
 import java.util.ArrayList;
@@ -112,7 +113,7 @@ public class OvsInterfaceConfigAddHelper {
             createTunnelPort = bridgeEntry == null || bridgeEntry.getBridgeInterfaceEntry() == null ?
                     true : bridgeEntry.getBridgeInterfaceEntry().isEmpty();
             tunnelName = SouthboundUtils.generateOfTunnelName(dpId, ifTunnel);
-            InterfaceManagerCommonUtils.createInterfaceChildEntry(tunnelName, interfaceNew.getName());
+            InterfaceManagerCommonUtils.createInterfaceChildEntry(tunnelName, interfaceNew.getName(), Optional.absent());
         }
 
         LOG.debug("creating bridge interfaceEntry in ConfigDS {}", dpId);
index 95e1cffc8f6e153e2411c0c45793ba7661cd17e6..b0625ddd9e091d15aa428982823581b1042b0418 100644 (file)
@@ -7,10 +7,13 @@
  */
 package org.opendaylight.genius.interfacemanager.renderer.ovs.confighelpers;
 
+import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
 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.interfacemanager.commons.InterfaceManagerCommonUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
@@ -27,8 +30,10 @@ public class OvsVlanMemberConfigAddHelper {
                                                                 IdManagerService idManager) {
         LOG.debug("add vlan member configuration {}",interfaceNew.getName());
         List<ListenableFuture<Void>> futures = new ArrayList<>();
-
-        InterfaceManagerCommonUtils.createInterfaceChildEntry(parentRefs.getParentInterface(), interfaceNew.getName());
+        WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
+        InterfaceManagerCommonUtils.createInterfaceChildEntry(parentRefs.getParentInterface(),
+            interfaceNew.getName(), Optional.of(writeTransaction));
+        futures.add(writeTransaction.submit());
 
         InterfaceKey interfaceKey = new InterfaceKey(parentRefs.getParentInterface());
         Interface ifaceParent = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
index 50e1f35204f63d77b07030d54b5c00ab252ba1f3..b1c0a7d33af363736e1973a4aff7e7a09d169ca0 100644 (file)
@@ -85,7 +85,7 @@ public class OvsInterfaceTopologyStateUpdateHelper {
                 }
                 return futures;
             });
-        });
+        }, IfmClusterUtils.INTERFACE_CONFIG_ENTITY);
         return null;
     }
 
index a52198aa3f2ec0630c84c8d4287b65696a1c4671..ec54e6e6492a8ee9d44c631aa989e971700fd1fe 100644 (file)
@@ -20,7 +20,8 @@ import org.slf4j.LoggerFactory;
 
 public class IfmClusterUtils {
     private static final Logger LOG = LoggerFactory.getLogger(IfmClusterUtils.class);
-    public static final String IFACE_ENTITY = "iface";
+    public static final String INTERFACE_CONFIG_ENTITY = "interface_config";
+    public static final String INTERFACE_SERVICE_BINDING_ENTITY = "interface_service_binding";
 
     private  static InterfacemgrProvider ifaceServiceProvider = null;
 
@@ -32,17 +33,18 @@ public class IfmClusterUtils {
             EntityOwnershipService entityOwnershipService) {
         setIfaceServiceProvider(provider);
         try {
-            EntityOwnerUtils.registerEntityCandidateForOwnerShip(entityOwnershipService,
-                    IFACE_ENTITY, IFACE_ENTITY,
-                    null/*listener*/);
+            EntityOwnerUtils.registerEntityCandidateForOwnerShip(entityOwnershipService, INTERFACE_CONFIG_ENTITY,
+                INTERFACE_CONFIG_ENTITY, null/*listener*/);
+            EntityOwnerUtils.registerEntityCandidateForOwnerShip(entityOwnershipService, INTERFACE_SERVICE_BINDING_ENTITY,
+                INTERFACE_SERVICE_BINDING_ENTITY, null/*listener*/);
         } catch (CandidateAlreadyRegisteredException e) {
-            LOG.error("failed to register the entity, ",IFACE_ENTITY);
+            LOG.error("failed to register entity {} for entity-owenership-service", e.getEntity());
         }
     }
 
-    public static void runOnlyInLeaderNode(final Runnable job) {
+    public static void runOnlyInLeaderNode(final Runnable job, String entity) {
         ListenableFuture<Boolean> checkEntityOwnerFuture = ClusteringUtils.checkNodeEntityOwner(
-            ifaceServiceProvider.getEntityOwnershipService(), IFACE_ENTITY, IFACE_ENTITY);
+            ifaceServiceProvider.getEntityOwnershipService(), entity, entity);
         Futures.addCallback(checkEntityOwnerFuture, new FutureCallback<Boolean>() {
             @Override
             public void onSuccess(Boolean isOwner) {
@@ -50,13 +52,13 @@ public class IfmClusterUtils {
                 if (isOwner) {
                     job.run();
                 } else {
-                    LOG.trace("job is not run as node is not owner for :{} ", IFACE_ENTITY);
+                    LOG.trace("job is not run as node is not owner for :{} ", INTERFACE_CONFIG_ENTITY);
                 }
             }
 
             @Override
             public void onFailure(Throwable error) {
-                LOG.error("Failed to identify owner for entity {} due to {}", IFACE_ENTITY, error);
+                LOG.error("Failed to identify owner for entity {} due to {}", INTERFACE_CONFIG_ENTITY, error);
             }
         });
     }
index 265a0d695ecaf42ab2cb0c61fe391f06f8171656..b048e52f34679879541519285442146f9722953d 100644 (file)
@@ -328,6 +328,7 @@ public class SouthboundUtils {
                 getIfBfdObj(BFD_PARAM_ENABLE, ifTunnel != null ? ifTunnel.isMonitorEnabled().toString() : "false"));
         bfdParams.add(getIfBfdObj(BFD_PARAM_MIN_TX, ifTunnel != null && ifTunnel.getMonitorInterval() != null
                 ? ifTunnel.getMonitorInterval().toString() : BFD_MIN_TX_VAL));
+        bfdParams.add(getIfBfdObj(BFD_FORWARDING_IF_RX_VAL, "true"));
         return bfdParams;
     }
 
index bd3f40cd273e317874e3422101e0b41506718bf0..3609842f7acb0cb084fc8423cdddccc5b711f34b 100644 (file)
@@ -14,12 +14,14 @@ import java.util.Objects;
 import java.util.concurrent.Callable;
 import javax.inject.Inject;
 import javax.inject.Singleton;
+
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
 import org.opendaylight.genius.interfacemanager.IfmConstants;
 import org.opendaylight.genius.interfacemanager.InterfacemgrProvider;
+import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.IfmClusterUtils;
 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.config.factory.FlowBasedServicesConfigAddable;
 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.config.factory.FlowBasedServicesConfigRemovable;
 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.config.factory.FlowBasedServicesRendererFactory;
@@ -28,15 +30,15 @@ import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.config
 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.config.helpers.FlowBasedIngressServicesConfigBindHelper;
 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.config.helpers.FlowBasedIngressServicesConfigUnbindHelper;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfoKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public class FlowBasedServicesConfigListener extends AsyncDataTreeChangeListenerBase<BoundServices, FlowBasedServicesConfigListener> {
+public class FlowBasedServicesConfigListener extends AsyncClusteredDataTreeChangeListenerBase<BoundServices, FlowBasedServicesConfigListener> {
     private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesConfigListener.class);
 
     @Inject
@@ -64,17 +66,18 @@ public class FlowBasedServicesConfigListener extends AsyncDataTreeChangeListener
 
     @Override
     protected void remove(InstanceIdentifier<BoundServices> key, BoundServices boundServiceOld) {
-        String interfaceName = InstanceIdentifier.keyOf(key.firstIdentifierOf(ServicesInfo.class)).getInterfaceName();
-        LOG.info("Service Binding Entry removed for Interface: {}, Data: {}",
-                interfaceName, boundServiceOld);
-        Class<? extends ServiceModeBase> serviceMode = InstanceIdentifier
-                .keyOf(key.firstIdentifierOf(ServicesInfo.class)).getServiceMode();
-        FlowBasedServicesConfigRemovable flowBasedServicesConfigRemovable = FlowBasedServicesRendererFactory
-                .getFlowBasedServicesRendererFactory(serviceMode).                getFlowBasedServicesRemoveRenderer();
-        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
-        RendererConfigRemoveWorker configWorker = new RendererConfigRemoveWorker(flowBasedServicesConfigRemovable, key,
+        IfmClusterUtils.runOnlyInLeaderNode(() -> {
+            ServicesInfoKey serviceKey = InstanceIdentifier.keyOf(key.firstIdentifierOf(ServicesInfo.class));
+            LOG.info("Service Binding Entry removed for Interface: {}, Data: {}", serviceKey.getInterfaceName(),
                 boundServiceOld);
-        coordinator.enqueueJob(interfaceName, configWorker, IfmConstants.JOB_MAX_RETRIES);
+            FlowBasedServicesConfigRemovable flowBasedServicesConfigRemovable =
+                FlowBasedServicesRendererFactory.getFlowBasedServicesRendererFactory(serviceKey.getServiceMode())
+                    .getFlowBasedServicesRemoveRenderer();
+            DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+            RendererConfigRemoveWorker configWorker =
+                new RendererConfigRemoveWorker(flowBasedServicesConfigRemovable, key, boundServiceOld);
+            coordinator.enqueueJob(serviceKey.getInterfaceName(), configWorker, IfmConstants.JOB_MAX_RETRIES);
+        }, IfmClusterUtils.INTERFACE_SERVICE_BINDING_ENTITY);
     }
 
     @Override
@@ -89,18 +92,18 @@ public class FlowBasedServicesConfigListener extends AsyncDataTreeChangeListener
 
     @Override
     protected void add(InstanceIdentifier<BoundServices> key, BoundServices boundServicesNew) {
-        String interfaceName = InstanceIdentifier.keyOf(key.firstIdentifierOf(ServicesInfo.class)).getInterfaceName();
-        LOG.info("Service Binding Entry created for Interface: {}, Data: {}",
-                interfaceName, boundServicesNew);
-        Class<? extends ServiceModeBase> serviceMode = InstanceIdentifier
-                .keyOf(key.firstIdentifierOf(ServicesInfo.class)).getServiceMode();
-
-        FlowBasedServicesConfigAddable flowBasedServicesAddable = FlowBasedServicesRendererFactory
-                .getFlowBasedServicesRendererFactory(serviceMode).getFlowBasedServicesAddRenderer();
-        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
-        RendererConfigAddWorker configWorker = new RendererConfigAddWorker(flowBasedServicesAddable, key,
+        IfmClusterUtils.runOnlyInLeaderNode(() -> {
+            ServicesInfoKey serviceKey = InstanceIdentifier.keyOf(key.firstIdentifierOf(ServicesInfo.class));
+            LOG.info("Service Binding Entry created for Interface: {}, Data: {}", serviceKey.getInterfaceName(),
                 boundServicesNew);
-        coordinator.enqueueJob(interfaceName, configWorker, IfmConstants.JOB_MAX_RETRIES);
+            FlowBasedServicesConfigAddable flowBasedServicesAddable =
+                FlowBasedServicesRendererFactory.getFlowBasedServicesRendererFactory(serviceKey.getServiceMode())
+                    .getFlowBasedServicesAddRenderer();
+            DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+            RendererConfigAddWorker configWorker =
+                new RendererConfigAddWorker(flowBasedServicesAddable, key, boundServicesNew);
+            coordinator.enqueueJob(serviceKey.getInterfaceName(), configWorker, IfmConstants.JOB_MAX_RETRIES);
+        }, IfmClusterUtils.INTERFACE_SERVICE_BINDING_ENTITY);
     }
 
     @Override
index 3b3f29a8920184854f584e3658ce64052ab1e4b5..66b430386bd5d2f949c952e7c882f19dbf9c538d 100644 (file)
@@ -16,10 +16,11 @@ import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
 import org.opendaylight.genius.interfacemanager.IfmConstants;
 import org.opendaylight.genius.interfacemanager.InterfacemgrProvider;
+import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.IfmClusterUtils;
 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.state.factory.FlowBasedServicesStateAddable;
 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.state.factory.FlowBasedServicesStateRemovable;
 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.state.factory.FlowBasedServicesStateRendererFactory;
@@ -36,7 +37,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public class FlowBasedServicesInterfaceStateListener extends AsyncDataTreeChangeListenerBase<Interface, FlowBasedServicesInterfaceStateListener> {
+public class FlowBasedServicesInterfaceStateListener extends AsyncClusteredDataTreeChangeListenerBase<Interface, FlowBasedServicesInterfaceStateListener> {
     private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesInterfaceStateListener.class);
 
     @Inject
@@ -70,16 +71,14 @@ public class FlowBasedServicesInterfaceStateListener extends AsyncDataTreeChange
 
     @Override
     protected void remove(InstanceIdentifier<Interface> key, Interface interfaceStateOld) {
-        LOG.debug("Received interface state remove event for {}", interfaceStateOld.getName());
-        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
-        for(Object serviceMode : FlowBasedServicesUtils.SERVICE_MODE_MAP.values()) {
-            FlowBasedServicesStateRemovable flowBasedServicesStateRemovable = FlowBasedServicesStateRendererFactory.
-                    getFlowBasedServicesStateRendererFactory((Class<? extends ServiceModeBase>) serviceMode).
-                    getFlowBasedServicesStateRemoveRenderer();
-            RendererStateInterfaceUnbindWorker stateUnbindWorker =
-                    new RendererStateInterfaceUnbindWorker(flowBasedServicesStateRemovable, interfaceStateOld);
-            coordinator.enqueueJob(interfaceStateOld.getName(), stateUnbindWorker, IfmConstants.JOB_MAX_RETRIES);
-        }
+        IfmClusterUtils.runOnlyInLeaderNode(() -> {
+            LOG.debug("Received interface state remove event for {}", interfaceStateOld.getName());
+            DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+            FlowBasedServicesUtils.SERVICE_MODE_MAP.values().stream().forEach(serviceMode ->
+                coordinator.enqueueJob(interfaceStateOld.getName(), new RendererStateInterfaceUnbindWorker
+                    (FlowBasedServicesStateRendererFactory.getFlowBasedServicesStateRendererFactory(serviceMode)
+                        .getFlowBasedServicesStateRemoveRenderer(), interfaceStateOld), IfmConstants.JOB_MAX_RETRIES));
+        }, IfmClusterUtils.INTERFACE_SERVICE_BINDING_ENTITY);
     }
 
     @Override
@@ -89,20 +88,14 @@ public class FlowBasedServicesInterfaceStateListener extends AsyncDataTreeChange
 
     @Override
     protected void add(InstanceIdentifier<Interface> key, Interface interfaceStateNew) {
-        if (interfaceStateNew.getOperStatus() == Interface.OperStatus.Down) {
-            LOG.info("Interface: {} operstate is down when adding. Not Binding services", interfaceStateNew.getName());
-            return;
-        }
-        LOG.debug("Received interface state add event for {}", interfaceStateNew.getName());
-        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
-        for(Object serviceMode : FlowBasedServicesUtils.SERVICE_MODE_MAP.values()) {
-            FlowBasedServicesStateAddable flowBasedServicesStateAddable = FlowBasedServicesStateRendererFactory.
-                    getFlowBasedServicesStateRendererFactory((Class<? extends ServiceModeBase>) serviceMode).
-                    getFlowBasedServicesStateAddRenderer();
-            RendererStateInterfaceBindWorker stateBindWorker = new RendererStateInterfaceBindWorker(flowBasedServicesStateAddable,
-                    interfaceStateNew);
-            coordinator.enqueueJob(interfaceStateNew.getName(), stateBindWorker, IfmConstants.JOB_MAX_RETRIES);
-        }
+        IfmClusterUtils.runOnlyInLeaderNode(() -> {
+            LOG.debug("Received interface state add event for {}", interfaceStateNew.getName());
+            DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+            FlowBasedServicesUtils.SERVICE_MODE_MAP.values().stream().forEach(serviceMode ->
+                coordinator.enqueueJob(interfaceStateNew.getName(), new RendererStateInterfaceBindWorker
+                    (FlowBasedServicesStateRendererFactory.getFlowBasedServicesStateRendererFactory(serviceMode)
+                        .getFlowBasedServicesStateAddRenderer(), interfaceStateNew), IfmConstants.JOB_MAX_RETRIES));
+        }, IfmClusterUtils.INTERFACE_SERVICE_BINDING_ENTITY);
     }
 
     @Override
index a06708d536c4d78720b82e8b204e048feb22571f..d740b96a4f7f2ededd76a0650f936cc8a4e83ba3 100644 (file)
@@ -13,6 +13,7 @@ import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collections;
 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.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -79,11 +80,11 @@ public class FlowBasedServicesUtils {
         EGRESS
     }
 
-    public static final ImmutableBiMap SERVICE_MODE_MAP =
-            new ImmutableBiMap.Builder<ServiceMode, Class<? extends ServiceModeBase>>()
-                    .put(ServiceMode.EGRESS, ServiceModeEgress.class)
-                    .put(ServiceMode.INGRESS, ServiceModeIngress.class)
-                    .build();
+    public static final ImmutableBiMap<ServiceMode, Class<? extends ServiceModeBase>> SERVICE_MODE_MAP =
+        new ImmutableBiMap.Builder<ServiceMode, Class<? extends ServiceModeBase>>()
+            .put(ServiceMode.EGRESS, ServiceModeEgress.class)
+            .put(ServiceMode.INGRESS, ServiceModeIngress.class)
+            .build();
 
     public static ServicesInfo getServicesInfoForInterface(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
                                                            DataBroker dataBroker) {