ifm changes for performance enhancements
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / listeners / InterfaceInventoryStateListener.java
index b5c60c37f9a4fca288cb63510466b6402c8c545c..472ff9c3eba8946b16e8a18a5b91bb3d8a01a8b4 100644 (file)
@@ -8,6 +8,7 @@
 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;
@@ -15,15 +16,19 @@ 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.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.OvsInterfaceStateUpdateHelper;
 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
@@ -57,7 +62,8 @@ 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;
@@ -67,6 +73,9 @@ public class InterfaceInventoryStateListener
     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,
@@ -75,7 +84,11 @@ public class InterfaceInventoryStateListener
             final InterfaceManagerCommonUtils interfaceManagerCommonUtils,
             final OvsInterfaceStateAddHelper ovsInterfaceStateAddHelper,
             final OvsInterfaceStateUpdateHelper ovsInterfaceStateUpdateHelper,
-            final AlivenessMonitorUtils alivenessMonitorUtils) {
+            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;
@@ -85,9 +98,23 @@ public class InterfaceInventoryStateListener
         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)
@@ -101,7 +128,14 @@ public class InterfaceInventoryStateListener
 
     @Override
     protected void remove(InstanceIdentifier<FlowCapableNodeConnector> key,
-            FlowCapableNodeConnector flowCapableNodeConnectorOld) {
+                          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;
@@ -117,26 +151,35 @@ public class InterfaceInventoryStateListener
     }
 
     private void remove(NodeConnectorId nodeConnectorIdNew, NodeConnectorId nodeConnectorIdOld,
-            FlowCapableNodeConnector fcNodeConnectorNew, String portName, boolean isNetworkEvent) {
+                        FlowCapableNodeConnector fcNodeConnectorNew, String portName, boolean isNetworkEvent) {
         boolean isNodePresent = interfaceManagerCommonUtils.isNodePresent(nodeConnectorIdNew);
-        InterfaceStateRemoveWorker portStateRemoveWorker = new InterfaceStateRemoveWorker(idManager, nodeConnectorIdNew,
-                nodeConnectorIdOld, fcNodeConnectorNew, portName, portName, isNodePresent, isNetworkEvent, true);
+        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) {
+                          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());
+                fcNodeConnectorNew.getName());
 
         InterfaceStateUpdateWorker portStateUpdateWorker = new InterfaceStateUpdateWorker(key, fcNodeConnectorOld,
             fcNodeConnectorNew, portName);
@@ -145,6 +188,13 @@ public class InterfaceInventoryStateListener
 
     @Override
     protected void add(InstanceIdentifier<FlowCapableNodeConnector> key, FlowCapableNodeConnector fcNodeConnectorNew) {
+        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;
@@ -153,10 +203,13 @@ public class InterfaceInventoryStateListener
         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)) {
+        if (InterfaceManagerCommonUtils.isNovaPort(portName) || InterfaceManagerCommonUtils.isK8SPort(portName)) {
             NodeConnectorId nodeConnectorIdOld =
                     FlowBasedServicesUtils.getNodeConnectorIdFromInterface(portName, interfaceManagerCommonUtils);
             if (nodeConnectorIdOld != null && !nodeConnectorId.equals(nodeConnectorIdOld)) {
@@ -179,7 +232,7 @@ 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");
                 }
             }
@@ -198,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;
@@ -207,9 +260,9 @@ public class InterfaceInventoryStateListener
 
         @Override
         public Object call() {
-            List<ListenableFuture<Void>> futures = ovsInterfaceStateAddHelper.addState(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());
@@ -232,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;
@@ -244,7 +298,7 @@ public class InterfaceInventoryStateListener
         public Object call() {
             List<ListenableFuture<Void>> futures = ovsInterfaceStateUpdateHelper.updateState(
                     interfaceName, fcNodeConnectorNew, fcNodeConnectorOld);
-            List<InterfaceChildEntry> interfaceChildEntries = getInterfaceChildEntries(dataBroker, interfaceName);
+            List<InterfaceChildEntry> interfaceChildEntries = getInterfaceChildEntries(interfaceName);
             for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
                 InterfaceStateUpdateWorker interfaceStateUpdateWorker = new InterfaceStateUpdateWorker(key,
                         fcNodeConnectorOld, fcNodeConnectorNew, interfaceChildEntry.getChildInterface());
@@ -265,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;
@@ -300,24 +354,21 @@ public class InterfaceInventoryStateListener
                 }
             }
 
-            futures = removeInterfaceStateConfiguration(nodeConnectorIdNew, nodeConnectorIdOld, interfaceName,
-                    fcNodeConnectorOld, isNodePresent);
+            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);
+                        interfaceChildEntry.getChildInterface(), isNodePresent, isNetworkEvent, false);
                 coordinator.enqueueJob(interfaceName, interfaceStateRemoveWorker);
             }
             return futures;
         }
 
-        private List<ListenableFuture<Void>> removeInterfaceStateConfiguration(NodeConnectorId nodeConnectorIdNew,
-                NodeConnectorId nodeConnectorIdOld, String interfaceName, FlowCapableNodeConnector fcNodeConnectorOld,
-                boolean isNodePresent) {
+        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();
@@ -342,7 +393,7 @@ public class InterfaceInventoryStateListener
                 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(idManager, defaultOperationalShardTransaction,
+                        interfaceMetaUtils.removeLportTagInterfaceMap(defaultOperationalShardTransaction,
                                 interfaceName);
                         handleTunnelMonitoringRemoval(dpId, iface.getName(), iface.getAugmentation(IfTunnel.class),
                                 defaultOperationalShardTransaction, futures);
@@ -351,7 +402,7 @@ public class InterfaceInventoryStateListener
                 }
                 // remove ingress flow only for northbound configured interfaces
                 // skip this check for non-unique ports(Ex: br-int,br-ex)
-                if (iface != null || iface == null && !interfaceName.contains(fcNodeConnectorOld.getName())) {
+                if (iface != null || !interfaceName.contains(fcNodeConnectorOld.getName())) {
                     FlowBasedServicesUtils.removeIngressFlow(interfaceName, dpId, dataBroker, futures);
                 }
 
@@ -363,15 +414,16 @@ public class InterfaceInventoryStateListener
             return futures;
         }
 
-        private void handleTunnelMonitoringRemoval(BigInteger dpId, String interfaceName,
-                IfTunnel ifTunnel, WriteTransaction transaction, List<ListenableFuture<Void>> futures) {
-            interfaceManagerCommonUtils.removeTunnelIngressFlow(ifTunnel, dpId, interfaceName);
+        private void handleTunnelMonitoringRemoval(BigInteger dpId, String removedInterfaceName,
+                                                   IfTunnel ifTunnel, WriteTransaction transaction,
+                                                   List<ListenableFuture<Void>> futures) {
+            interfaceManagerCommonUtils.removeTunnelIngressFlow(ifTunnel, dpId, removedInterfaceName);
 
-            IfmUtil.unbindService(dataBroker, coordinator, interfaceName,
-                    FlowBasedServicesUtils.buildDefaultServiceId(interfaceName));
+            IfmUtil.unbindService(dataBroker, coordinator, removedInterfaceName,
+                    FlowBasedServicesUtils.buildDefaultServiceId(removedInterfaceName));
 
             futures.add(transaction.submit());
-            alivenessMonitorUtils.stopLLDPMonitoring(ifTunnel, interfaceName);
+            alivenessMonitorUtils.stopLLDPMonitoring(ifTunnel, removedInterfaceName);
         }
 
         @Override
@@ -382,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();
         }