GENIUS-266: Deletion of OF-Port along with status 26/82926/8
authorApurba Mukherjee <apurba.mukherjee@ericsson.com>
Thu, 4 Jul 2019 06:42:18 +0000 (12:12 +0530)
committerFaseela K <faseela.k@ericsson.com>
Thu, 1 Aug 2019 09:56:51 +0000 (09:56 +0000)
- takes care of deleting of-Port
- takes case of deleting tunnels to and from this port
- takes care of deleting ingress and egress flows

Change-Id: I8d42b02134d163e5ebf6b18aa7734cc65237ab33
Signed-off-by: Apurba Mukherjee <apurba.mukherjee@ericsson.com>
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmInternalTunnelAddWorker.java
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmInternalTunnelDeleteWorker.java
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/itmdirecttunnels/listeners/TunnelInventoryStateListener.java
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/listeners/TransportZoneListener.java
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/recovery/impl/ItmTepInstanceRecoveryHandler.java
itm/itm-impl/src/test/java/org/opendaylight/genius/itm/impl/ItmInternalTunnelDeleteTest.java

index a625af78b756960af41337fa8e247a033400b67e..542ae3f5f99e2606b75db95f53c27e4099246e02 100644 (file)
@@ -424,7 +424,7 @@ public final class ItmInternalTunnelAddWorker {
                                 .child(OvsBridgeRefEntry.class, new OvsBridgeRefEntryKey(dpId)).build();
 
                 eventCallbacks.onAdd(LogicalDatastoreType.OPERATIONAL, bridgeRefEntryFromDS, (refEntryIid) -> {
-                    addPortToBridgeOnCallback(iface, iface.getName(), refEntryIid);
+                    addPortToBridgeOnCallback(iface, tunnelName, refEntryIid);
                     return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
                 }, Duration.ofMillis(5000), (id) -> {
                         try {
index 787c81256e85c4e0672f736578083aa24400e79b..ca1a5ea8a6fbb4cfd889b05b8ed9fdf585c85354 100644 (file)
@@ -29,6 +29,7 @@ import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.infra.TypedWriteTransaction;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.itm.cache.DpnTepStateCache;
+import org.opendaylight.genius.itm.cache.OfEndPointCache;
 import org.opendaylight.genius.itm.cache.OvsBridgeEntryCache;
 import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache;
 import org.opendaylight.genius.itm.cache.TunnelStateCache;
@@ -48,6 +49,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.OvsBridgeEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.OvsBridgeEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.ovs.bridge.entry.OvsBridgeTunnelEntry;
@@ -85,6 +87,8 @@ public class ItmInternalTunnelDeleteWorker {
     private final OvsBridgeRefEntryCache ovsBridgeRefEntryCache;
     private final TunnelStateCache tunnelStateCache;
     private final DirectTunnelUtils directTunnelUtils;
+    private final OfEndPointCache ofEndPointCache;
+    private final ItmConfig itmConfig;
 
     public ItmInternalTunnelDeleteWorker(DataBroker dataBroker, JobCoordinator jobCoordinator,
                                          TunnelMonitoringConfig tunnelMonitoringConfig,
@@ -92,7 +96,9 @@ public class ItmInternalTunnelDeleteWorker {
                                          OvsBridgeEntryCache ovsBridgeEntryCache,
                                          OvsBridgeRefEntryCache ovsBridgeRefEntryCache,
                                          TunnelStateCache tunnelStateCache,
-                                         DirectTunnelUtils directTunnelUtils) {
+                                         DirectTunnelUtils directTunnelUtils,
+                                         OfEndPointCache ofEndPointCache,
+                                         ItmConfig itmConfig) {
         this.dataBroker = dataBroker;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.jobCoordinator = jobCoordinator;
@@ -103,6 +109,8 @@ public class ItmInternalTunnelDeleteWorker {
         this.ovsBridgeRefEntryCache = ovsBridgeRefEntryCache;
         this.tunnelStateCache = tunnelStateCache;
         this.directTunnelUtils = directTunnelUtils;
+        this.ofEndPointCache = ofEndPointCache;
+        this.itmConfig = itmConfig;
     }
 
     @SuppressWarnings("checkstyle:IllegalCatch")
@@ -170,6 +178,7 @@ public class ItmInternalTunnelDeleteWorker {
                             }
                         }
                     }
+
                     for (DPNTEPsInfo dstDpn : meshedDpnList) {
                         // Second, take care of Tep TZ membership and identify if tep can be removed
                         if (Objects.equals(srcDpn.getDPNID(), dstDpn.getDPNID())) {
@@ -435,39 +444,52 @@ public class ItmInternalTunnelDeleteWorker {
             return;
         }
 
-        Optional<OvsBridgeRefEntry> ovsBridgeRefEntryOptional = ovsBridgeRefEntryCache.get(dpId);
-        Optional<OvsBridgeEntry> ovsBridgeEntryOptional;
-        OvsdbBridgeRef ovsdbBridgeRef = null;
-        if (ovsBridgeRefEntryOptional.isPresent()) {
-            ovsdbBridgeRef = ovsBridgeRefEntryOptional.get().getOvsBridgeReference();
-        } else {
-            ovsBridgeEntryOptional = ovsBridgeEntryCache.get(dpId);
-            if (ovsBridgeEntryOptional.isPresent()) {
-                ovsdbBridgeRef = ovsBridgeEntryOptional.get().getOvsBridgeReference();
-            }
-        }
-
-        if (ovsdbBridgeRef != null) {
-            removeTerminationEndPoint(ovsdbBridgeRef.getValue(), interfaceName);
-        }
-
-        // delete tunnel ingress flow
-        removeTunnelIngressFlow(tx, interfaceName, dpId);
+        OvsdbBridgeRef ovsdbBridgeRef = getOvsdbBridgeRef(dpId);
+        Optional<OvsBridgeEntry> ovsBridgeEntryOptional = ovsBridgeEntryCache.get(dpId);
 
         // delete bridge to tunnel interface mappings
         OvsBridgeEntryKey bridgeEntryKey = new OvsBridgeEntryKey(dpId);
         InstanceIdentifier<OvsBridgeEntry> bridgeEntryIid =
                 DirectTunnelUtils.getOvsBridgeEntryIdentifier(bridgeEntryKey);
 
-        ovsBridgeEntryOptional = ovsBridgeEntryCache.get(dpId);
+
         if (ovsBridgeEntryOptional.isPresent()) {
             List<OvsBridgeTunnelEntry> bridgeTunnelEntries = ovsBridgeEntryOptional.get().nonnullOvsBridgeTunnelEntry();
+
+            if (ovsdbBridgeRef != null) {
+                if (!itmConfig.isUseOfTunnels()) {
+                    removeTerminationEndPoint(ovsdbBridgeRef.getValue(), interfaceName);
+                } else if (bridgeTunnelEntries.size() <= 1) {
+                    removeTerminationEndPoint(ovsdbBridgeRef.getValue(), ofEndPointCache.get(dpId));
+                    ofEndPointCache.remove(dpId);
+                }
+            }
+
             deleteBridgeInterfaceEntry(bridgeEntryKey, bridgeTunnelEntries, bridgeEntryIid, interfaceName);
             // IfIndex needs to be removed only during State Clean up not Config
-            // TunnelMetaUtils.removeLportTagInterfaceMap(idManager, defaultOperationalShardTransaction, interfaceName);
-            cleanUpInterfaceWithUnknownState(interfaceName, parentRefs, ifTunnel);
-            directTunnelUtils.removeLportTagInterfaceMap(interfaceName);
         }
+
+        directTunnelUtils.deleteTunnelStateEntry(interfaceName);
+        // delete tunnel ingress flow
+        removeTunnelIngressFlow(tx, interfaceName, dpId);
+        directTunnelUtils.removeTunnelEgressFlow(tx, dpId, interfaceName);
+        cleanUpInterfaceWithUnknownState(interfaceName, parentRefs, ifTunnel);
+        directTunnelUtils.removeLportTagInterfaceMap(interfaceName);
+    }
+
+    private OvsdbBridgeRef getOvsdbBridgeRef(BigInteger dpId) throws ReadFailedException {
+        Optional<OvsBridgeRefEntry> ovsBridgeRefEntryOptional = ovsBridgeRefEntryCache.get(dpId);
+        Optional<OvsBridgeEntry> ovsBridgeEntryOptional;
+        OvsdbBridgeRef ovsdbBridgeRef = null;
+        if (ovsBridgeRefEntryOptional.isPresent()) {
+            ovsdbBridgeRef = ovsBridgeRefEntryOptional.get().getOvsBridgeReference();
+        } else {
+            ovsBridgeEntryOptional = ovsBridgeEntryCache.get(dpId);
+            if (ovsBridgeEntryOptional.isPresent()) {
+                ovsdbBridgeRef = ovsBridgeEntryOptional.get().getOvsBridgeReference();
+            }
+        }
+        return ovsdbBridgeRef;
     }
 
     private void removeTerminationEndPoint(InstanceIdentifier<?> bridgeIid, String interfaceName) {
index d3af4c7b0852923dd9e01061693e391f0cf79b6e..7c2ec1cc241d47203029080596f041bb33a7e5d1 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.genius.itm.itmdirecttunnels.listeners;
 
-import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
 
 import com.google.common.util.concurrent.ListenableFuture;
@@ -110,12 +109,13 @@ public class TunnelInventoryStateListener extends
         String portName = flowCapableNodeConnector.getName();
         LOG.debug("InterfaceInventoryState Remove for {}", portName);
         // ITM Direct Tunnels Return if its not tunnel port and if its not Internal
-        if (!DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName)) {
+        if (!DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName) && !portName.startsWith("of")) {
             LOG.debug("Node Connector Remove - {} Interface is not a tunnel I/f, so no-op", portName);
             return;
         } else {
             try {
-                if (!tunnelStateCache.isInternalBasedOnState(portName)) {
+                if (DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName)
+                        && !tunnelStateCache.isInternalBasedOnState(portName)) {
                     LOG.debug("Node Connector Remove {} Interface is not a internal tunnel I/f, so no-op", portName);
                     return;
                 }
@@ -339,7 +339,7 @@ public class TunnelInventoryStateListener extends
         DpnTepInterfaceInfo dpnTepInfo,
         boolean opStateModified, String interfaceName, String portName,
         Interface.OperStatus opState) {
-        if (dpnTepInfo == null && !interfaceName.equals(portName)) {
+        if (dpnTepInfo == null && !portName.startsWith("of") && !interfaceName.equals(portName)) {
             return;
         }
         LOG.debug("updating interface state entry for {}", interfaceName);
@@ -368,8 +368,9 @@ public class TunnelInventoryStateListener extends
                                                                            String interfaceName,
                                                                            FlowCapableNodeConnector
                                                                                    flowCapableNodeConnector) {
-        List<ListenableFuture<Void>> futures = new ArrayList<>();
 
+
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
         BigInteger dpId = DirectTunnelUtils.getDpnFromNodeConnectorId(nodeConnectorId);
         // In a genuine port delete scenario, the reason will be there in the incoming event, for all remaining
         // cases treat the event as DPN disconnect, if old and new ports are same. Else, this is a VM migration
@@ -377,22 +378,32 @@ public class TunnelInventoryStateListener extends
         if (flowCapableNodeConnector.getReason() != PortReason.Delete) {
             //Remove event is because of connection lost between controller and switch, or switch shutdown.
             // Hence, dont remove the interface but set the status as "unknown"
-            futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
-                tx -> updateInterfaceStateOnNodeRemove(tx, interfaceName, flowCapableNodeConnector)));
-        } else {
-            LOG.debug("removing interface state for interface: {}", interfaceName);
-            directTunnelUtils.deleteTunnelStateEntry(interfaceName);
-            DpnTepInterfaceInfo dpnTepInfo = dpnTepStateCache.getTunnelFromCache(interfaceName);
-            if (dpnTepInfo != null) {
-                futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
-                    // Do if-index and ingress flow clean-up only for tunnel-interfaces
-                    directTunnelUtils.removeLportTagInterfaceMap(interfaceName);
-                    directTunnelUtils.removeTunnelIngressFlow(tx, dpId, interfaceName);
-                    directTunnelUtils.removeTunnelEgressFlow(tx, dpId, interfaceName);
-                }));
+            if (interfaceName.startsWith("of")) {
+                LOG.debug("Received remove state for dpid {}", dpId.intValue());
+                for (Map.Entry<String, NodeConnectorInfo> entry : meshedMap.entrySet()) {
+                    if (!dpId.toString().equals(entry.getKey())) {
+                        String fwdTunnel = dpnTepStateCache.getDpnTepInterface(dpId, new BigInteger(entry.getKey()))
+                                .getTunnelName();
+                        LOG.debug("Fwd Tunnel name for {} : {} is {}", dpId.intValue(), entry.getKey(), fwdTunnel);
+                        futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
+                            tx -> updateInterfaceStateOnNodeRemove(tx, fwdTunnel, flowCapableNodeConnector)));
+                        String bwdTunnel = dpnTepStateCache.getDpnTepInterface(new BigInteger(entry.getKey()), dpId)
+                                .getTunnelName();
+                        LOG.debug("Bwd Tunnel name for {} : {} is {}", entry.getKey(), dpId.intValue(), bwdTunnel);
+                        futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
+                            tx -> updateInterfaceStateOnNodeRemove(tx, bwdTunnel,
+                                    entry.getValue().getNodeConnector())));
+                    }
+                }
             } else {
-                LOG.error("DPNTEPInfo is null for Tunnel Interface {}", interfaceName);
+                futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
+                    tx -> updateInterfaceStateOnNodeRemove(tx, interfaceName, flowCapableNodeConnector)));
             }
