ifm changes for performance enhancements
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / listeners / InterfaceInventoryStateListener.java
index 893133c9f1083c4b5424c103d22147c314733a13..472ff9c3eba8946b16e8a18a5b91bb3d8a01a8b4 100644 (file)
@@ -8,30 +8,40 @@
 package org.opendaylight.genius.interfacemanager.listeners;
 
 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.Callable;
 import javax.inject.Inject;
 import javax.inject.Singleton;
+
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
-import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
 import org.opendaylight.genius.interfacemanager.IfmConstants;
 import org.opendaylight.genius.interfacemanager.IfmUtil;
+import org.opendaylight.genius.interfacemanager.InterfacemgrProvider;
+import org.opendaylight.genius.interfacemanager.commons.AlivenessMonitorUtils;
 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
 import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
+import org.opendaylight.genius.interfacemanager.recovery.impl.InterfaceServiceRecoveryHandler;
+import org.opendaylight.genius.interfacemanager.recovery.listeners.RecoverableListener;
 import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceStateAddHelper;
-import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceStateRemoveHelper;
 import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceStateUpdateHelper;
-import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.IfmClusterUtils;
+import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
+import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortReason;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
@@ -52,24 +62,59 @@ import org.slf4j.LoggerFactory;
  */
 @Singleton
 public class InterfaceInventoryStateListener
