More elan Blueprint clean-up
[netvirt.git] / vpnservice / elanmanager / elanmanager-impl / src / main / java / org / opendaylight / netvirt / elan / l2gw / utils / ElanL2GatewayUtils.java
index 10bfbddec906b605e249f7489d78b8c9a41dd081..42a7b8ae3515dd33946cecbd25691cc13038aa76 100644 (file)
@@ -7,6 +7,11 @@
  */
 package org.opendaylight.netvirt.elan.l2gw.utils;
 
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -15,37 +20,52 @@ import java.util.Objects;
 import java.util.Set;
 import java.util.Timer;
 import java.util.TimerTask;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
-
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
 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.clustering.EntityOwnershipService;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.elanmanager.utils.ElanL2GwCacheUtils;
+import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.genius.interfacemanager.IfmUtil;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.utils.SystemPropertyReader;
+import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
+import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
+import org.opendaylight.genius.utils.hwvtep.HwvtepUtils;
 import org.opendaylight.netvirt.elan.l2gw.jobs.DeleteL2GwDeviceMacsFromElanJob;
-import org.opendaylight.netvirt.elan.l2gw.jobs.LogicalSwitchDeletedJob;
-import org.opendaylight.netvirt.elan.l2gw.listeners.HwvtepPhysicalLocatorListener;
+import org.opendaylight.netvirt.elan.l2gw.jobs.DeleteLogicalSwitchJob;
+import org.opendaylight.netvirt.elan.l2gw.listeners.HwvtepTerminationPointListener;
 import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
 import org.opendaylight.netvirt.elan.utils.ElanConstants;
 import org.opendaylight.netvirt.elan.utils.ElanUtils;
-import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
-import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
-import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.netvirt.elanmanager.utils.ElanL2GwCacheUtils;
 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice;
-import org.opendaylight.vpnservice.utils.SystemPropertyReader;
-import org.opendaylight.vpnservice.utils.hwvtep.HwvtepSouthboundConstants;
-import org.opendaylight.vpnservice.utils.hwvtep.HwvtepSouthboundUtils;
-import org.opendaylight.vpnservice.utils.hwvtep.HwvtepUtils;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
 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;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwDeviceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.forwarding.tables.MacTable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.attributes.Devices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