+
+        } else {
+            LOG.debug("removing interface state for interface: {}", interfaceName);
+            // removing interfaces are already done in delete worker
+            meshedMap.remove(dpId.toString());
         }
         return futures;
     }
index 03a4d08b5841c28d0966aaa61328fa4c96139039..4b7ac014ac8e95c59bda3b673c1c60e5eb84077a 100644 (file)
@@ -123,7 +123,7 @@ public class TransportZoneListener extends AbstractSyncDataTreeChangeListener<Tr
         initializeTZNode();
         this.itmInternalTunnelDeleteWorker = new ItmInternalTunnelDeleteWorker(dataBroker, jobCoordinator,
                 tunnelMonitoringConfig, interfaceManager, dpnTepStateCache, ovsBridgeEntryCache,
-                ovsBridgeRefEntryCache, tunnelStateCache, directTunnelUtils);
+                ovsBridgeRefEntryCache, tunnelStateCache, directTunnelUtils, ofEndPointCache, itmConfig);
         this.itmInternalTunnelAddWorker = new ItmInternalTunnelAddWorker(dataBroker, jobCoordinator,
                 tunnelMonitoringConfig, itmConfig, directTunnelUtils, interfaceManager,
                 ovsBridgeRefEntryCache, ofEndPointCache, eventCallbacks);