-        extends AsyncClusteredDataTreeChangeListenerBase<FlowCapableNodeConnector, InterfaceInventoryStateListener> {
+        extends AsyncClusteredDataTreeChangeListenerBase<FlowCapableNodeConnector, InterfaceInventoryStateListener>
+        implements RecoverableListener {
     private static final Logger LOG = LoggerFactory.getLogger(InterfaceInventoryStateListener.class);
     private final DataBroker dataBroker;
     private final IdManagerService idManager;
-    private final IMdsalApiManager mdsalApiManager;
-    private final AlivenessMonitorService alivenessMonitorService;
+    private final EntityOwnershipUtils entityOwnershipUtils;
+    private final JobCoordinator coordinator;
+    private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
+    private final AlivenessMonitorUtils alivenessMonitorUtils;
+    private final OvsInterfaceStateUpdateHelper ovsInterfaceStateUpdateHelper;
+    private final OvsInterfaceStateAddHelper ovsInterfaceStateAddHelper;
+    private final InterfaceMetaUtils interfaceMetaUtils;
+    private final PortNameCache portNameCache;
+    private final InterfacemgrProvider interfacemgrProvider;
 
     @Inject
     public InterfaceInventoryStateListener(final DataBroker dataBroker, final IdManagerService idManagerService,
-            final IMdsalApiManager mdsalApiManager, final AlivenessMonitorService alivenessMonitorService) {
+            final IMdsalApiManager mdsalApiManager, final AlivenessMonitorService alivenessMonitorService,
+            final EntityOwnershipUtils entityOwnershipUtils, final JobCoordinator coordinator,
+            final InterfaceManagerCommonUtils interfaceManagerCommonUtils,
+            final OvsInterfaceStateAddHelper ovsInterfaceStateAddHelper,
+            final OvsInterfaceStateUpdateHelper ovsInterfaceStateUpdateHelper,
+            final AlivenessMonitorUtils alivenessMonitorUtils,
+            final InterfaceMetaUtils interfaceMetaUtils,
+            final PortNameCache portNameCache,
+            final InterfaceServiceRecoveryHandler interfaceServiceRecoveryHandler,
+            final InterfacemgrProvider interfacemgrProvider) {
         super(FlowCapableNodeConnector.class, InterfaceInventoryStateListener.class);
         this.dataBroker = dataBroker;
         this.idManager = idManagerService;
-        this.mdsalApiManager = mdsalApiManager;
-        this.alivenessMonitorService = alivenessMonitorService;
+        this.entityOwnershipUtils = entityOwnershipUtils;
+        this.coordinator = coordinator;
+        this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
+        this.alivenessMonitorUtils = alivenessMonitorUtils;
+        this.ovsInterfaceStateUpdateHelper = ovsInterfaceStateUpdateHelper;
+        this.ovsInterfaceStateAddHelper = ovsInterfaceStateAddHelper;
+        this.interfaceMetaUtils = interfaceMetaUtils;
+        this.portNameCache = portNameCache;
+        this.interfacemgrProvider = interfacemgrProvider;
+        registerListener();
+        interfaceServiceRecoveryHandler.addRecoverableListener(this);
+    }
+
+    @Override
+    public void registerListener() {
         this.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
     }
 
+    @Override
+    public  void deregisterListener() {
+        close();
+    }
+
     @Override
     protected InstanceIdentifier<FlowCapableNodeConnector> getWildCardPath() {
         return InstanceIdentifier.create(Nodes.class).child(Node.class).child(NodeConnector.class)
@@ -83,8 +128,16 @@ public class InterfaceInventoryStateListener
 
     @Override
     protected void remove(InstanceIdentifier<FlowCapableNodeConnector> key,
-            FlowCapableNodeConnector flowCapableNodeConnectorOld) {
-        if (!IfmClusterUtils.isEntityOwner(IfmClusterUtils.INTERFACE_CONFIG_ENTITY)) {
+                          FlowCapableNodeConnector flowCapableNodeConnectorOld) {
+        if (interfacemgrProvider.isItmDirectTunnelsEnabled()
+                && interfaceManagerCommonUtils.isTunnelInternal(flowCapableNodeConnectorOld.getName())) {
+            LOG.debug("ITM Direct Tunnels is enabled, ignoring node connector removed for internal tunnel {}",
+                    flowCapableNodeConnectorOld.getName());
+            return;
+        }
+
+        if (!entityOwnershipUtils.isEntityOwner(IfmConstants.INTERFACE_CONFIG_ENTITY,
+                IfmConstants.INTERFACE_CONFIG_ENTITY)) {
             return;
         }
 
@@ -98,27 +151,35 @@ public class InterfaceInventoryStateListener
     }
 
     private void remove(NodeConnectorId nodeConnectorIdNew, NodeConnectorId nodeConnectorIdOld,
-            FlowCapableNodeConnector fcNodeConnectorNew, String portName, boolean isNetworkEvent) {
-        boolean isNodePresent = InterfaceManagerCommonUtils.isNodePresent(dataBroker, nodeConnectorIdNew);
-        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
-        InterfaceStateRemoveWorker portStateRemoveWorker = new InterfaceStateRemoveWorker(idManager, nodeConnectorIdNew,
-                nodeConnectorIdOld, fcNodeConnectorNew, portName, portName, isNodePresent, isNetworkEvent, true);
+                        FlowCapableNodeConnector fcNodeConnectorNew, String portName, boolean isNetworkEvent) {
+        boolean isNodePresent = interfaceManagerCommonUtils.isNodePresent(nodeConnectorIdNew);
+        InterfaceStateRemoveWorker portStateRemoveWorker = new InterfaceStateRemoveWorker(idManager,
+                nodeConnectorIdNew, nodeConnectorIdOld, fcNodeConnectorNew, portName, isNodePresent,
+                isNetworkEvent, true);
         coordinator.enqueueJob(portName, portStateRemoveWorker, IfmConstants.JOB_MAX_RETRIES);
+        LOG.trace("Removing entry for port id {} from map",nodeConnectorIdNew.getValue());
+        portNameCache.remove(nodeConnectorIdNew.getValue());
     }
 
     @Override
     protected void update(InstanceIdentifier<FlowCapableNodeConnector> key, FlowCapableNodeConnector fcNodeConnectorOld,
-            FlowCapableNodeConnector fcNodeConnectorNew) {
-        if (!IfmClusterUtils.isEntityOwner(IfmClusterUtils.INTERFACE_CONFIG_ENTITY)) {
+                          FlowCapableNodeConnector fcNodeConnectorNew) {
+        if (interfacemgrProvider.isItmDirectTunnelsEnabled()
+                && interfaceManagerCommonUtils.isTunnelInternal(fcNodeConnectorNew.getName())) {
+            LOG.debug("ITM Direct Tunnels is enabled, ignoring node connector Update for internal tunnel {}",
+                    fcNodeConnectorNew.getName());
+            return;
+        }
+
+        if (!entityOwnershipUtils.isEntityOwner(IfmConstants.INTERFACE_CONFIG_ENTITY,
+                IfmConstants.INTERFACE_CONFIG_ENTITY)) {
             return;
         }
 
         LOG.debug("Received NodeConnector Update Event: {}, {}, {}", key, fcNodeConnectorOld, fcNodeConnectorNew);
-        NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class))
-            .getId();
+        NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
         String portName = InterfaceManagerCommonUtils.getPortNameForInterface(nodeConnectorId,
-            fcNodeConnectorNew.getName());
-        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+                fcNodeConnectorNew.getName());
 
         InterfaceStateUpdateWorker portStateUpdateWorker = new InterfaceStateUpdateWorker(key, fcNodeConnectorOld,
             fcNodeConnectorNew, portName);
@@ -127,25 +188,43 @@ public class InterfaceInventoryStateListener
 
     @Override
     protected void add(InstanceIdentifier<FlowCapableNodeConnector> key, FlowCapableNodeConnector fcNodeConnectorNew) {
-        if (!IfmClusterUtils.isEntityOwner(IfmClusterUtils.INTERFACE_CONFIG_ENTITY)) {
+        if (interfacemgrProvider.isItmDirectTunnelsEnabled()
+                && interfaceManagerCommonUtils.isTunnelInternal(fcNodeConnectorNew.getName())) {
+            LOG.debug("ITM Direct Tunnels is enabled, ignoring node connector add for internal tunnel {}",
+                    fcNodeConnectorNew.getName());
+            return;
+        }
+
+        if (!entityOwnershipUtils.isEntityOwner(IfmConstants.INTERFACE_CONFIG_ENTITY,
+                IfmConstants.INTERFACE_CONFIG_ENTITY)) {
             return;
         }
 
         LOG.debug("Received NodeConnector Add Event: {}, {}", key, fcNodeConnectorNew);
         NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class))
             .getId();
+        LOG.trace("Adding entry for portid {} portname {} in map", nodeConnectorId.getValue(),
+                fcNodeConnectorNew.getName());
+        portNameCache.put(nodeConnectorId.getValue(),fcNodeConnectorNew.getName());
         String portName = InterfaceManagerCommonUtils.getPortNameForInterface(nodeConnectorId,
             fcNodeConnectorNew.getName());
 
-        if (InterfaceManagerCommonUtils.isNovaPort(portName)) {
-            NodeConnectorId nodeConnectorIdOld = IfmUtil.getNodeConnectorIdFromInterface(portName, dataBroker);
+        if (InterfaceManagerCommonUtils.isNovaPort(portName) || InterfaceManagerCommonUtils.isK8SPort(portName)) {
+            NodeConnectorId nodeConnectorIdOld =
+                    FlowBasedServicesUtils.getNodeConnectorIdFromInterface(portName, interfaceManagerCommonUtils);
             if (nodeConnectorIdOld != null && !nodeConnectorId.equals(nodeConnectorIdOld)) {
-                if (!fcNodeConnectorNew.getReason().equals(PortReason.Add)) {
-                    LOG.error("Dropping NodeConnector Event for {}, VM migration should be triggered "
-                            + "only for OFPT_PORT_STATUS/OFPPR_ADD", fcNodeConnectorNew.getName());
-                    return;
+                BigInteger dpnIdOld = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorIdOld);
+                BigInteger dpnIdNew = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
+                if (!Objects.equals(dpnIdOld, dpnIdNew)) {
+                    if (fcNodeConnectorNew.getReason() != PortReason.Add) {
+                        LOG.error("Dropping Port update event for {}, as DPN id is changed from {} to {}",
+                            fcNodeConnectorNew.getName(), dpnIdOld, dpnIdNew);
+                        return;
+                    }
+                } else {
+                    LOG.warn("Port number update detected for {}", fcNodeConnectorNew.getName());
                 }
-                // VM Migration: Delete existing interface entry for older DPN
+                //VM Migration or Port Number Update: Delete existing interface entry for older DPN
                 LOG.debug("Triggering NodeConnector Remove Event for the interface: {}, {}, {}", portName,
                     nodeConnectorId, nodeConnectorIdOld);
                 remove(nodeConnectorId, nodeConnectorIdOld, fcNodeConnectorNew, portName, false);
@@ -153,12 +232,12 @@ public class InterfaceInventoryStateListener
                 // for processing remove before add
                 try {
                     Thread.sleep(IfmConstants.DELAY_TIME_IN_MILLISECOND);
-                } catch (InterruptedException e) {
+                } catch (final InterruptedException e) {
                     LOG.error("Error while waiting for the vm migration remove events to get processed");
                 }
             }
         }
-        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+
         InterfaceStateAddWorker ifStateAddWorker = new InterfaceStateAddWorker(idManager, nodeConnectorId,
             fcNodeConnectorNew, portName);
         coordinator.enqueueJob(portName, ifStateAddWorker, IfmConstants.JOB_MAX_RETRIES);
@@ -172,7 +251,7 @@ public class InterfaceInventoryStateListener
         private final IdManagerService idManager;
 
         InterfaceStateAddWorker(IdManagerService idManager, NodeConnectorId nodeConnectorId,
-                FlowCapableNodeConnector fcNodeConnectorNew, String portName) {
+                                FlowCapableNodeConnector fcNodeConnectorNew, String portName) {
             this.nodeConnectorId = nodeConnectorId;
             this.fcNodeConnectorNew = fcNodeConnectorNew;
             this.interfaceName = portName;
@@ -181,13 +260,13 @@ public class InterfaceInventoryStateListener
 
         @Override
         public Object call() {
-            List<ListenableFuture<Void>> futures = OvsInterfaceStateAddHelper.addState(dataBroker, idManager,
-                    mdsalApiManager, alivenessMonitorService, nodeConnectorId, interfaceName, fcNodeConnectorNew);
-            List<InterfaceChildEntry> interfaceChildEntries = getInterfaceChildEntries(dataBroker, interfaceName);
+            List<ListenableFuture<Void>> futures = ovsInterfaceStateAddHelper.addState(nodeConnectorId,
+                    interfaceName, fcNodeConnectorNew);
+            List<InterfaceChildEntry> interfaceChildEntries = getInterfaceChildEntries(interfaceName);
             for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
                 InterfaceStateAddWorker interfaceStateAddWorker = new InterfaceStateAddWorker(idManager,
                         nodeConnectorId, fcNodeConnectorNew, interfaceChildEntry.getChildInterface());
-                DataStoreJobCoordinator.getInstance().enqueueJob(interfaceName, interfaceStateAddWorker);
+                coordinator.enqueueJob(interfaceName, interfaceStateAddWorker);
             }
             return futures;
         }
@@ -206,8 +285,9 @@ public class InterfaceInventoryStateListener
         private final String interfaceName;
 
         InterfaceStateUpdateWorker(InstanceIdentifier<FlowCapableNodeConnector> key,
-                FlowCapableNodeConnector fcNodeConnectorOld, FlowCapableNodeConnector fcNodeConnectorNew,
-                String portName) {
+                                   FlowCapableNodeConnector fcNodeConnectorOld,
+                                   FlowCapableNodeConnector fcNodeConnectorNew,
+                                   String portName) {
             this.key = key;
             this.fcNodeConnectorOld = fcNodeConnectorOld;
             this.fcNodeConnectorNew = fcNodeConnectorNew;
@@ -216,13 +296,13 @@ public class InterfaceInventoryStateListener
 
         @Override
         public Object call() {
-            List<ListenableFuture<Void>> futures = OvsInterfaceStateUpdateHelper.updateState(key,
-                    alivenessMonitorService, dataBroker, interfaceName, fcNodeConnectorNew, fcNodeConnectorOld);
-            List<InterfaceChildEntry> interfaceChildEntries = getInterfaceChildEntries(dataBroker, interfaceName);
+            List<ListenableFuture<Void>> futures = ovsInterfaceStateUpdateHelper.updateState(
+                    interfaceName, fcNodeConnectorNew, fcNodeConnectorOld);
+            List<InterfaceChildEntry> interfaceChildEntries = getInterfaceChildEntries(interfaceName);
             for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
                 InterfaceStateUpdateWorker interfaceStateUpdateWorker = new InterfaceStateUpdateWorker(key,
                         fcNodeConnectorOld, fcNodeConnectorNew, interfaceChildEntry.getChildInterface());
-                DataStoreJobCoordinator.getInstance().enqueueJob(interfaceName, interfaceStateUpdateWorker);
+                coordinator.enqueueJob(interfaceName, interfaceStateUpdateWorker);
             }
             return futures;
         }
@@ -239,20 +319,20 @@ public class InterfaceInventoryStateListener
         private NodeConnectorId nodeConnectorIdOld;
         FlowCapableNodeConnector fcNodeConnectorOld;
         private final String interfaceName;
-        private final String parentInterface;
         private final IdManagerService idManager;
         private final boolean isNodePresent;
         private final boolean isNetworkEvent;
         private final boolean isParentInterface;
 
         InterfaceStateRemoveWorker(IdManagerService idManager, NodeConnectorId nodeConnectorIdNew,
-                NodeConnectorId nodeConnectorIdOld, FlowCapableNodeConnector fcNodeConnectorOld, String interfaceName,
-                String parentInterface, boolean isNodePresent, boolean isNetworkEvent, boolean isParentInterface) {
+                                   NodeConnectorId nodeConnectorIdOld,
+                                   FlowCapableNodeConnector fcNodeConnectorOld, String interfaceName,
+                                   boolean isNodePresent, boolean isNetworkEvent,
+                                   boolean isParentInterface) {
             this.nodeConnectorIdNew = nodeConnectorIdNew;
             this.nodeConnectorIdOld = nodeConnectorIdOld;
             this.fcNodeConnectorOld = fcNodeConnectorOld;
             this.interfaceName = interfaceName;
-            this.parentInterface = parentInterface;
             this.idManager = idManager;
             this.isNodePresent = isNodePresent;
             this.isNetworkEvent = isNetworkEvent;
@@ -265,7 +345,8 @@ public class InterfaceInventoryStateListener
             // VM Migration: Skip OFPPR_DELETE event received after OFPPR_ADD
             // for same interface from Older DPN
             if (isParentInterface && isNetworkEvent) {
-                nodeConnectorIdOld = IfmUtil.getNodeConnectorIdFromInterface(interfaceName, dataBroker);
+                nodeConnectorIdOld = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(interfaceName,
+                        interfaceManagerCommonUtils);
                 if (nodeConnectorIdOld != null && !nodeConnectorIdNew.equals(nodeConnectorIdOld)) {
                     LOG.debug("Dropping the NodeConnector Remove Event for the interface: {}, {}, {}", interfaceName,
                             nodeConnectorIdNew, nodeConnectorIdOld);
@@ -273,22 +354,78 @@ public class InterfaceInventoryStateListener
                 }
             }
 
-            futures = OvsInterfaceStateRemoveHelper.removeInterfaceStateConfiguration(idManager, mdsalApiManager,
-                    alivenessMonitorService, nodeConnectorIdNew, nodeConnectorIdOld, dataBroker, interfaceName,
-                    fcNodeConnectorOld, isNodePresent, parentInterface);
+            futures = removeInterfaceStateConfiguration();
 
-            List<InterfaceChildEntry> interfaceChildEntries = getInterfaceChildEntries(dataBroker, interfaceName);
+            List<InterfaceChildEntry> interfaceChildEntries = getInterfaceChildEntries(interfaceName);
             for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
                 // Fetch all interfaces on this port and trigger remove worker
                 // for each of them
                 InterfaceStateRemoveWorker interfaceStateRemoveWorker = new InterfaceStateRemoveWorker(idManager,
                         nodeConnectorIdNew, nodeConnectorIdOld, fcNodeConnectorOld,
-                        interfaceChildEntry.getChildInterface(), interfaceName, isNodePresent, isNetworkEvent, false);
-                DataStoreJobCoordinator.getInstance().enqueueJob(interfaceName, interfaceStateRemoveWorker);
+                        interfaceChildEntry.getChildInterface(), isNodePresent, isNetworkEvent, false);
+                coordinator.enqueueJob(interfaceName, interfaceStateRemoveWorker);
             }
             return futures;
         }
 
+        private List<ListenableFuture<Void>> removeInterfaceStateConfiguration() {
+            LOG.debug("Removing interface state information for interface: {} {}", interfaceName, isNodePresent);
+            List<ListenableFuture<Void>> futures = new ArrayList<>();
+            WriteTransaction defaultOperationalShardTransaction = dataBroker.newWriteOnlyTransaction();
+
+            //VM Migration: Use old nodeConnectorId to delete the interface entry
+            NodeConnectorId nodeConnectorId = nodeConnectorIdOld != null
+                    && !nodeConnectorIdNew.equals(nodeConnectorIdOld) ? nodeConnectorIdOld : nodeConnectorIdNew;
+            // delete the port entry from interface operational DS
+            BigInteger dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
+
+            //VM Migration: Update the interface state to unknown only if remove event received for same switch
+            if (!isNodePresent && nodeConnectorIdNew.equals(nodeConnectorIdOld)) {
+                //Remove event is because of connection lost between controller and switch, or switch shutdown.
+                // Hence, don't remove the interface but set the status as "unknown"
+                ovsInterfaceStateUpdateHelper.updateInterfaceStateOnNodeRemove(interfaceName, fcNodeConnectorOld,
+                        defaultOperationalShardTransaction);
+            } else {
+                InterfaceManagerCommonUtils.deleteStateEntry(interfaceName, defaultOperationalShardTransaction);
+                org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
+                    .Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
+
+                if (iface != null) {
+                    // If this interface is a tunnel interface, remove the tunnel ingress flow and stop LLDP monitoring
+                    if (InterfaceManagerCommonUtils.isTunnelInterface(iface)) {
+                        interfaceMetaUtils.removeLportTagInterfaceMap(defaultOperationalShardTransaction,
+                                interfaceName);
+                        handleTunnelMonitoringRemoval(dpId, iface.getName(), iface.getAugmentation(IfTunnel.class),
+                                defaultOperationalShardTransaction, futures);
+                        return futures;
+                    }
+                }
+                // remove ingress flow only for northbound configured interfaces
+                // skip this check for non-unique ports(Ex: br-int,br-ex)
+                if (iface != null || !interfaceName.contains(fcNodeConnectorOld.getName())) {
+                    FlowBasedServicesUtils.removeIngressFlow(interfaceName, dpId, dataBroker, futures);
+                }
+
+                // Delete the Vpn Interface from DpnToInterface Op DS.
+                interfaceManagerCommonUtils.deleteDpnToInterface(dpId, interfaceName,
+                        defaultOperationalShardTransaction);
+            }
+            futures.add(defaultOperationalShardTransaction.submit());
+            return futures;
+        }
+
+        private void handleTunnelMonitoringRemoval(BigInteger dpId, String removedInterfaceName,
+                                                   IfTunnel ifTunnel, WriteTransaction transaction,
+                                                   List<ListenableFuture<Void>> futures) {
+            interfaceManagerCommonUtils.removeTunnelIngressFlow(ifTunnel, dpId, removedInterfaceName);
+
+            IfmUtil.unbindService(dataBroker, coordinator, removedInterfaceName,
+                    FlowBasedServicesUtils.buildDefaultServiceId(removedInterfaceName));
+
+            futures.add(transaction.submit());
+            alivenessMonitorUtils.stopLLDPMonitoring(ifTunnel, removedInterfaceName);
+        }
+
         @Override
         public String toString() {
             return "InterfaceStateRemoveWorker{" + "nodeConnectorIdNew=" + nodeConnectorIdNew + ", nodeConnectorIdOld="
@@ -297,9 +434,9 @@ public class InterfaceInventoryStateListener
         }
     }
 
-    public static List<InterfaceChildEntry> getInterfaceChildEntries(DataBroker dataBroker, String interfaceName) {
-        InterfaceParentEntry interfaceParentEntry = InterfaceMetaUtils
-                .getInterfaceParentEntryFromConfigDS(interfaceName, dataBroker);
+    public List<InterfaceChildEntry> getInterfaceChildEntries(String interfaceName) {
+        InterfaceParentEntry interfaceParentEntry =
+                interfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceName);
         if (interfaceParentEntry != null && interfaceParentEntry.getInterfaceChildEntry() != null) {
             return interfaceParentEntry.getInterfaceChildEntry();
         }