ifm changes for performance enhancements
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / listeners / TerminationPointStateListener.java
index 1164d6c99952efbd3b426faadbe64b9c082be6e7..4cc66f2ab58dbc3e99d91b4872d7f146606e7ffd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -11,16 +11,20 @@ import com.google.common.util.concurrent.ListenableFuture;
 
 import java.util.List;
 import java.util.concurrent.Callable;
+import javax.inject.Inject;
+import javax.inject.Singleton;
 
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
-import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
 import org.opendaylight.genius.interfacemanager.IfmConstants;
 import org.opendaylight.genius.interfacemanager.InterfacemgrProvider;
 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.genius.interfacemanager.recovery.impl.InterfaceServiceRecoveryHandler;
+import org.opendaylight.genius.interfacemanager.recovery.listeners.RecoverableListener;
 import org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers.OvsInterfaceTopologyStateUpdateHelper;
-import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.IfmClusterUtils;
-import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
+import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
@@ -31,26 +35,53 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class TerminationPointStateListener extends AsyncClusteredDataTreeChangeListenerBase<OvsdbTerminationPointAugmentation, TerminationPointStateListener> {
+@Singleton
+public class TerminationPointStateListener extends
+        AsyncClusteredDataTreeChangeListenerBase<OvsdbTerminationPointAugmentation, TerminationPointStateListener>
+        implements RecoverableListener {
     private static final Logger LOG = LoggerFactory.getLogger(TerminationPointStateListener.class);
-    private final DataBroker dataBroker;
-    private final MdsalUtils mdsalUtils;
-    private final SouthboundUtils southboundUtils;
-    private final InterfacemgrProvider interfaceMgrProvider;
 
-    public TerminationPointStateListener(DataBroker dataBroker,
-                                         final InterfacemgrProvider interfaceMgrProvider) {
-        super(OvsdbTerminationPointAugmentation.class, TerminationPointStateListener.class);
-        this.dataBroker = dataBroker;
-        this.mdsalUtils = new MdsalUtils(dataBroker);
-        this.southboundUtils = new SouthboundUtils(mdsalUtils);
+    private final InterfacemgrProvider interfaceMgrProvider;
+    private final DataBroker dataBroker;
+    private final EntityOwnershipUtils entityOwnershipUtils;
+    private final JobCoordinator coordinator;
+    private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
+    private final OvsInterfaceTopologyStateUpdateHelper ovsInterfaceTopologyStateUpdateHelper;
+    private final InterfaceServiceRecoveryHandler interfaceServiceRecoveryHandler;
+
+    @Inject
+    public TerminationPointStateListener(final DataBroker dataBroker, final InterfacemgrProvider interfaceMgrProvider,
+                                         final EntityOwnershipUtils entityOwnershipUtils,
+                                         final JobCoordinator coordinator,
+                                         final InterfaceManagerCommonUtils interfaceManagerCommonUtils,
+                                         final OvsInterfaceTopologyStateUpdateHelper
+                                                     ovsInterfaceTopologyStateUpdateHelper,
+                                         final InterfaceServiceRecoveryHandler interfaceServiceRecoveryHandler) {
         this.interfaceMgrProvider = interfaceMgrProvider;
+        this.entityOwnershipUtils = entityOwnershipUtils;
+        this.coordinator = coordinator;
+        this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
+        this.ovsInterfaceTopologyStateUpdateHelper = ovsInterfaceTopologyStateUpdateHelper;
+        this.dataBroker = dataBroker;
+        this.interfaceServiceRecoveryHandler = interfaceServiceRecoveryHandler;
+        registerListener();
+        this.interfaceServiceRecoveryHandler.addRecoverableListener(this);
+    }
+
+    @Override
+    public void registerListener() {
+        this.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
+    }
+
+    @Override
+    public  void deregisterListener() {
+        close();
     }
 
     @Override
     protected InstanceIdentifier<OvsdbTerminationPointAugmentation> getWildCardPath() {
-        return InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class)
-                .child(Node.class).child(TerminationPoint.class).augmentation(OvsdbTerminationPointAugmentation.class).build();
+        return InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class).child(Node.class)
+                .child(TerminationPoint.class).augmentation(OvsdbTerminationPointAugmentation.class).build();
     }
 
     @Override
@@ -61,12 +92,26 @@ public class TerminationPointStateListener extends AsyncClusteredDataTreeChangeL
     @Override
     protected void remove(InstanceIdentifier<OvsdbTerminationPointAugmentation> identifier,
                           OvsdbTerminationPointAugmentation tpOld) {
+        if (interfaceMgrProvider.isItmDirectTunnelsEnabled()
+                && interfaceManagerCommonUtils.isTunnelInternal(tpOld.getName())) {
+            LOG.debug("ITM Direct Tunnels is enabled, hence ignoring termination point add for internal tunnel {}",
+                    tpOld.getName());
+            return;
+        }
         LOG.debug("Received remove DataChange Notification for ovsdb termination point {}", tpOld.getName());
+
+        String oldInterfaceName = SouthboundUtils.getExternalInterfaceIdValue(tpOld);
+        if (oldInterfaceName == null && InterfaceManagerCommonUtils.isTunnelPort(tpOld.getName())) {
+            interfaceMgrProvider.removeTerminationPointForInterface(tpOld.getName());
+            interfaceMgrProvider.removeNodeIidForInterface(tpOld.getName());
+        } else {
+            interfaceMgrProvider.removeTerminationPointForInterface(oldInterfaceName);
+            interfaceMgrProvider.removeNodeIidForInterface(oldInterfaceName);
+        }
         if (tpOld.getInterfaceBfdStatus() != null) {
             LOG.debug("Received termination point removed notification with bfd status values {}", tpOld.getName());
-            DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
             RendererStateRemoveWorker rendererStateRemoveWorker = new RendererStateRemoveWorker(tpOld);
-            jobCoordinator.enqueueJob(tpOld.getName(), rendererStateRemoveWorker);
+            coordinator.enqueueJob(tpOld.getName(), rendererStateRemoveWorker);
         }
     }
 
@@ -74,72 +119,94 @@ public class TerminationPointStateListener extends AsyncClusteredDataTreeChangeL
     protected void update(InstanceIdentifier<OvsdbTerminationPointAugmentation> identifier,
                           OvsdbTerminationPointAugmentation tpOld,
                           OvsdbTerminationPointAugmentation tpNew) {
+        if (interfaceMgrProvider.isItmDirectTunnelsEnabled()
+                && interfaceManagerCommonUtils.isTunnelInternal(tpNew.getName())) {
+            LOG.debug("ITM Direct Tunnels is enabled, hence ignoring termination point update - "
+                    + "old {}, new {} internal tunnel", tpOld.getName(), tpNew.getName());
+            return;
+        }
+
         LOG.debug("Received Update DataChange Notification for ovsdb termination point {}", tpNew.getName());
-        if (tpNew.getInterfaceBfdStatus() != null && (tpOld == null ||
-                !tpNew.getInterfaceBfdStatus().equals(tpOld.getInterfaceBfdStatus()))) {
-            LOG.trace("Bfd Status changed for ovsdb termination point identifier: {},  old: {}, new: {}.",
-                    identifier, tpOld, tpNew);
-            DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
-            RendererStateUpdateWorker rendererStateAddWorker = new RendererStateUpdateWorker(identifier, tpNew);
-            jobCoordinator.enqueueJob(tpNew.getName(), rendererStateAddWorker, IfmConstants.JOB_MAX_RETRIES);
+        if (tpOld != null) {
+            if ((org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils
+                    .bfdMonitoringEnabled(tpNew.getInterfaceBfd())
+                    != org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils
+                    .bfdMonitoringEnabled(tpOld.getInterfaceBfd()))
+                    || (tpNew.getInterfaceBfdStatus() != null
+                    && !tpNew.getInterfaceBfdStatus().equals(tpOld.getInterfaceBfdStatus()))) {
+                LOG.info("Bfd Status changed for ovsdb termination point identifier: {},  old: {}, new: {}.",
+                        identifier, tpOld, tpNew);
+                RendererStateUpdateWorker rendererStateAddWorker = new RendererStateUpdateWorker(tpNew);
+                coordinator.enqueueJob(tpNew.getName(), rendererStateAddWorker, IfmConstants.JOB_MAX_RETRIES);
+            }
+        }
+        InstanceIdentifier<Node> nodeIid = identifier.firstIdentifierOf(Node.class);
+        String newInterfaceName = SouthboundUtils.getExternalInterfaceIdValue(tpNew);
+        if (newInterfaceName == null && InterfaceManagerCommonUtils.isTunnelPort(tpNew.getName())) {
+            interfaceMgrProvider.addTerminationPointForInterface(tpNew.getName(), tpNew);
+            interfaceMgrProvider.addNodeIidForInterface(tpNew.getName(), nodeIid);
+        } else {
+            interfaceMgrProvider.addTerminationPointForInterface(newInterfaceName, tpNew);
+            interfaceMgrProvider.addNodeIidForInterface(newInterfaceName, nodeIid);
         }
 
-        IfmClusterUtils.runOnlyInLeaderNode(() -> {
+        // skip parent-refs updation for interfaces with external-id for tunnels
+        if (!org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils.isInterfaceTypeTunnel(
+            tpNew.getInterfaceType())) {
+            if (!entityOwnershipUtils.isEntityOwner(IfmConstants.INTERFACE_CONFIG_ENTITY,
+                    IfmConstants.INTERFACE_CONFIG_ENTITY)) {
+                return;
+            }
+            String dpnId = interfaceMgrProvider.getDpidForInterface(newInterfaceName, nodeIid);
             String oldInterfaceName = SouthboundUtils.getExternalInterfaceIdValue(tpOld);
-            String newInterfaceName = SouthboundUtils.getExternalInterfaceIdValue(tpNew);
-            if (newInterfaceName != null && (oldInterfaceName == null || !oldInterfaceName.equals(newInterfaceName))) {
-                InstanceIdentifier<Node> nodeInstanceId = identifier.firstIdentifierOf(Node.class);
-                String dpnId = southboundUtils.getDatapathIdFromNodeInstanceId(nodeInstanceId);
-                if (dpnId == null) {
-                    return;
-                }
-                String parentRefName = InterfaceManagerCommonUtils.getPortNameForInterface(dpnId, tpNew.getName());
+            if (dpnId != null && newInterfaceName != null && (oldInterfaceName == null
+                || !oldInterfaceName.equals(newInterfaceName))) {
+                String parentRefName =
+                        InterfaceManagerCommonUtils.getPortNameForInterface(dpnId, tpNew.getName());
                 LOG.debug("Detected update to termination point {} with external ID {}, updating parent ref "
-                        + "of that interface ID to this termination point's interface-state name {}",
-                        tpNew.getName(), newInterfaceName, parentRefName);
+                    + "of that interface ID to this termination point's interface-state name {}", tpNew.getName(),
+                    newInterfaceName, parentRefName);
                 interfaceMgrProvider.updateInterfaceParentRef(newInterfaceName, parentRefName);
             }
-        });
+        }
     }
 
     @Override
     protected void add(InstanceIdentifier<OvsdbTerminationPointAugmentation> identifier,
                        OvsdbTerminationPointAugmentation tpNew) {
+        if (interfaceMgrProvider.isItmDirectTunnelsEnabled()
+                && interfaceManagerCommonUtils.isTunnelInternal(tpNew.getName())) {
+            LOG.debug("ITM Direct Tunnels is enabled, hence ignoring termination point add for internal tunnel {}",
+                    tpNew.getName());
+            return;
+        }
         update(identifier, null, tpNew);
     }
 
     private class RendererStateUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
-        InstanceIdentifier<OvsdbTerminationPointAugmentation> instanceIdentifier;
         OvsdbTerminationPointAugmentation terminationPointNew;
 
-
-        public RendererStateUpdateWorker(InstanceIdentifier<OvsdbTerminationPointAugmentation> instanceIdentifier,
-                                         OvsdbTerminationPointAugmentation tpNew) {
-            this.instanceIdentifier = instanceIdentifier;
+        RendererStateUpdateWorker(OvsdbTerminationPointAugmentation tpNew) {
             this.terminationPointNew = tpNew;
         }
 
         @Override
         public List<ListenableFuture<Void>> call() {
-            // If another renderer(for eg : CSS) needs to be supported, check can be performed here
-            // to call the respective helpers.
-            return OvsInterfaceTopologyStateUpdateHelper.updateTunnelState(dataBroker,
-                    terminationPointNew);
+            return ovsInterfaceTopologyStateUpdateHelper.updateTunnelState(terminationPointNew);
         }
     }
 
     private class RendererStateRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
         OvsdbTerminationPointAugmentation terminationPointOld;
 
-
-        public RendererStateRemoveWorker(OvsdbTerminationPointAugmentation tpNew) {
+        RendererStateRemoveWorker(OvsdbTerminationPointAugmentation tpNew) {
             this.terminationPointOld = tpNew;
         }
 
         @Override
         public List<ListenableFuture<Void>> call() {
             LOG.debug("Removing bfd state from cache, if any, for {}", terminationPointOld.getName());
-            InterfaceManagerCommonUtils.removeBfdStateFromCache(terminationPointOld.getName());
+            interfaceManagerCommonUtils.removeBfdStateFromCache(terminationPointOld.getName());
             return null;
         }
     }