index 5c166367a3a87d9bfa74718eeef7f3436bfe397c..d0bc3a085b70855dfe231d967d04980103a56791 100644 (file)
@@ -102,7 +102,7 @@ public class ItmTepInstanceRecoveryHandler implements ServiceRecoveryInterface {
                 dpntePsInfoCache);
         this.itmInternalTunnelDeleteWorker = new ItmInternalTunnelDeleteWorker(dataBroker, jobCoordinator,
                 tunnelMonitoringConfig, interfaceManager, dpnTepStateCache, ovsBridgeEntryCache,
-                ovsBridgeRefEntryCache, tunnelStateCache, directTunnelUtils);
+                ovsBridgeRefEntryCache, tunnelStateCache, directTunnelUtils, ofEndPointCache, itmConfig);
         serviceRecoveryRegistry.registerServiceRecoveryRegistry(getServiceRegistryKey(), this);
     }
 
index b7512a260fc583520e49384c2c18e21e61b7411c..ad518e997479796f1048478105f22a6d70081369 100644 (file)
@@ -30,6 +30,7 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
 import org.opendaylight.genius.itm.cache.DpnTepStateCache;
+import org.opendaylight.genius.itm.cache.OfEndPointCache;
 import org.opendaylight.genius.itm.cache.OvsBridgeEntryCache;
 import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache;
 import org.opendaylight.genius.itm.cache.TunnelStateCache;