@@ -57,92 +77,55 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hw
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindings;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTable;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.AddL2GwDeviceInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetExternalTunnelInterfaceNameInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetExternalTunnelInterfaceNameOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.ItmRpcService;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
 /**
- * It gathers a set of utility methods that handle ELAN configuration in external Devices (where external means
- * "not-CSS". As of now: TORs).
+ * It gathers a set of utility methods that handle ELAN configuration in
+ * external Devices (where external means "not-CSS". As of now: TORs).
  *
- * It makes use of HwvtepUtils class located under ovsdb/hwvtepsouthbound project for low-level mdsal operations
+ * <p>It makes use of HwvtepUtils class located under ovsdb/hwvtepsouthbound
+ * project for low-level mdsal operations
  *
  * @author eperefr
- *
  */
 public class ElanL2GatewayUtils {
-    private static DataBroker broker;
-    private static ItmRpcService itmRpcService;
-    private static DataStoreJobCoordinator dataStoreJobCoordinator;
-    private static Timer LogicalSwitchDeleteJobTimer = new Timer();
-    private static final int LOGICAL_SWITCH_DELETE_DELAY = 120000;
-    private static ConcurrentMap<Pair<NodeId, String>, TimerTask> LogicalSwitchDeletedTasks =
-            new ConcurrentHashMap<Pair<NodeId, String>, TimerTask>();
-
     private static final Logger LOG = LoggerFactory.getLogger(ElanL2GatewayUtils.class);
 
-    /**
-     * Sets the data broker.
-     *
-     * @param dataBroker
-     *            the new data broker
-     */
-    public static void setDataBroker(DataBroker dataBroker) {
-        broker = dataBroker;
-    }
+    private final DataBroker broker;
+    private final ItmRpcService itmRpcService;
+    private final ElanUtils elanUtils;
+    private final EntityOwnershipService entityOwnershipService;
+    private final ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils;
 
-    /**
-     * Sets the itm rpc service.
-     *
-     * @param itmRpc
-     *            the new itm rpc service
-     */
-    public static void setItmRpcService(ItmRpcService itmRpc) {
-        itmRpcService = itmRpc;
+    private final DataStoreJobCoordinator dataStoreJobCoordinator = DataStoreJobCoordinator.getInstance();
+    private static Timer LogicalSwitchDeleteJobTimer = new Timer();
+    private static final int LOGICAL_SWITCH_DELETE_DELAY = 120000;
+    private final ConcurrentMap<Pair<NodeId, String>, TimerTask> logicalSwitchDeletedTasks = new ConcurrentHashMap<>();
+
+    public ElanL2GatewayUtils(DataBroker broker, ItmRpcService itmRpcService, ElanUtils elanUtils,
+                              EntityOwnershipService entityOwnershipService,
+                              ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils) {
+        this.broker = broker;
+        this.itmRpcService = itmRpcService;
+        this.elanUtils = elanUtils;
+        this.entityOwnershipService = entityOwnershipService;
+        this.elanL2GatewayMulticastUtils = elanL2GatewayMulticastUtils;
     }
 
     /**
-     * Sets DataStoreJobCoordinator
+     * Installs dpn macs in external device. first it checks if the physical
+     * locator towards this dpn tep is present or not if the physical locator is
+     * present go ahead and add the ucast macs otherwise update the mcast mac
+     * entry to include this dpn tep ip and schedule the job to put ucast macs
+     * once the physical locator is programmed in device
      *
-     * @param dsJobCoordinator
-     *            the new dataStoreJobCoordinator
-     */
-    public static void setDataStoreJobCoordinator(DataStoreJobCoordinator dsJobCoordinator) {
-        dataStoreJobCoordinator = dsJobCoordinator;
-    }
-
-    /**
-     * Installs dpn macs in external device.
-     * first it checks if the physical locator towards this dpn tep is present or not
-     * if the physical locator is present go ahead and add the ucast macs
-     * otherwise update the mcast mac entry to include this dpn tep ip
-     * and schedule the job to put ucast macs once the physical locator is programmed in device
      * @param elanName
      *            the elan name
      * @param lstElanInterfaceNames
@@ -152,8 +135,8 @@ public class ElanL2GatewayUtils {
      * @param externalNodeId
      *            the external node id
      */
-    public static void installDpnMacsInL2gwDevice(String elanName,  Set<String> lstElanInterfaceNames,
-                                                  BigInteger dpnId, NodeId externalNodeId) {
+    public void installDpnMacsInL2gwDevice(String elanName, Set<String> lstElanInterfaceNames, BigInteger dpnId,
+            NodeId externalNodeId) {
         L2GatewayDevice elanL2GwDevice = ElanL2GwCacheUtils.getL2GatewayDeviceFromCache(elanName,
                 externalNodeId.getValue());
         if (elanL2GwDevice == null) {
@@ -162,8 +145,8 @@ public class ElanL2GatewayUtils {
         }
         IpAddress dpnTepIp = getSourceDpnTepIp(dpnId, externalNodeId);
         if (dpnTepIp == null) {
-            LOG.warn("Could not install dpn macs in l2gw device , dpnTepIp not found dpn : {} , nodeid : {}",
-                    dpnId, externalNodeId);
+            LOG.warn("Could not install dpn macs in l2gw device , dpnTepIp not found dpn : {} , nodeid : {}", dpnId,
+                    externalNodeId);
             return;
         }
 
@@ -181,21 +164,21 @@ public class ElanL2GatewayUtils {
             scheduleAddDpnMacsInExtDevice(elanName, dpnId, staticMacs, elanL2GwDevice);
             return;
         }
-        ElanL2GatewayMulticastUtils.scheduleMcastMacUpdateJob(elanName, elanL2GwDevice);
+        elanL2GatewayMulticastUtils.scheduleMcastMacUpdateJob(elanName, elanL2GwDevice);
         scheduleAddDpnMacsInExtDevice(elanName, dpnId, staticMacs, elanL2GwDevice);
     }
 
     /**
-     * gets the macs addresses for elan interfaces
+     * gets the macs addresses for elan interfaces.
      *
      * @param lstElanInterfaceNames
      *            the lst elan interface names
      * @return the list
      */
-    private static List<PhysAddress> getElanDpnMacsFromInterfaces(Set<String> lstElanInterfaceNames) {
+    private List<PhysAddress> getElanDpnMacsFromInterfaces(Set<String> lstElanInterfaceNames) {
         List<PhysAddress> result = new ArrayList<>();
         for (String interfaceName : lstElanInterfaceNames) {
-            ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
+            ElanInterfaceMac elanInterfaceMac = elanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
             if (elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
                 for (MacEntry macEntry : elanInterfaceMac.getMacEntry()) {
                     result.add(macEntry.getMacAddress());
@@ -246,8 +229,8 @@ public class ElanL2GatewayUtils {
      *            the datastore type
      * @return the remote mcast mac
      */
-    public static RemoteMcastMacs readRemoteMcastMac(NodeId nodeId, String logicalSwitchName,
-                                                     LogicalDatastoreType datastoreType) {
+    public RemoteMcastMacs readRemoteMcastMac(NodeId nodeId, String logicalSwitchName,
+            LogicalDatastoreType datastoreType) {
         InstanceIdentifier<LogicalSwitches> logicalSwitch = HwvtepSouthboundUtils
                 .createLogicalSwitchesInstanceIdentifier(nodeId, new HwvtepNodeName(logicalSwitchName));
         RemoteMcastMacsKey remoteMcastMacsKey = new RemoteMcastMacsKey(new HwvtepLogicalSwitchRef(logicalSwitch),
@@ -266,7 +249,7 @@ public class ElanL2GatewayUtils {
      * @param macAddresses
      *            the mac addresses
      */
-    public static void removeMacsFromElanExternalDevices(ElanInstance elanInstance, List<PhysAddress> macAddresses) {
+    public void removeMacsFromElanExternalDevices(ElanInstance elanInstance, List<PhysAddress> macAddresses) {
         ConcurrentMap<String, L2GatewayDevice> elanL2GwDevices = ElanL2GwCacheUtils
                 .getInvolvedL2GwDevices(elanInstance.getElanInstanceName());
         for (L2GatewayDevice l2GatewayDevice : elanL2GwDevices.values()) {
@@ -280,34 +263,29 @@ public class ElanL2GatewayUtils {
      *
      * @param deviceNodeId
      *            the device node id
-     * @param logicalSwitchName
      * @param macAddresses
      *            the mac addresses
      * @return the listenable future
      */
-    private static ListenableFuture<Void> removeRemoteUcastMacsFromExternalDevice(String deviceNodeId,
+    private ListenableFuture<Void> removeRemoteUcastMacsFromExternalDevice(String deviceNodeId,
             String logicalSwitchName, List<PhysAddress> macAddresses) {
         NodeId nodeId = new NodeId(deviceNodeId);
 
         // TODO (eperefr)
-        List<MacAddress> lstMac = Lists.transform(macAddresses, new Function<PhysAddress, MacAddress>() {
-            @Override
-            public MacAddress apply(PhysAddress physAddress) {
-                return (physAddress != null) ? new MacAddress(physAddress.getValue()) : null;
-            }
-        });
+        List<MacAddress> lstMac = Lists.transform(macAddresses,
+            physAddress -> physAddress != null ? new MacAddress(physAddress.getValue()) : null);
         return HwvtepUtils.deleteRemoteUcastMacs(broker, nodeId, logicalSwitchName, lstMac);
     }
 
-    public static ElanInstance getElanInstanceForUcastLocalMac(LocalUcastMacs localUcastMac) {
-        Optional<LogicalSwitches> lsOpc = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL,
+    public ElanInstance getElanInstanceForUcastLocalMac(LocalUcastMacs localUcastMac) {
+        Optional<LogicalSwitches> lsOpc = elanUtils.read(broker, LogicalDatastoreType.OPERATIONAL,
                 (InstanceIdentifier<LogicalSwitches>) localUcastMac.getLogicalSwitchRef().getValue());
         if (lsOpc.isPresent()) {
             LogicalSwitches ls = lsOpc.get();
             if (ls != null) {
                 // Logical switch name is Elan name
                 String elanName = getElanFromLogicalSwitch(ls.getHwvtepNodeName().getValue());
-                return ElanUtils.getElanInstanceByName(elanName);
+                return ElanUtils.getElanInstanceByName(broker, elanName);
             } else {
                 String macAddress = localUcastMac.getMacEntryKey().getValue();
                 LOG.error("Could not find logical_switch for {} being added/deleted", macAddress);
@@ -325,8 +303,11 @@ public class ElanL2GatewayUtils {
      *            the l2gw device node id
      * @param elan
      *            the elan
+     * @param interfaceName
+     *            the interface name
      */
-    public static void installL2gwDeviceMacsInDpn(BigInteger dpnId, NodeId l2gwDeviceNodeId, ElanInstance elan) {
+    public void installL2gwDeviceMacsInDpn(BigInteger dpnId, NodeId l2gwDeviceNodeId, ElanInstance elan,
+            String interfaceName) {
         L2GatewayDevice l2gwDevice = ElanL2GwCacheUtils.getL2GatewayDeviceFromCache(elan.getElanInstanceName(),
                 l2gwDeviceNodeId.getValue());
         if (l2gwDevice == null) {
@@ -334,7 +315,7 @@ public class ElanL2GatewayUtils {
             return;
         }
 
-        installDmacFlowsOnDpn(dpnId, l2gwDevice, elan);
+        installDmacFlowsOnDpn(dpnId, l2gwDevice, elan, interfaceName);
     }
 
     /**
@@ -346,16 +327,19 @@ public class ElanL2GatewayUtils {
      *            the l2gw device
      * @param elan
      *            the elan
+     * @param interfaceName
+     *            the interface name
      */
-    public static void installDmacFlowsOnDpn(BigInteger dpnId, L2GatewayDevice l2gwDevice, ElanInstance elan) {
+    public void installDmacFlowsOnDpn(BigInteger dpnId, L2GatewayDevice l2gwDevice, ElanInstance elan,
+            String interfaceName) {
         String elanName = elan.getElanInstanceName();
 
         List<LocalUcastMacs> l2gwDeviceLocalMacs = l2gwDevice.getUcastLocalMacs();
         if (l2gwDeviceLocalMacs != null && !l2gwDeviceLocalMacs.isEmpty()) {
             for (LocalUcastMacs localUcastMac : l2gwDeviceLocalMacs) {
-                //TODO batch these ops
-                ElanUtils.installDmacFlowsToExternalRemoteMac(dpnId, l2gwDevice.getHwvtepNodeId(), elan.getElanTag(),
-                        elan.getVni(), localUcastMac.getMacEntryKey().getValue(), elanName);
+                // TODO batch these ops
+                elanUtils.installDmacFlowsToExternalRemoteMac(dpnId, l2gwDevice.getHwvtepNodeId(), elan.getElanTag(),
+                        elan.getSegmentationId(), localUcastMac.getMacEntryKey().getValue(), elanName, interfaceName);
             }
             LOG.debug("Installing L2gw device [{}] local macs [size: {}] in dpn [{}] for elan [{}]",
                     l2gwDevice.getHwvtepNodeId(), l2gwDeviceLocalMacs.size(), dpnId, elanName);
@@ -369,88 +353,111 @@ public class ElanL2GatewayUtils {
      *            the dpn id
      * @param elan
      *            the elan
+     * @param interfaceName
+     *            the interface name
      */
-    public static void installElanL2gwDevicesLocalMacsInDpn(BigInteger dpnId, ElanInstance elan) {
+    public void installElanL2gwDevicesLocalMacsInDpn(BigInteger dpnId, ElanInstance elan, String interfaceName) {
         ConcurrentMap<String, L2GatewayDevice> elanL2GwDevicesFromCache = ElanL2GwCacheUtils
                 .getInvolvedL2GwDevices(elan.getElanInstanceName());
         if (elanL2GwDevicesFromCache != null) {
             for (L2GatewayDevice l2gwDevice : elanL2GwDevicesFromCache.values()) {
-                installDmacFlowsOnDpn(dpnId, l2gwDevice, elan);
+                installDmacFlowsOnDpn(dpnId, l2gwDevice, elan, interfaceName);
             }
         } else {
             LOG.debug("No Elan l2 gateway devices in cache for [{}] ", elan.getElanInstanceName());
         }
     }
 
-    public static void installL2GwUcastMacInElan(final ElanInstance elan,
-            final L2GatewayDevice extL2GwDevice, final String macToBeAdded) {
+    public void installL2GwUcastMacInElan(final ElanInstance elan, final L2GatewayDevice extL2GwDevice,
+            final String macToBeAdded, String interfaceName) {
         final String extDeviceNodeId = extL2GwDevice.getHwvtepNodeId();
         final String elanInstanceName = elan.getElanInstanceName();
 
-        // Retrieve all participating DPNs in this Elan. Populate this MAC in DMAC table.
-        // Looping through all DPNs in order to add/remove mac flows in their DMAC table
-        final List<DpnInterfaces> elanDpns = ElanUtils.getInvolvedDpnsInElan(elanInstanceName);
+        // Retrieve all participating DPNs in this Elan. Populate this MAC in
+        // DMAC table.
+        // Looping through all DPNs in order to add/remove mac flows in their
+        // DMAC table
+        final List<DpnInterfaces> elanDpns = elanUtils.getInvolvedDpnsInElan(elanInstanceName);
         if (elanDpns != null && elanDpns.size() > 0) {
             String jobKey = elan.getElanInstanceName() + ":" + macToBeAdded;
-            ElanClusterUtils.runOnlyInLeaderNode(jobKey,
-                    "install l2gw mcas in dmac table",
-                    new Callable<List<ListenableFuture<Void>>>() {
-                        @Override
-                        public List<ListenableFuture<Void>> call() throws Exception {
-                            List<ListenableFuture<Void>> fts = Lists.newArrayList();
-                            for (DpnInterfaces elanDpn : elanDpns) {
-                                //TODO batch the below call
-                                fts.addAll(ElanUtils.installDmacFlowsToExternalRemoteMac(elanDpn.getDpId(),
-                                        extDeviceNodeId, elan.getElanTag(), elan.getVni(), macToBeAdded,
-                                        elanInstanceName));
-                            }
-                            return fts;
+            ElanClusterUtils.runOnlyInLeaderNode(entityOwnershipService, jobKey, "install l2gw macs in dmac table",
+                () -> {
+                    List<ListenableFuture<Void>> fts = Lists.newArrayList();
+                    if (doesLocalUcastMacExistsInCache(extL2GwDevice, macToBeAdded)) {
+                        for (DpnInterfaces elanDpn : elanDpns) {
+                            // TODO batch the below call
+                            fts.addAll(elanUtils.installDmacFlowsToExternalRemoteMac(elanDpn.getDpId(),
+                                    extDeviceNodeId, elan.getElanTag(), elan.getSegmentationId(), macToBeAdded,
+                                    elanInstanceName, interfaceName));
                         }
-                    });
+                    } else {
+                        LOG.trace("Skipping install of dmac flows for mac {} as it is not found in cache",
+                                macToBeAdded);
+                    }
+                    return fts;
+                });
         }
         final IpAddress extL2GwDeviceTepIp = extL2GwDevice.getTunnelIp();
-        final List<PhysAddress> macList = new ArrayList<PhysAddress>();
+        final List<PhysAddress> macList = new ArrayList<>();
         macList.add(new PhysAddress(macToBeAdded));
 
-        String jobKey = "hwvtep:"+elan.getElanInstanceName() + ":" + macToBeAdded;
-        ElanClusterUtils.runOnlyInLeaderNode(jobKey,
-                "install remote ucast macs in l2gw device",
-                new Callable<List<ListenableFuture<Void>>>() {
-                    @Override
-                    public List<ListenableFuture<Void>> call() throws Exception {
-                        ConcurrentMap<String, L2GatewayDevice> elanL2GwDevices =
-                                ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanInstanceName);
-
-                        List<ListenableFuture<Void>>  fts = Lists.newArrayList();
-                        for (L2GatewayDevice otherDevice : elanL2GwDevices.values()) {
-                            if (!otherDevice.getHwvtepNodeId().equals(extDeviceNodeId)
-                                    && !areMLAGDevices(extL2GwDevice, otherDevice)) {
-                                final String hwvtepId = otherDevice.getHwvtepNodeId();
-                                InstanceIdentifier<Node> iid = HwvtepSouthboundUtils.createInstanceIdentifier(
-                                        new NodeId(hwvtepId));
-                                final String logicalSwitchName = elanInstanceName;
-
-                                ListenableFuture<Void> ft = HwvtepUtils.installUcastMacs(
-                                        broker, hwvtepId, macList, logicalSwitchName, extL2GwDeviceTepIp);
-                                //TODO batch the above call
-                                Futures.addCallback(ft, new FutureCallback<Void>() {
-                                    @Override
-                                    public void onSuccess(Void noarg) {
-                                        LOG.trace("Successful in initiating ucast_remote_macs addition" +
-                                                "related to {} in {}", logicalSwitchName, hwvtepId);
-                                    }
-
-                                    @Override
-                                    public void onFailure(Throwable error) {
-                                        LOG.error(String.format("Failed adding ucast_remote_macs related to " +
-                                                "%s in %s", logicalSwitchName, hwvtepId), error);
-                                    };
-                                });
-                                fts.add(ft);
+        String jobKey = "hwvtep:" + elan.getElanInstanceName() + ":" + macToBeAdded;
+        ElanClusterUtils.runOnlyInLeaderNode(entityOwnershipService, jobKey, "install remote ucast macs in l2gw device",
+            () -> {
+                List<ListenableFuture<Void>> fts = Lists.newArrayList();
+                if (!doesLocalUcastMacExistsInCache(extL2GwDevice, macToBeAdded)) {
+                    LOG.trace(
+                            "Skipping install of remote ucast macs {} in l2gw device as it is not found in cache",
+                            macToBeAdded);
+                    return fts;
+                }
+                ConcurrentMap<String, L2GatewayDevice> elanL2GwDevices = ElanL2GwCacheUtils
+                        .getInvolvedL2GwDevices(elanInstanceName);
+                for (L2GatewayDevice otherDevice : elanL2GwDevices.values()) {
+                    if (!otherDevice.getHwvtepNodeId().equals(extDeviceNodeId)
+                            && !areMLAGDevices(extL2GwDevice, otherDevice)) {
+                        final String hwvtepId = otherDevice.getHwvtepNodeId();
+                        InstanceIdentifier<Node> iid = HwvtepSouthboundUtils
+                                .createInstanceIdentifier(new NodeId(hwvtepId));
+                        final String logicalSwitchName = elanInstanceName;
+
+                        ListenableFuture<Void> ft = HwvtepUtils.installUcastMacs(broker, hwvtepId, macList,
+                                logicalSwitchName, extL2GwDeviceTepIp);
+                        // TODO batch the above call
+                        Futures.addCallback(ft, new FutureCallback<Void>() {
+                            @Override
+                            public void onSuccess(Void noarg) {
+                                LOG.trace("Successful in initiating ucast_remote_macs addition"
+                                        + "related to {} in {}", logicalSwitchName, hwvtepId);
                             }
-                        }
-                        return fts;
-                    }});
+
+                            @Override
+                            public void onFailure(Throwable error) {
+                                LOG.error(String.format(
+                                        "Failed adding ucast_remote_macs related to " + "%s in %s",
+                                        logicalSwitchName, hwvtepId), error);
+                            }
+                        });
+                        fts.add(ft);
+                    }
+                }
+                return fts;
+            });
+    }
+
+    /**
+     * Does local ucast mac exists in cache.
+     *
+     * @param elanL2GwDevice
+     *            the elan L2 Gw device
+     * @param macAddress
+     *            the mac address to be verified
+     * @return true, if successful
+     */
+    private static boolean doesLocalUcastMacExistsInCache(L2GatewayDevice elanL2GwDevice, String macAddress) {
+        java.util.Optional<LocalUcastMacs> macExistsInCache = elanL2GwDevice.getUcastLocalMacs().stream()
+                .filter(mac -> mac.getMacEntryKey().getValue().equalsIgnoreCase(macAddress)).findFirst();
+        return macExistsInCache.isPresent();
     }
 
     /**
@@ -463,7 +470,7 @@ public class ElanL2GatewayUtils {
      * @param macAddresses
      *            the mac addresses
      */
-    public static void unInstallL2GwUcastMacFromElan(final ElanInstance elan, final L2GatewayDevice l2GwDevice,
+    public void unInstallL2GwUcastMacFromElan(final ElanInstance elan, final L2GatewayDevice l2GwDevice,
             final List<MacAddress> macAddresses) {
         if (macAddresses == null || macAddresses.isEmpty()) {
             return;
@@ -474,29 +481,27 @@ public class ElanL2GatewayUtils {
         // DMAC table. Looping through all DPNs in order to add/remove mac flows
         // in their DMAC table
         for (final MacAddress mac : macAddresses) {
-            final List<DpnInterfaces> elanDpns = ElanUtils.getInvolvedDpnsInElan(elanName);
+            final List<DpnInterfaces> elanDpns = elanUtils.getInvolvedDpnsInElan(elanName);
             if (elanDpns != null && !elanDpns.isEmpty()) {
                 String jobKey = elanName + ":" + mac.getValue();
-                ElanClusterUtils.runOnlyInLeaderNode(jobKey, "delete l2gw macs from dmac table",
-                        new Callable<List<ListenableFuture<Void>>>() {
-                            @Override
-                            public List<ListenableFuture<Void>> call() {
-                                List<ListenableFuture<Void>> fts = Lists.newArrayList();
-                                for (DpnInterfaces elanDpn : elanDpns) {
-                                    BigInteger dpnId = elanDpn.getDpId();
-                                    // never batch deletes
-                                    fts.addAll(ElanUtils.deleteDmacFlowsToExternalMac(elan.getElanTag(), dpnId,
-                                            l2GwDevice.getHwvtepNodeId(), mac.getValue()));
-                                }
-                                return fts;
-                            }
-                        });
+                ElanClusterUtils.runOnlyInLeaderNode(entityOwnershipService, jobKey, "delete l2gw macs from dmac table",
+                    () -> {
+                        List<ListenableFuture<Void>> fts = Lists.newArrayList();
+                        for (DpnInterfaces elanDpn : elanDpns) {
+                            BigInteger dpnId = elanDpn.getDpId();
+                            // never batch deletes
+                            fts.addAll(elanUtils.deleteDmacFlowsToExternalMac(elan.getElanTag(), dpnId,
+                                    l2GwDevice.getHwvtepNodeId(), mac.getValue()));
+                        }
+                        return fts;
+                    });
             }
         }
 
         DeleteL2GwDeviceMacsFromElanJob job = new DeleteL2GwDeviceMacsFromElanJob(broker, elanName, l2GwDevice,
                 macAddresses);
-        ElanClusterUtils.runOnlyInLeaderNode(job.getJobKey(), "delete remote ucast macs in l2gw devices", job);
+        ElanClusterUtils.runOnlyInLeaderNode(entityOwnershipService, job.getJobKey(),
+                "delete remote ucast macs in l2gw devices", job);
     }
 
     /**
@@ -507,13 +512,13 @@ public class ElanL2GatewayUtils {
      * @param dpnId
      *            the dpn id
      */
-    public static void deleteElanL2GwDevicesUcastLocalMacsFromDpn(final String elanName, final BigInteger dpnId) {
+    public void deleteElanL2GwDevicesUcastLocalMacsFromDpn(final String elanName, final BigInteger dpnId) {
         ConcurrentMap<String, L2GatewayDevice> elanL2GwDevices = ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanName);
         if (elanL2GwDevices == null || elanL2GwDevices.isEmpty()) {
             LOG.trace("No L2 gateway devices in Elan [{}] cache.", elanName);
             return;
         }
-        final ElanInstance elan = ElanUtils.getElanInstanceByName(elanName);
+        final ElanInstance elan = ElanUtils.getElanInstanceByName(broker, elanName);
         if (elan == null) {
             LOG.error("Could not find Elan by name: {}", elanName);
             return;
@@ -526,17 +531,14 @@ public class ElanL2GatewayUtils {
             if (localMacs != null && !localMacs.isEmpty()) {
                 for (final MacAddress mac : localMacs) {
                     String jobKey = elanName + ":" + mac.getValue();
-                    ElanClusterUtils.runOnlyInLeaderNode(jobKey, "delete l2gw macs from dmac table",
-                            new Callable<List<ListenableFuture<Void>>>() {
-                                @Override
-                                public List<ListenableFuture<Void>> call() {
-                                    List<ListenableFuture<Void>> futures = Lists.newArrayList();
-
-                                    futures.addAll(ElanUtils.deleteDmacFlowsToExternalMac(elanTag, dpnId,
-                                            l2GwDevice.getHwvtepNodeId(), mac.getValue()));
-                                    return futures;
-                                }
-                            });
+                    ElanClusterUtils.runOnlyInLeaderNode(entityOwnershipService, jobKey,
+                            "delete l2gw macs from dmac table", () -> {
+                            List<ListenableFuture<Void>> futures = Lists.newArrayList();
+
+                            futures.addAll(elanUtils.deleteDmacFlowsToExternalMac(elanTag, dpnId,
+                                    l2GwDevice.getHwvtepNodeId(), mac.getValue()));
+                            return futures;
+                        });
                 }
             }
         }
@@ -556,12 +558,8 @@ public class ElanL2GatewayUtils {
         }
         List<LocalUcastMacs> lstUcastLocalMacs = l2gwDevice.getUcastLocalMacs();
         if (lstUcastLocalMacs != null && !lstUcastLocalMacs.isEmpty()) {
-            macs = Lists.transform(lstUcastLocalMacs, new Function<LocalUcastMacs, MacAddress>() {
-                @Override
-                public MacAddress apply(LocalUcastMacs localUcastMac) {
-                    return (localUcastMac != null) ? localUcastMac.getMacEntryKey() : null;
-                }
-            });
+            macs = Lists.transform(lstUcastLocalMacs,
+                localUcastMac -> localUcastMac != null ? localUcastMac.getMacEntryKey() : null);
         }
         return macs;
     }
@@ -577,73 +575,71 @@ public class ElanL2GatewayUtils {
      *            the elan name
      * @return the listenable future
      */
-    public static ListenableFuture<Void> deleteElanMacsFromL2GatewayDevice(L2GatewayDevice l2GatewayDevice,
+    public ListenableFuture<Void> deleteElanMacsFromL2GatewayDevice(L2GatewayDevice l2GatewayDevice,
             String elanName) {
-        List<MacAddress> elanMacTableEntries = getElanMacTableEntries(elanName);
-        List<MacAddress> elanL2GatewayDevicesLocalMacs = getElanL2GatewayDevicesLocalMacs(l2GatewayDevice, elanName);
+        String hwvtepNodeId = l2GatewayDevice.getHwvtepNodeId();
+        String logicalSwitch = getLogicalSwitchFromElan(elanName);
 
-        List<MacAddress> lstElanLocalMacs = new ArrayList<>(elanMacTableEntries);
-        lstElanLocalMacs.addAll(elanL2GatewayDevicesLocalMacs);
+        List<MacAddress> lstElanMacs = getRemoteUcastMacs(new NodeId(hwvtepNodeId), logicalSwitch,
+                LogicalDatastoreType.CONFIGURATION);
+        ListenableFuture<Void> future = HwvtepUtils.deleteRemoteUcastMacs(broker, new NodeId(hwvtepNodeId),
+                logicalSwitch, lstElanMacs);
 
-        return HwvtepUtils.deleteRemoteUcastMacs(broker, new NodeId(l2GatewayDevice.getHwvtepNodeId()),
-                elanName, lstElanLocalMacs);
-    }
+        Futures.addCallback(future, new FutureCallback<Void>() {
+            @Override
+            public void onSuccess(Void noarg) {
+                LOG.trace("Successful in batch deletion of elan [{}] macs from l2gw device [{}]", elanName,
+                        hwvtepNodeId);
+            }
 
-    /**
-     * Gets the elan mac table entries.
-     *
-     * @param elanName
-     *            the elan name
-     * @return the elan mac table entries as list
-     */
-    public static List<MacAddress> getElanMacTableEntries(String elanName) {
-        MacTable macTable = ElanUtils.getElanMacTable(elanName);
-        if (macTable == null || macTable.getMacEntry() == null || macTable.getMacEntry().isEmpty()) {
-            LOG.trace("MacTable is empty for elan: {}", elanName);
-            return Collections.emptyList();
-        }
-        List<MacAddress> lstMacs = Lists.transform(macTable.getMacEntry(), new Function<MacEntry, MacAddress>() {
             @Override
-            public MacAddress apply(MacEntry macEntry) {
-                return (macEntry != null) ? new MacAddress(macEntry.getMacAddress().getValue()) : null;
+            public void onFailure(Throwable error) {
+                LOG.warn(String.format("Failed during batch delete of elan [%s] macs from l2gw device [%s]. "
+                        + "Retrying with sequential deletes.", elanName, hwvtepNodeId), error);
+                if (lstElanMacs != null && !lstElanMacs.isEmpty()) {
+                    for (MacAddress mac : lstElanMacs) {
+                        HwvtepUtils.deleteRemoteUcastMac(broker, new NodeId(hwvtepNodeId), logicalSwitch, mac);
+                    }
+                }
             }
         });
-        return lstMacs;
+
+        if (LOG.isDebugEnabled()) {
+            List<String> elanMacs = lstElanMacs.stream().map(mac -> mac.getValue()).collect(Collectors.toList());
+            LOG.debug("Deleting elan [{}] macs from node [{}]. Deleted macs = {}", elanName, hwvtepNodeId, elanMacs);
+        }
+        return future;
     }
 
     /**
-     * Gets the elan l2 gateway devices local macs.
+     * Gets the remote ucast macs from hwvtep node filtering based on logical
+     * switch.
      *
-     * @param l2GwDeviceToBeExcluded
-     *            the l2 gw device to be excluded
-     * @param elanName
-     *            the elan name
-     * @return the elan l2 gateway devices local macs
+     * @param hwvtepNodeId
+     *            the hwvtep node id
+     * @param logicalSwitch
+     *            the logical switch
+     * @param datastoreType
+     *            the datastore type
+     * @return the remote ucast macs
      */
-    public static List<MacAddress> getElanL2GatewayDevicesLocalMacs(L2GatewayDevice l2GwDeviceToBeExcluded,
-            String elanName) {
-        List<MacAddress> lstL2GatewayDeviceMacs = new ArrayList<>();
-
-        ConcurrentMap<String, L2GatewayDevice> elanL2GwDevicesFromCache = ElanL2GwCacheUtils
-                .getInvolvedL2GwDevices(elanName);
-        if (elanL2GwDevicesFromCache != null) {
-            for (L2GatewayDevice otherDevice : elanL2GwDevicesFromCache.values()) {
-                if (!otherDevice.getHwvtepNodeId().equals(l2GwDeviceToBeExcluded.getHwvtepNodeId())) {
-                    List<LocalUcastMacs> lstUcastLocalMacs = otherDevice.getUcastLocalMacs();
-                    if (lstUcastLocalMacs != null) {
-                        List<MacAddress> l2GwDeviceMacs = Lists.transform(lstUcastLocalMacs,
-                                new Function<LocalUcastMacs, MacAddress>() {
-                                    @Override
-                                    public MacAddress apply(LocalUcastMacs localUcastMac) {
-                                        return (localUcastMac != null) ? localUcastMac.getMacEntryKey() : null;
-                                    }
-                                });
-                        lstL2GatewayDeviceMacs.addAll(l2GwDeviceMacs);
-                    }
-                }
+    public List<MacAddress> getRemoteUcastMacs(NodeId hwvtepNodeId, String logicalSwitch,
+            LogicalDatastoreType datastoreType) {
+        List<MacAddress> lstMacs = Collections.emptyList();
+        Node hwvtepNode = HwvtepUtils.getHwVtepNode(broker, datastoreType, hwvtepNodeId);
+        if (hwvtepNode != null) {
+            List<RemoteUcastMacs> remoteUcastMacs = hwvtepNode.getAugmentation(HwvtepGlobalAugmentation.class)
+                    .getRemoteUcastMacs();
+            if (remoteUcastMacs != null && !remoteUcastMacs.isEmpty()) {
+                // Filtering remoteUcastMacs based on the logical switch and
+                // forming a list of MacAddress
+                lstMacs = remoteUcastMacs.stream()
+                        .filter(mac -> logicalSwitch.equals(mac.getLogicalSwitchRef().getValue()
+                                .firstKeyOf(LogicalSwitches.class).getHwvtepNodeName().getValue()))
+                        .map(mac -> mac.getMacEntryKey()).collect(Collectors.toList());
             }
         }
-        return lstL2GatewayDeviceMacs;
+        return lstMacs;
     }
 
     /**
@@ -657,15 +653,15 @@ public class ElanL2GatewayUtils {
      *            the l2 gateway device which has to be configured
      * @return the listenable future
      */
-    public static ListenableFuture<Void> installElanMacsInL2GatewayDevice(String elanName,
+    public ListenableFuture<Void> installElanMacsInL2GatewayDevice(String elanName,
             L2GatewayDevice l2GatewayDevice) {
         String logicalSwitchName = getLogicalSwitchFromElan(elanName);
         NodeId hwVtepNodeId = new NodeId(l2GatewayDevice.getHwvtepNodeId());
 
-        List<RemoteUcastMacs> lstL2GatewayDevicesMacs = getOtherDevicesMacs(elanName,
-                l2GatewayDevice, hwVtepNodeId, logicalSwitchName);
-        List<RemoteUcastMacs> lstElanMacTableEntries = getElanMacTableEntriesMacs(elanName,
-                l2GatewayDevice, hwVtepNodeId, logicalSwitchName);
+        List<RemoteUcastMacs> lstL2GatewayDevicesMacs = getOtherDevicesMacs(elanName, l2GatewayDevice, hwVtepNodeId,
+                logicalSwitchName);
+        List<RemoteUcastMacs> lstElanMacTableEntries = getElanMacTableEntriesMacs(elanName, l2GatewayDevice,
+                hwVtepNodeId, logicalSwitchName);
 
         List<RemoteUcastMacs> lstRemoteUcastMacs = new ArrayList<>(lstL2GatewayDevicesMacs);
         lstRemoteUcastMacs.addAll(lstElanMacTableEntries);
@@ -691,9 +687,8 @@ public class ElanL2GatewayUtils {
      * @return the l2 gateway devices macs as remote ucast macs
      */
     public static List<RemoteUcastMacs> getOtherDevicesMacs(String elanName,
-                                                            L2GatewayDevice l2GatewayDeviceToBeConfigured,
-                                                            NodeId hwVtepNodeId, String logicalSwitchName) {
-        List<RemoteUcastMacs> lstRemoteUcastMacs = new ArrayList<RemoteUcastMacs>();
+            L2GatewayDevice l2GatewayDeviceToBeConfigured, NodeId hwVtepNodeId, String logicalSwitchName) {
+        List<RemoteUcastMacs> lstRemoteUcastMacs = new ArrayList<>();
         ConcurrentMap<String, L2GatewayDevice> elanL2GwDevicesFromCache = ElanL2GwCacheUtils
                 .getInvolvedL2GwDevices(elanName);
 
@@ -751,19 +746,18 @@ public class ElanL2GatewayUtils {
      *            the logical switch name
      * @return the elan mac table entries as remote ucast macs
      */
-    public static List<RemoteUcastMacs> getElanMacTableEntriesMacs(String elanName,
-                                                                   L2GatewayDevice l2GatewayDeviceToBeConfigured,
-                                                                   NodeId hwVtepNodeId, String logicalSwitchName) {
-        List<RemoteUcastMacs> lstRemoteUcastMacs = new ArrayList<RemoteUcastMacs>();
+    public List<RemoteUcastMacs> getElanMacTableEntriesMacs(String elanName,
+            L2GatewayDevice l2GatewayDeviceToBeConfigured, NodeId hwVtepNodeId, String logicalSwitchName) {
+        List<RemoteUcastMacs> lstRemoteUcastMacs = new ArrayList<>();
 
-        MacTable macTable = ElanUtils.getElanMacTable(elanName);
+        MacTable macTable = elanUtils.getElanMacTable(elanName);
         if (macTable == null || macTable.getMacEntry() == null || macTable.getMacEntry().isEmpty()) {
             LOG.trace("MacTable is empty for elan: {}", elanName);
             return lstRemoteUcastMacs;
         }
 
         for (MacEntry macEntry : macTable.getMacEntry()) {
-            BigInteger dpnId = ElanUtils.getDpidFromInterface(macEntry.getInterface());
+            BigInteger dpnId = elanUtils.getDpidFromInterface(macEntry.getInterface());
             if (dpnId == null) {
                 LOG.error("DPN ID not found for interface {}", macEntry.getInterface());
                 continue;
@@ -796,7 +790,7 @@ public class ElanL2GatewayUtils {
      *            the dst node
      * @return the external tunnel interface name
      */
-    public static String getExternalTunnelInterfaceName(String sourceNode, String dstNode) {
+    public String getExternalTunnelInterfaceName(String sourceNode, String dstNode) {
         Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
         String tunnelInterfaceName = null;
         try {
@@ -810,8 +804,7 @@ public class ElanL2GatewayUtils {
                 LOG.debug("Tunnel interface name: {} for sourceNode: {} and dstNode: {}", tunnelInterfaceName,
                         sourceNode, dstNode);
             } else {
-                LOG.warn("RPC call to ITM.GetExternalTunnelInterfaceName failed with error: {}",
-                        rpcResult.getErrors());
+                LOG.warn("RPC call to ITM.GetExternalTunnelInterfaceName failed with error: {}", rpcResult.getErrors());
             }
         } catch (NullPointerException | InterruptedException | ExecutionException e) {
             LOG.error("Failed to get external tunnel interface name for sourceNode: {} and dstNode: {}: {} ",
@@ -829,7 +822,7 @@ public class ElanL2GatewayUtils {
      *            the dst hw vtep node id
      * @return the dpn tep ip
      */
-    public static IpAddress getSourceDpnTepIp(BigInteger srcDpnId, NodeId dstHwVtepNodeId) {
+    public IpAddress getSourceDpnTepIp(BigInteger srcDpnId, NodeId dstHwVtepNodeId) {
         IpAddress dpnTepIp = null;
         String tunnelInterfaceName = getExternalTunnelInterfaceName(String.valueOf(srcDpnId),
                 dstHwVtepNodeId.getValue());
@@ -860,7 +853,7 @@ public class ElanL2GatewayUtils {
      *            the default vlan id
      * @return the listenable future
      */
-    public static ListenableFuture<Void> updateVlanBindingsInL2GatewayDevice(NodeId nodeId, String logicalSwitchName,
+    public ListenableFuture<Void> updateVlanBindingsInL2GatewayDevice(NodeId nodeId, String logicalSwitchName,
             Devices hwVtepDevice, Integer defaultVlanId) {
         if (hwVtepDevice == null || hwVtepDevice.getInterfaces() == null || hwVtepDevice.getInterfaces().isEmpty()) {
             String errMsg = "HwVtepDevice is null or interfaces are empty.";
@@ -869,8 +862,18 @@ public class ElanL2GatewayUtils {
         }
 
         WriteTransaction transaction = broker.newWriteOnlyTransaction();
-        for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.attributes.devices.Interfaces deviceInterface : hwVtepDevice
+        for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712
+                .l2gateway.attributes.devices.Interfaces deviceInterface : hwVtepDevice
                 .getInterfaces()) {
+            NodeId physicalSwitchNodeId = HwvtepSouthboundUtils.createManagedNodeId(nodeId,
+                    hwVtepDevice.getDeviceName());
+            TerminationPoint portTerminationPoint = HwvtepUtils.getPhysicalPortTerminationPoint(broker,
+                    LogicalDatastoreType.OPERATIONAL, physicalSwitchNodeId, deviceInterface.getInterfaceName());
+            if (portTerminationPoint == null) {
+                // port is not present in Hwvtep; don't configure VLAN bindings
+                // on this port
+                continue;
+            }
             List<VlanBindings> vlanBindings = new ArrayList<>();
             if (deviceInterface.getSegmentationIds() != null && !deviceInterface.getSegmentationIds().isEmpty()) {
                 for (Integer vlanId : deviceInterface.getSegmentationIds()) {
@@ -890,6 +893,28 @@ public class ElanL2GatewayUtils {
         return future;
     }
 
+    /**
+     * Update vlan bindings in l2 gateway device.
+     *
+     * @param nodeId
+     *            the node id
+     * @param psName
+     *            the physical switch name
+     * @param interfaceName
+     *            the interface in physical switch
+     * @param vlanBindings
+     *            the vlan bindings to be configured
+     * @return the listenable future
+     */
+    public ListenableFuture<Void> updateVlanBindingsInL2GatewayDevice(NodeId nodeId, String psName,
+            String interfaceName, List<VlanBindings> vlanBindings) {
+        WriteTransaction transaction = broker.newWriteOnlyTransaction();
+        HwvtepUtils.mergeVlanBindings(transaction, nodeId, psName, interfaceName, vlanBindings);
+        ListenableFuture<Void> future = transaction.submit();
+        LOG.info("Updated Hwvtep VlanBindings in config DS. NodeID: {}", nodeId.getValue());
+        return future;
+    }
+
     /**
      * Delete vlan bindings from l2 gateway device.
      *
@@ -901,7 +926,7 @@ public class ElanL2GatewayUtils {
      *            the default vlan id
      * @return the listenable future
      */
-    public static ListenableFuture<Void> deleteVlanBindingsFromL2GatewayDevice(NodeId nodeId, Devices hwVtepDevice,
+    public ListenableFuture<Void> deleteVlanBindingsFromL2GatewayDevice(NodeId nodeId, Devices hwVtepDevice,
             Integer defaultVlanId) {
         if (hwVtepDevice == null || hwVtepDevice.getInterfaces() == null || hwVtepDevice.getInterfaces().isEmpty()) {
             String errMsg = "HwVtepDevice is null or interfaces are empty.";
@@ -911,8 +936,8 @@ public class ElanL2GatewayUtils {
         NodeId physicalSwitchNodeId = HwvtepSouthboundUtils.createManagedNodeId(nodeId, hwVtepDevice.getDeviceName());
 
         WriteTransaction transaction = broker.newWriteOnlyTransaction();
-        for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.attributes.devices.Interfaces deviceInterface : hwVtepDevice
-                .getInterfaces()) {
+        for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712
+                .l2gateway.attributes.devices.Interfaces deviceInterface : hwVtepDevice.getInterfaces()) {
             String phyPortName = deviceInterface.getInterfaceName();
             if (deviceInterface.getSegmentationIds() != null && !deviceInterface.getSegmentationIds().isEmpty()) {
                 for (Integer vlanId : deviceInterface.getSegmentationIds()) {
@@ -971,14 +996,15 @@ public class ElanL2GatewayUtils {
     }
 
     public static InstanceIdentifier<Interface> getInterfaceIdentifier(InterfaceKey interfaceKey) {
-        InstanceIdentifier.InstanceIdentifierBuilder<Interface> interfaceInstanceIdentifierBuilder =
-                InstanceIdentifier.builder(Interfaces.class).child(Interface.class, interfaceKey);
+        InstanceIdentifier.InstanceIdentifierBuilder<Interface> interfaceInstanceIdentifierBuilder = InstanceIdentifier
+                .builder(Interfaces.class).child(Interface.class, interfaceKey);
         return interfaceInstanceIdentifierBuilder.build();
     }
 
     public static Interface getInterfaceFromConfigDS(InterfaceKey interfaceKey, DataBroker dataBroker) {
         InstanceIdentifier<Interface> interfaceId = getInterfaceIdentifier(interfaceKey);
-        Optional<Interface> interfaceOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceId, dataBroker);
+        Optional<Interface> interfaceOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceId,
+                dataBroker);
         if (!interfaceOptional.isPresent()) {
             return null;
         }
@@ -998,12 +1024,13 @@ public class ElanL2GatewayUtils {
      *            the elan name
      * @return the listenable future
      */
-    public static List<ListenableFuture<Void>> deleteL2GwDeviceUcastLocalMacsFromElan(L2GatewayDevice l2GatewayDevice,
+    public List<ListenableFuture<Void>> deleteL2GwDeviceUcastLocalMacsFromElan(L2GatewayDevice l2GatewayDevice,
             String elanName) {
-        LOG.info("Deleting L2GatewayDevice [{}] UcastLocalMacs from elan [{}]", l2GatewayDevice.getHwvtepNodeId(), elanName);
+        LOG.info("Deleting L2GatewayDevice [{}] UcastLocalMacs from elan [{}]", l2GatewayDevice.getHwvtepNodeId(),
+                elanName);
 
         List<ListenableFuture<Void>> futures = new ArrayList<>();
-        ElanInstance elan = ElanUtils.getElanInstanceByName(elanName);
+        ElanInstance elan = ElanUtils.getElanInstanceByName(broker, elanName);
         if (elan == null) {
             LOG.error("Could not find Elan by name: {}", elanName);
             return futures;
@@ -1037,62 +1064,55 @@ public class ElanL2GatewayUtils {
         return MDSALUtil.NODE_PREFIX + MDSALUtil.SEPARATOR + dpnId.toString();
     }
 
-    public static void scheduleAddDpnMacInExtDevices(String elanName, BigInteger dpId,
-                                                     List<PhysAddress> staticMacAddresses) {
-        ConcurrentMap<String, L2GatewayDevice> elanDevices = ElanL2GwCacheUtils
-                .getInvolvedL2GwDevices(elanName);
+    public void scheduleAddDpnMacInExtDevices(String elanName, BigInteger dpId,
+            List<PhysAddress> staticMacAddresses) {
+        ConcurrentMap<String, L2GatewayDevice> elanDevices = ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanName);
         for (final L2GatewayDevice externalDevice : elanDevices.values()) {
             scheduleAddDpnMacsInExtDevice(elanName, dpId, staticMacAddresses, externalDevice);
         }
     }
 
-    public static void scheduleAddDpnMacsInExtDevice(final String elanName, BigInteger dpId,
-                                                     final List<PhysAddress> staticMacAddresses,
-                                                     final L2GatewayDevice externalDevice) {
+    public void scheduleAddDpnMacsInExtDevice(final String elanName, BigInteger dpId,
+            final List<PhysAddress> staticMacAddresses, final L2GatewayDevice externalDevice) {
         NodeId nodeId = new NodeId(externalDevice.getHwvtepNodeId());
-        final IpAddress dpnTepIp = ElanL2GatewayUtils.getSourceDpnTepIp(dpId, nodeId);
+        final IpAddress dpnTepIp = getSourceDpnTepIp(dpId, nodeId);
         LOG.trace("Dpn Tep IP: {} for dpnId: {} and nodeId: {}", dpnTepIp, dpId, nodeId);
         if (dpnTepIp == null) {
             LOG.error("could not install dpn mac in l2gw TEP IP not found for dpnId {} and nodeId {}", dpId, nodeId);
             return;
         }
-        TerminationPointKey tpKey = HwvtepSouthboundUtils.getTerminationPointKey(
-                dpnTepIp.getIpv4Address().getValue());
-        InstanceIdentifier<TerminationPoint> tpPath = HwvtepSouthboundUtils.createTerminationPointId
-                (nodeId, tpKey);
+        TerminationPointKey tpKey = HwvtepSouthboundUtils.getTerminationPointKey(dpnTepIp.getIpv4Address().getValue());
+        InstanceIdentifier<TerminationPoint> tpPath = HwvtepSouthboundUtils.createTerminationPointId(nodeId, tpKey);
 
-        HwvtepPhysicalLocatorListener.runJobAfterPhysicalLocatorIsAvialable(tpPath, new Runnable() {
-            @Override
-            public void run() {
-                HwvtepUtils.installUcastMacs(broker,
-                        externalDevice.getHwvtepNodeId(), staticMacAddresses,
-                        elanName, dpnTepIp);
-            }
-        });
+        HwvtepTerminationPointListener.runJobAfterPhysicalLocatorIsAvialable(tpPath, () -> HwvtepUtils
+                .installUcastMacs(broker, externalDevice.getHwvtepNodeId(), staticMacAddresses, elanName, dpnTepIp));
     }
 
-    public static void scheduleDeleteLogicalSwitch(final NodeId hwvtepNodeId, final String lsName) {
+    public void scheduleDeleteLogicalSwitch(final NodeId hwvtepNodeId, final String lsName) {
         TimerTask logicalSwitchDeleteTask = new TimerTask() {
             @Override
             public void run() {
-                LogicalSwitchDeletedJob logicalSwitchDeletedJob = new LogicalSwitchDeletedJob(broker, hwvtepNodeId,
+                Pair<NodeId, String> nodeIdLogicalSwitchNamePair = new ImmutablePair<>(hwvtepNodeId,
                         lsName);
-                ElanL2GatewayUtils.dataStoreJobCoordinator.enqueueJob(logicalSwitchDeletedJob.getJobKey(),
-                        logicalSwitchDeletedJob, SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
+                logicalSwitchDeletedTasks.remove(nodeIdLogicalSwitchNamePair);
+
+                DeleteLogicalSwitchJob deleteLsJob = new DeleteLogicalSwitchJob(broker, hwvtepNodeId, lsName);
+                dataStoreJobCoordinator.enqueueJob(deleteLsJob.getJobKey(), deleteLsJob,
+                        SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
             }
         };
-        Pair<NodeId, String> nodeIdLogicalSwitchNamePair = new ImmutablePair<NodeId, String>(hwvtepNodeId, lsName);
-        LogicalSwitchDeletedTasks.putIfAbsent(nodeIdLogicalSwitchNamePair, logicalSwitchDeleteTask);
+        Pair<NodeId, String> nodeIdLogicalSwitchNamePair = new ImmutablePair<>(hwvtepNodeId, lsName);
+        logicalSwitchDeletedTasks.put(nodeIdLogicalSwitchNamePair, logicalSwitchDeleteTask);
         LogicalSwitchDeleteJobTimer.schedule(logicalSwitchDeleteTask, LOGICAL_SWITCH_DELETE_DELAY);
     }
 
-    public static void cancelDeleteLogicalSwitch(final NodeId hwvtepNodeId, final String lsName) {
-        Pair<NodeId, String> nodeIdLogicalSwitchNamePair = new ImmutablePair<NodeId, String>(hwvtepNodeId, lsName);
-        TimerTask logicalSwitchDeleteTask = LogicalSwitchDeletedTasks.get(nodeIdLogicalSwitchNamePair);
+    public void cancelDeleteLogicalSwitch(final NodeId hwvtepNodeId, final String lsName) {
+        Pair<NodeId, String> nodeIdLogicalSwitchNamePair = new ImmutablePair<>(hwvtepNodeId, lsName);
+        TimerTask logicalSwitchDeleteTask = logicalSwitchDeletedTasks.get(nodeIdLogicalSwitchNamePair);
         if (logicalSwitchDeleteTask != null) {
             LOG.debug("Delete logical switch {} action on node {} cancelled", lsName, hwvtepNodeId);
             logicalSwitchDeleteTask.cancel();
-            LogicalSwitchDeletedTasks.remove(nodeIdLogicalSwitchNamePair);
+            logicalSwitchDeletedTasks.remove(nodeIdLogicalSwitchNamePair);
         }
     }
 }