@@ -125,6 +126,7 @@ public class ItmInternalTunnelDeleteTest {
     ItmInternalTunnelDeleteWorker itmInternalTunnelDeleteWorker;
     UnprocessedNodeConnectorCache unprocessedNodeConnectorCache;
     UnprocessedNodeConnectorEndPointCache unprocessedNodeConnectorEndPointCache;
+    OfEndPointCache ofEndPointCache;
 
 
     Optional<TunnelMonitorParams> tunnelMonitorParamsOptional;
@@ -168,7 +170,7 @@ public class ItmInternalTunnelDeleteTest {
             new OvsBridgeEntryCache(dataBroker, new GuavaCacheProvider(new CacheManagersRegistryImpl())),
             new OvsBridgeRefEntryCache(dataBroker, new GuavaCacheProvider(new CacheManagersRegistryImpl())),
             new TunnelStateCache(dataBroker, new GuavaCacheProvider(new CacheManagersRegistryImpl())),
-            directTunnelUtils);
+            directTunnelUtils, ofEndPointCache, itmConfig);
     }
 
     @After
@@ -210,6 +212,7 @@ public class ItmInternalTunnelDeleteTest {
         doReturn(mockReadWriteTx).when(dataBroker).newReadWriteTransaction();
         lenient().doReturn(Futures.immediateCheckedFuture(null)).when(mockReadWriteTx).submit();
         doReturn(true).when(mockReadWriteTx).cancel();
+        lenient().doReturn(false).when(itmConfig).isUseOfTunnels();
     }
 
     // Since all the unit test cases will be written to the new way, this should be taken care then.