OF port deletion complete implementation 58/90958/13
authorApurba Mukherjee <apurba.mukherjee@ericsson.com>
Tue, 7 Jul 2020 16:16:52 +0000 (21:46 +0530)
committerApurba Mukherjee <apurba.mukherjee@ericsson.com>
Mon, 17 Aug 2020 10:56:10 +0000 (16:26 +0530)
Change-Id: I485909dd804b049808366c0374a35a3a41511f0e
Signed-off-by: Apurba Mukherjee <apurba.mukherjee@ericsson.com>
16 files changed:
interfacemanager/interfacemanager-api/src/main/java/org/opendaylight/genius/interfacemanager/interfaces/IInterfaceManager.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/InterfacemgrProvider.java
interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/listeners/InternalTunnelCache.java [new file with mode: 0644]
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/cache/OfTepStateCache.java
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/confighelpers/ItmOfPortRemoveWorker.java
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/confighelpers/ItmOfTunnelDeleteWorker.java
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/impl/ItmUtils.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/itmdirecttunnels/renderer/ovs/utilities/DirectTunnelUtils.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/main/java/org/opendaylight/genius/itm/servicebinding/BindServiceUtils.java
itm/itm-impl/src/test/java/org/opendaylight/genius/itm/impl/ItmInternalTunnelDeleteTest.java
itm/itm-impl/src/test/java/org/opendaylight/genius/itm/impl/ItmManagerRpcServiceTest.java

index 9b92e748f097f119e9432b0d3cf101b345e83c64..7f405094ec9a4778d030f39ac118b0d056c7b095 100644 (file)
@@ -195,4 +195,13 @@ public interface IInterfaceManager {
     Map getBridgeRefEntryMap();
 
     boolean isItmOfTunnelsEnabled();
+
+    void addInternalTunnelToCache(String tunnelName, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+            .ietf.interfaces.rev140508.interfaces.state.Interface iface);
+
+    org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
+        getInternalTunnelCacheInfo(String tunnelName);
+
+    org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
+        removeInternalTunnelFromCache(String tunnelName);
 }
index 227a274c6af1799468c02e352b5641a0550793e6..1cac89ef9c47364ed19bb8747e76c0c1aa9b75c3 100644 (file)
@@ -32,6 +32,7 @@ import org.opendaylight.genius.interfacemanager.exceptions.InterfaceAlreadyExist
 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceAdminState;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
+import org.opendaylight.genius.interfacemanager.listeners.InternalTunnelCache;
 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
 import org.opendaylight.genius.interfacemanager.rpcservice.InterfaceManagerRpcService;
 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
@@ -119,6 +120,7 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
     private Map<InstanceIdentifier<Node>, OvsdbBridgeAugmentation> nodeIidToBridgeMap;
     private EntityOwnershipCandidateRegistration configEntityCandidate;
     private EntityOwnershipCandidateRegistration bindingEntityCandidate;
+    private InternalTunnelCache internalTunnelCache;
 
     @Inject
     public InterfacemgrProvider(@Reference final DataBroker dataBroker,
@@ -129,7 +131,8 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
                                 final InterfaceManagerCommonUtils interfaceManagerCommonUtils,
                                 final InterfaceMetaUtils interfaceMetaUtils,
                                 final IfmConfig ifmConfig,
-                                final IfmDiagStatusProvider ifmStatusProvider) {
+                                final IfmDiagStatusProvider ifmStatusProvider,
+                                final InternalTunnelCache internalTunnelCache) {
         this.dataBroker = dataBroker;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.entityOwnershipService = entityOwnershipService;
@@ -140,6 +143,7 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         this.interfaceMetaUtils = interfaceMetaUtils;
         this.ifmConfig = ifmConfig;
         this.ifmStatusProvider = ifmStatusProvider;
+        this.internalTunnelCache = internalTunnelCache;
         start();
     }
 
@@ -899,4 +903,22 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
     public boolean isItmOfTunnelsEnabled() {
         return ifmConfig.isItmOfTunnels();
     }
+
+    @Override
+    public void addInternalTunnelToCache(String tunnelName, org.opendaylight.yang.gen.v1.urn.ietf.params
+            .xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface iface) {
+        internalTunnelCache.add(tunnelName,iface);
+    }
+
+    @Override
+    public org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
+            .rev140508.interfaces.state.Interface getInternalTunnelCacheInfo(String tunnelName) {
+        return internalTunnelCache.get(tunnelName);
+    }
+
+    @Override
+    public org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
+            .rev140508.interfaces.state.Interface removeInternalTunnelFromCache(String tunnelName) {
+        return internalTunnelCache.remove(tunnelName);
+    }
 }
diff --git a/interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/listeners/InternalTunnelCache.java b/interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/listeners/InternalTunnelCache.java
new file mode 100644 (file)
index 0000000..a43ea0a
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2020 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.genius.interfacemanager.listeners;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.inject.Singleton;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+
+
+@Singleton
+public class InternalTunnelCache {
+
+    private volatile ConcurrentMap<String, Interface> internalTunnelCache = new ConcurrentHashMap<>();
+
+    public synchronized void add(String tunnelName, Interface iface) {
+        internalTunnelCache.putIfAbsent(tunnelName, iface);
+    }
+
+    public synchronized Interface get(String tunnelName) {
+        return internalTunnelCache.get(tunnelName);
+    }
+
+    public synchronized Interface remove(String tunnelName) {
+        return internalTunnelCache.remove(tunnelName);
+    }
+}
index e89e94d6584e9317d1481ba49a75bee93c186798..1fbed8d9e3f9cd3360db596bb67087b613953d49 100644 (file)
@@ -14,11 +14,17 @@ import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
+import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
 import org.opendaylight.genius.itm.servicebinding.BindServiceUtils;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.cache.DataObjectCache;
 import org.opendaylight.infrautils.caches.CacheProvider;
 import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.Tunnel;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.OfTepsState;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTep;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTepKey;
@@ -31,22 +37,45 @@ import org.slf4j.LoggerFactory;
 public class OfTepStateCache extends DataObjectCache<String, OfTep> {
 
     private final ManagedNewTransactionRunner txRunner;
+    private final IInterfaceManager interfaceManager;
+    private final DirectTunnelUtils directTunnelUtils;
     List<ListenableFuture<Void>> futures = new ArrayList<>();
     private static final Logger LOG = LoggerFactory.getLogger(OfTepStateCache.class);
 
     @Inject
-    public OfTepStateCache(DataBroker dataBroker, CacheProvider cacheProvider) {
+    public OfTepStateCache(DataBroker dataBroker, CacheProvider cacheProvider,
+                           IInterfaceManager interfaceManager, DirectTunnelUtils directTunnelUtils) {
         super(OfTep.class, dataBroker, LogicalDatastoreType.OPERATIONAL,
             InstanceIdentifier.builder(OfTepsState.class).child(OfTep.class).build(), cacheProvider,
             (iid, ofTepList) -> ofTepList.getOfPortName(), ofPortName -> InstanceIdentifier.builder(OfTepsState.class)
                     .child(OfTep.class, new OfTepKey(ofPortName)).build());
+        this.interfaceManager = interfaceManager;
+        this.directTunnelUtils = directTunnelUtils;
         this.txRunner =  new ManagedNewTransactionRunnerImpl(dataBroker);
     }
 
     protected void added(InstanceIdentifier<OfTep> path, OfTep ofTep) {
-        LOG.info("Binding default egress dispatcher service for{}", ofTep.getOfPortName());
-        BindServiceUtils.bindDefaultEgressDispatcherService(txRunner, futures, "VXLAN_TRUNK_INTERFACE",
-                String.valueOf(ofTep.getPortNumber()), ofTep.getOfPortName(),
-                ofTep.getIfIndex());
+        LOG.debug("Adding interface name to internal cache.");
+        List<String> childLowerLayerIfList = new ArrayList<>();
+        String lowref = MDSALUtil.NODE_PREFIX + MDSALUtil.SEPARATOR + ofTep.getSourceDpnId()
+                + MDSALUtil.SEPARATOR + ofTep.getPortNumber();
+        childLowerLayerIfList.add(0, lowref);
+        InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setIfIndex(ofTep.getIfIndex().intValue())
+                .withKey(new InterfaceKey(ofTep.getOfPortName()))
+                .setLowerLayerIf(childLowerLayerIfList).setType(Tunnel.class)
+                .setName(ofTep.getOfPortName());
+        interfaceManager.addInternalTunnelToCache(ofTep.getOfPortName(), ifaceBuilder.build());
+
+        if (directTunnelUtils.isEntityOwner()) {
+            LOG.info("Binding default egress dispatcher service for{}", ofTep.getOfPortName());
+            BindServiceUtils.bindDefaultEgressDispatcherService(txRunner, futures, "VXLAN_TRUNK_INTERFACE",
+                    String.valueOf(ofTep.getPortNumber()), ofTep.getOfPortName(),
+                    ofTep.getIfIndex());
+        }
+    }
+
+    protected void removed(InstanceIdentifier<OfTep> path, OfTep ofTep) {
+        BindServiceUtils.unbindService(futures, txRunner, ofTep.getOfPortName());
+        interfaceManager.removeInternalTunnelFromCache(ofTep.getOfPortName());
     }
 }
index 4eb7376f589b552e696687e5f32cef2d847c8f07..5eebf4fdf3a0aea738a5e5a3663f8b26250a7731 100644 (file)
@@ -12,10 +12,11 @@ import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
 
 import com.google.common.util.concurrent.ListenableFuture;
 import java.time.Duration;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.concurrent.Callable;
@@ -61,6 +62,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.Dpn
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.DpnsTeps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.DpnsTepsBuilder;
@@ -73,6 +75,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tun
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.OperationFailedException;
+import org.opendaylight.yangtools.yang.common.Uint16;
 import org.opendaylight.yangtools.yang.common.Uint64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -143,10 +146,12 @@ public final class ItmInternalTunnelAddWorker {
         DirectTunnelUtils directTunnelUtils) throws ExecutionException, InterruptedException, OperationFailedException {
         LOG.debug("Updating CONFIGURATION datastore with DPN {} ", dpn);
         InstanceIdentifier<DpnEndpoints> dep = InstanceIdentifier.create(DpnEndpoints.class) ;
-        List<DPNTEPsInfo> dpnList = new ArrayList<>() ;
-        dpnList.add(new DPNTEPsInfoBuilder(dpn)
-            .setDstId(directTunnelUtils.allocateId(ITMConstants.ITM_IDPOOL_NAME, dpn.getDPNID().toString())).build());
-        DpnEndpoints tnlBuilder = new DpnEndpointsBuilder().setDPNTEPsInfo(dpnList).build() ;
+        Map<DPNTEPsInfoKey, DPNTEPsInfo> dpnMap = new HashMap<>() ;
+        DPNTEPsInfo info = new DPNTEPsInfoBuilder(dpn)
+                .setDstId(directTunnelUtils
+                        .allocateId(ITMConstants.ITM_IDPOOL_NAME, dpn.getDPNID().toString())).build();
+        dpnMap.put(info.key(), info);
+        DpnEndpoints tnlBuilder = new DpnEndpointsBuilder().setDPNTEPsInfo(dpnMap).build() ;
         tx.merge(dep, tnlBuilder);
     }
 
@@ -342,42 +347,36 @@ public final class ItmInternalTunnelAddWorker {
                         + " destination IP - {} gateway IP - {}", trunkInterfaceName, parentInterfaceName,
                 srcte.getIpAddress(), dstte.getIpAddress(), gwyIpAddress) ;
 
-        boolean useOfTunnel = itmCfg.isUseOfTunnels();
+        //boolean useOfTunnel = itmCfg.isUseOfTunnels();
 
         List<TunnelOptions> tunOptions = ItmUtils.buildTunnelOptions(srcte, itmCfg);
         Boolean isMonitorEnabled = !tunType.isAssignableFrom(TunnelTypeLogicalGroup.class) && isTunnelMonitoringEnabled;
         Interface iface = ItmUtils.buildTunnelInterface(srcDpnId, trunkInterfaceName,
                 trunkInterfaceDecription(ItmUtils.convertTunnelTypetoString(srcte.getTunnelType())),
                 true, tunType, srcte.getIpAddress(), dstte.getIpAddress(), true,
-                isMonitorEnabled, monitorProtocol, monitorInterval, useOfTunnel, parentInterfaceName, tunOptions);
+                isMonitorEnabled, monitorProtocol, monitorInterval, false, parentInterfaceName, tunOptions);
         LOG.debug("Trunk Interface builder - {} ", iface);
 
         final DpnTepsStateBuilder dpnTepsStateBuilder = new DpnTepsStateBuilder();
         final DpnsTepsBuilder dpnsTepsBuilder = new DpnsTepsBuilder();
-        final List<DpnsTeps> dpnTeps = new ArrayList<>();
-        final List<RemoteDpns> remoteDpns = new ArrayList<>();
-        String ofTunnelPortName = null;
+        final Map<DpnsTepsKey, DpnsTeps> dpnTeps = new HashMap<>();
+        final Map<RemoteDpnsKey, RemoteDpns> remoteDpns = new HashMap<>();
         dpnsTepsBuilder.withKey(new DpnsTepsKey(srcDpnId));
         dpnsTepsBuilder.setTunnelType(srcte.getTunnelType());
         dpnsTepsBuilder.setSourceDpnId(srcDpnId);
-        if (useOfTunnel) {
-            String tunnelType = ItmUtils.convertTunnelTypetoString(srcte.getTunnelType());
-            ofTunnelPortName = DirectTunnelUtils.generateOfPortName(srcDpnId, tunnelType);
-            dpnsTepsBuilder.setOfTunnel(ofTunnelPortName);
-        }
         RemoteDpnsBuilder remoteDpn = new RemoteDpnsBuilder();
         remoteDpn.withKey(new RemoteDpnsKey(dstDpnId));
         remoteDpn.setDestinationDpnId(dstDpnId);
         remoteDpn.setTunnelName(trunkInterfaceName);
         remoteDpn.setMonitoringEnabled(isTunnelMonitoringEnabled);
-        remoteDpn.setMonitoringInterval(monitorInterval);
+        remoteDpn.setMonitoringInterval(Uint16.valueOf(monitorInterval));
         remoteDpn.setInternal(true);
-        remoteDpns.add(remoteDpn.build());
+        remoteDpns.put(remoteDpn.key(),remoteDpn.build());
         dpnsTepsBuilder.setRemoteDpns(remoteDpns);
-        dpnTeps.add(dpnsTepsBuilder.build());
+        dpnTeps.put(dpnsTepsBuilder.key(), dpnsTepsBuilder.build());
         dpnTepsStateBuilder.setDpnsTeps(dpnTeps);
         updateDpnTepInterfaceInfoToConfig(dpnTepsStateBuilder.build());
-        addTunnelConfiguration(iface, ofTunnelPortName);
+        addTunnelConfiguration(iface, iface.getName());
     }
 
     private static void updateDpnTepInterfaceInfoToConfig(DpnTepsState dpnTeps) {
@@ -386,13 +385,13 @@ public final class ItmInternalTunnelAddWorker {
         ITMBatchingUtils.updateContainer(dpnTepsII, dpnTeps, ITMBatchingUtils.EntityType.DEFAULT_CONFIG);
     }
 
-    private void addTunnelConfiguration(Interface iface, String ofTunnelPortName)
-                                                                throws ReadFailedException {
+    private void addTunnelConfiguration(Interface iface, String tunnelName)
+            throws ReadFailedException {
         // ITM Direct Tunnels This transaction is not being used -- CHECK
         ParentRefs parentRefs = iface.augmentation(ParentRefs.class);
         if (parentRefs == null) {
             LOG.warn("ParentRefs for interface: {} Not Found. Creation of Tunnel OF-Port not supported"
-                    + " when dpid not provided.", iface.getName());
+                    + " when dpid not provided.", tunnelName);
             return;
         }
 
@@ -402,45 +401,39 @@ public final class ItmInternalTunnelAddWorker {
                     iface.getName());
             return;
         }
-        String tunnelName = ofTunnelPortName != null ? ofTunnelPortName : iface.getName();
         // create bridge on switch, if switch is connected
-        Optional<OvsBridgeRefEntry> ovsBridgeRefEntry = ovsBridgeRefEntryCache.get(dpId);
         LOG.info("adding tunnel port configuration for tunnelName: {}", tunnelName);
-        if (createTunnelPort(dpId)) {
-            LOG.debug("creating dpn tunnel mapping  for dpn: {} tunnelName: {}", dpId, tunnelName);
-            DirectTunnelUtils.createBridgeTunnelEntryInConfigDS(dpId, iface.getName());
-            if (ofTunnelPortName != null) {
-                ofEndPointCache.add(dpId, tunnelName);
-            }
-            if (ovsBridgeRefEntry.isPresent()) {
-                LOG.debug("creating bridge interface on dpn {}", dpId);
-                InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
-                        (InstanceIdentifier<OvsdbBridgeAugmentation>) ovsBridgeRefEntry.get()
-                                .getOvsBridgeReference().getValue();
-                LOG.debug("adding port to the bridge:{} tunnelName: {}", bridgeIid, tunnelName);
-                addPortToBridge(bridgeIid, iface, tunnelName);
-            } else {
-                LOG.debug("Bridge not found. Registering Eventcallback for dpid {}", dpId);
-
-                InstanceIdentifier<OvsBridgeRefEntry> bridgeRefEntryFromDS =
-                        InstanceIdentifier.builder(OvsBridgeRefInfo.class)
-                                .child(OvsBridgeRefEntry.class, new OvsBridgeRefEntryKey(dpId)).build();
-
-                eventCallbacks.onAdd(LogicalDatastoreType.OPERATIONAL, bridgeRefEntryFromDS, (refEntryIid) -> {
-                    addPortToBridgeOnCallback(iface, tunnelName, refEntryIid);
-                    return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
-                }, Duration.ofMillis(5000), (id) -> {
-                        try {
-                            Optional<OvsBridgeRefEntry> ovsBridgeRefEntryOnCallback = ovsBridgeRefEntryCache.get(dpId);
-                            InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIidOnCallback =
-                                    (InstanceIdentifier<OvsdbBridgeAugmentation>) ovsBridgeRefEntryOnCallback.get()
-                                            .getOvsBridgeReference().getValue();
-                            addPortToBridge(bridgeIidOnCallback, iface, tunnelName);
-                        }   catch (ReadFailedException e) {
-                            LOG.error("Bridge not found in DS/cache for dpId {}", dpId);
-                        }
-                    });
-            }
+        LOG.debug("creating dpn tunnel mapping  for dpn: {} tunnelName: {}", dpId, tunnelName);
+        Optional<OvsBridgeRefEntry> ovsBridgeRefEntry = ovsBridgeRefEntryCache.get(dpId);
+        DirectTunnelUtils.createBridgeTunnelEntryInConfigDS(dpId, iface.getName());
+        if (ovsBridgeRefEntry.isPresent()) {
+            LOG.debug("creating bridge interface on dpn {}", dpId);
+            InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
+                    (InstanceIdentifier<OvsdbBridgeAugmentation>) ovsBridgeRefEntry.get()
+                            .getOvsBridgeReference().getValue();
+            LOG.debug("adding port to the bridge:{} tunnelName: {}", bridgeIid, tunnelName);
+            addPortToBridge(bridgeIid, iface, tunnelName);
+        } else {
+            LOG.debug("Bridge not found. Registering Eventcallback for dpid {}", dpId);
+
+            InstanceIdentifier<OvsBridgeRefEntry> bridgeRefEntryFromDS =
+                    InstanceIdentifier.builder(OvsBridgeRefInfo.class)
+                            .child(OvsBridgeRefEntry.class, new OvsBridgeRefEntryKey(dpId)).build();
+
+            eventCallbacks.onAdd(LogicalDatastoreType.OPERATIONAL, bridgeRefEntryFromDS, (refEntryIid) -> {
+                addPortToBridgeOnCallback(iface, tunnelName, refEntryIid);
+                return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
+            }, Duration.ofMillis(5000), (id) -> {
+                    try {
+                        Optional<OvsBridgeRefEntry> ovsBridgeRefEntryOnCallback = ovsBridgeRefEntryCache.get(dpId);
+                        InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIidOnCallback =
+                                (InstanceIdentifier<OvsdbBridgeAugmentation>) ovsBridgeRefEntryOnCallback.get()
+                                        .getOvsBridgeReference().getValue();
+                        addPortToBridge(bridgeIidOnCallback, iface, tunnelName);
+                    }   catch (ReadFailedException e) {
+                        LOG.error("Bridge not found in DS/cache for dpId {}", dpId);
+                    }
+                });
         }
     }
 
@@ -451,13 +444,6 @@ public final class ItmInternalTunnelAddWorker {
         }
     }
 
-    private boolean createTunnelPort(Uint64 dpId) {
-        if (!itmCfg.isUseOfTunnels()) {
-            return true;
-        }
-        return ofEndPointCache.get(dpId) == null;
-    }
-
     private void addPortToBridgeOnCallback(Interface iface, String portName, OvsBridgeRefEntry bridgeRefEntry) {
         InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
                 (InstanceIdentifier<OvsdbBridgeAugmentation>) bridgeRefEntry.getOvsBridgeReference().getValue();
index e09a157723d8d771eee7d7354f3d2d38f47b6560..a330502ddec680dc605e355a43be053a51b24cd9 100644 (file)
@@ -23,7 +23,6 @@ import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.genius.cloudscaler.api.TombstonedNodeManager;
 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;
@@ -51,7 +50,6 @@ 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;
@@ -91,8 +89,6 @@ public class ItmInternalTunnelDeleteWorker {
     private final OvsBridgeRefEntryCache ovsBridgeRefEntryCache;
     private final TunnelStateCache tunnelStateCache;
     private final DirectTunnelUtils directTunnelUtils;
-    private final OfEndPointCache ofEndPointCache;
-    private final ItmConfig itmConfig;
     private final TombstonedNodeManager tombstonedNodeManager;
 
     public ItmInternalTunnelDeleteWorker(DataBroker dataBroker, JobCoordinator jobCoordinator,
@@ -102,8 +98,6 @@ public class ItmInternalTunnelDeleteWorker {
                                          OvsBridgeRefEntryCache ovsBridgeRefEntryCache,
                                          TunnelStateCache tunnelStateCache,
                                          DirectTunnelUtils directTunnelUtils,
-                                         OfEndPointCache ofEndPointCache,
-                                         ItmConfig itmConfig,
                                          TombstonedNodeManager tombstonedNodeManager) {
         this.dataBroker = dataBroker;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
@@ -115,8 +109,6 @@ public class ItmInternalTunnelDeleteWorker {
         this.ovsBridgeRefEntryCache = ovsBridgeRefEntryCache;
         this.tunnelStateCache = tunnelStateCache;
         this.directTunnelUtils = directTunnelUtils;
-        this.ofEndPointCache = ofEndPointCache;
-        this.itmConfig = itmConfig;
         this.tombstonedNodeManager = tombstonedNodeManager;
     }
 
@@ -136,7 +128,6 @@ public class ItmInternalTunnelDeleteWorker {
             }
             for (DPNTEPsInfo srcDpn : dpnTepsList) {
                 LOG.trace("Processing srcDpn {}", srcDpn);
-
                 List<TunnelEndPoints> meshedEndPtCache = ItmUtils.getTEPsForDpn(srcDpn.getDPNID(), meshedDpnList);
                 if (meshedEndPtCache == null) {
                     LOG.debug("No Tunnel End Point configured for this DPN {}", srcDpn.getDPNID());
@@ -471,53 +462,39 @@ public class ItmInternalTunnelDeleteWorker {
             return;
         }
 
-        OvsdbBridgeRef ovsdbBridgeRef = getOvsdbBridgeRef(dpId);
-        Optional<OvsBridgeEntry> ovsBridgeEntryOptional = ovsBridgeEntryCache.get(dpId);
+        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);
+        }
+        removeTunnelIngressFlow(tx, interfaceName, 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()) {
             @NonNull Map<OvsBridgeTunnelEntryKey, 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
+            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(Uint64 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 5d375ba11f04672229923347768aadea7d6178bd..3f06baf771fafc6a651c646cfb9a8c6126dda2ba 100644 (file)
@@ -9,20 +9,33 @@
 package org.opendaylight.genius.itm.confighelpers;
 
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
-import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTep;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTepKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class ItmOfPortRemoveWorker implements Callable<List<? extends ListenableFuture<?>>> {
-    public ItmOfPortRemoveWorker(Map<OfDpnTepKey, OfDpnTep> oldDpnTepList, DataBroker dataBroker,
+
+    private static final Logger LOG = LoggerFactory.getLogger(ItmOfPortRemoveWorker.class);
+
+    private Map<OfDpnTepKey, OfDpnTep> oldDpnTepMap;
+    private final ItmOfTunnelDeleteWorker itmOfTunnelDeleteWorker;
+
+    public ItmOfPortRemoveWorker(Map<OfDpnTepKey, OfDpnTep> oldDpnTepMap,
                                  ItmOfTunnelDeleteWorker itmOfTunnelDeleteWorker) {
+        this.itmOfTunnelDeleteWorker = itmOfTunnelDeleteWorker;
+        this.oldDpnTepMap = oldDpnTepMap;
     }
 
     @Override
-    public List<ListenableFuture<Void>> call() throws Exception {
-        return null;
+    public List<? extends ListenableFuture<?>> call() throws Exception {
+        List<ListenableFuture<?>> futures = new ArrayList<>();
+        futures.addAll(itmOfTunnelDeleteWorker.deleteOfTeps(oldDpnTepMap.values()));
+        LOG.debug("Invoking OfTep delete method with OfTep list to be deleted {}", oldDpnTepMap.values());
+        return futures;
     }
 }
index b1ecc3b54eb587c36cd8c2105a29738a6e2f1e19..67578bf2aae8c98dff88cdcd51f45eb13b4630aa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2019 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,
 
 package org.opendaylight.genius.itm.confighelpers;
 
-import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
+import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
+import org.opendaylight.genius.cloudscaler.api.TombstonedNodeManager;
+import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
+import org.opendaylight.genius.itm.cache.OfDpnTepConfigCache;
+import org.opendaylight.genius.itm.cache.OfTepStateCache;
+import org.opendaylight.genius.itm.cache.OvsBridgeEntryCache;
 import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache;
+import org.opendaylight.genius.itm.impl.ITMBatchingUtils;
 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
-import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.mdsal.binding.api.DataBroker;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
+import org.opendaylight.mdsal.binding.util.Datastore.Configuration;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.mdsal.binding.util.TypedReadWriteTransaction;
+import org.opendaylight.mdsal.common.api.ReadFailedException;
+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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.ovs.bridge.entry.OvsBridgeTunnelEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTep;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTep;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
+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.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.OperationFailedException;
+import org.opendaylight.yangtools.yang.common.Uint64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class ItmOfTunnelDeleteWorker {
-    public ItmOfTunnelDeleteWorker(DataBroker dataBroker, JobCoordinator jobCoordinator, ItmConfig itmConfig,
-                                   DirectTunnelUtils directTunnelUtils, OvsBridgeRefEntryCache ovsBridgeRefEntryCache,
-                                   DataTreeEventCallbackRegistrar eventCallbackRegistrar) {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ItmOfTunnelDeleteWorker.class);
+    private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger");
+
+    private final ManagedNewTransactionRunner txRunner;
+    private final DataBroker dataBroker;
+    private final OfDpnTepConfigCache ofDpnTepConfigCache;
+    private final TombstonedNodeManager tombstonedNodeManager;
+    private final IInterfaceManager interfaceManager;
+    private final DirectTunnelUtils directTunnelUtils;
+    private final OvsBridgeRefEntryCache ovsBridgeRefEntryCache;
+    private final OvsBridgeEntryCache ovsBridgeEntryCache;
+    private final OfTepStateCache ofTepStateCache;
+
+    public ItmOfTunnelDeleteWorker(DataBroker dataBroker,
+                                   OfDpnTepConfigCache ofDpnTepConfigCache,
+                                   TombstonedNodeManager tombstonedNodeManager,
+                                   IInterfaceManager interfaceManager,
+                                   DirectTunnelUtils directTunnelUtils,
+                                   OvsBridgeRefEntryCache ovsBridgeRefEntryCache,
+                                   OvsBridgeEntryCache ovsBridgeEntryCache,
+                                   OfTepStateCache ofTepStateCache) {
+        this.dataBroker = dataBroker;
+        this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+        this.ofDpnTepConfigCache = ofDpnTepConfigCache;
+        this.tombstonedNodeManager = tombstonedNodeManager;
+        this.interfaceManager = interfaceManager;
+        this.directTunnelUtils = directTunnelUtils;
+        this.ovsBridgeRefEntryCache = ovsBridgeRefEntryCache;
+        this.ovsBridgeEntryCache = ovsBridgeEntryCache;
+        this.ofTepStateCache = ofTepStateCache;
+    }
+
+    @SuppressWarnings("checkstyle:IllegalCatch")
+    public List<? extends ListenableFuture<?>> deleteOfTeps(Collection<OfDpnTep> ofTepsList) {
+        LOG.trace("OFTeps to be deleted {} " , ofTepsList);
+        return Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+            if (ofTepsList == null || ofTepsList.size() == 0) {
+                LOG.debug("no ofteps to delete");
+                return;
+            }
+
+            for (OfDpnTep srcDpn : ofTepsList) {
+                LOG.trace("Processing srcDpn {}", srcDpn);
+
+                Boolean isDpnTombstoned = tombstonedNodeManager.isDpnTombstoned(srcDpn.getSourceDpnId());
+
+                removeOfTepInterfaceFromOvsdb(srcDpn, tx);
+                if (isDpnTombstoned) {
+                    EVENT_LOGGER.debug("OfTep-DeleteWorker, Tombstoned, DpnTep for {} removed",
+                            srcDpn.getSourceDpnId());
+                    LOG.trace("Removing tunnelState entry for {} while tombstoned is set true",srcDpn.getSourceDpnId());
+                    removeOfTepState(srcDpn);
+                }
+                LOG.debug("Deleting OFTEP Interface information from Config datastore with DPNs-Tep "
+                        + "for source Dpn {}", srcDpn.getSourceDpnId());
+                // Clean up the DPNs TEP State DS
+                DirectTunnelUtils.removeOfTepFromDpnsTepConfigDS(dataBroker, srcDpn.getSourceDpnId());
+                EVENT_LOGGER.debug("OfTep-DeleteWorker, DpnTep for {} removed", srcDpn.getSourceDpnId());
+            }
+        }));
+    }
+
+    private void removeOfTepState(OfDpnTep srcDpn) {
+        LOG.trace("Removing ofTepstate for {} with tomstoned enable", srcDpn.getOfPortName());
+        directTunnelUtils.deleteOfTepStateEntry(srcDpn.getOfPortName());
+    }
+
+    private void removeOfTepInterfaceFromOvsdb(OfDpnTep dpnTep, TypedReadWriteTransaction<Configuration> tx) {
+        LOG.trace("Removing ofTep Interface {}", dpnTep.getOfPortName());
+        try {
+            removeConfiguration(dpnTep, tx);
+        } catch (ExecutionException | InterruptedException | OperationFailedException e) {
+            LOG.error("Cannot Delete Tunnel {} as OVS Bridge Entry is NULL ", dpnTep.getTunnelType(), e);
+        }
+    }
+
+    private void removeConfiguration(OfDpnTep dpnsTep, TypedReadWriteTransaction<Configuration> tx)
+            throws ExecutionException, InterruptedException, OperationFailedException {
+        // Check if the same transaction can be used across Config and operational shards
+        removeTunnelConfiguration(dpnsTep, tx);
+    }
+
+    private void removeTunnelConfiguration(OfDpnTep dpnTep, TypedReadWriteTransaction<Configuration> tx)
+            throws ExecutionException, InterruptedException, OperationFailedException {
+
+        LOG.info("removing ofTep configuration for {}", dpnTep.getOfPortName());
+
+        Optional<OvsBridgeRefEntry> ovsBridgeRefEntry = ovsBridgeRefEntryCache.get(dpnTep.getSourceDpnId());
+        Optional<OvsBridgeEntry> ovsBridgeEntryOptional;
+        OvsdbBridgeRef ovsdbBridgeRef = null;
+        if (ovsBridgeRefEntry.isPresent()) {
+            ovsdbBridgeRef = ovsBridgeRefEntry.get().getOvsBridgeReference();
+        } else {
+            ovsBridgeEntryOptional = ovsBridgeEntryCache.get(dpnTep.getSourceDpnId());
+            if (ovsBridgeEntryOptional.isPresent()) {
+                ovsdbBridgeRef = ovsBridgeEntryOptional.get().getOvsBridgeReference();
+            }
+        }
+
+        if (ovsdbBridgeRef != null) {
+            removeTerminationEndPoint(ovsdbBridgeRef.getValue(), dpnTep.getOfPortName());
+        }
+
+        // delete tunnel ingress flow
+        removeOfPortIngressFlow(tx, dpnTep.getOfPortName(), dpnTep.getSourceDpnId());
+
+        // delete bridge to tunnel interface mappings
+        OvsBridgeEntryKey bridgeEntryKey = new OvsBridgeEntryKey(dpnTep.getSourceDpnId());
+        InstanceIdentifier<OvsBridgeEntry> bridgeEntryIid =
+                DirectTunnelUtils.getOvsBridgeEntryIdentifier(bridgeEntryKey);
+
+        ovsBridgeEntryOptional = ovsBridgeEntryCache.get(dpnTep.getSourceDpnId());
+        if (ovsBridgeEntryOptional.isPresent()) {
+            Map<OvsBridgeTunnelEntryKey, OvsBridgeTunnelEntry> bridgeTunnelEntries = ovsBridgeEntryOptional
+                    .get().getOvsBridgeTunnelEntry();
+            deleteBridgeInterfaceEntry(bridgeEntryKey,
+                    bridgeTunnelEntries.values().stream().collect(Collectors.toList()),
+                    bridgeEntryIid, dpnTep.getOfPortName());
+            // IfIndex needs to be removed only during State Clean up not Config
+            cleanUpOfTepWithUnknownState(dpnTep.getOfPortName(), tx);
+            directTunnelUtils.removeLportTagInterfaceMap(dpnTep.getOfPortName());
+        }
+    }
+
+    private void removeTerminationEndPoint(InstanceIdentifier<?> bridgeIid, String ofPortName) {
+        LOG.debug("removing termination point for {}", ofPortName);
+        InstanceIdentifier<TerminationPoint> tpIid = DirectTunnelUtils.createTerminationPointInstanceIdentifier(
+                InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), ofPortName);
+        ITMBatchingUtils.delete(tpIid, ITMBatchingUtils.EntityType.TOPOLOGY_CONFIG);
+    }
+
+    private void removeOfPortIngressFlow(TypedReadWriteTransaction<Configuration> tx,
+                                         String ofTepName,
+                                         Uint64 dpId) throws ExecutionException, InterruptedException {
+        directTunnelUtils.removeTunnelIngressFlow(tx, dpId, ofTepName);
+    }
+
+    private void deleteBridgeInterfaceEntry(OvsBridgeEntryKey bridgeEntryKey,
+                                            List<OvsBridgeTunnelEntry> bridgeTunnelEntries,
+                                            InstanceIdentifier<OvsBridgeEntry> bridgeEntryIid,
+                                            String ofTepName) {
+        OvsBridgeTunnelEntryKey bridgeTunnelEntryKey = new OvsBridgeTunnelEntryKey(ofTepName);
+        InstanceIdentifier<OvsBridgeTunnelEntry> bridgeTunnelEntryIid =
+                DirectTunnelUtils.getBridgeTunnelEntryIdentifier(bridgeEntryKey, bridgeTunnelEntryKey);
+        ITMBatchingUtils.delete(bridgeTunnelEntryIid, ITMBatchingUtils.EntityType.DEFAULT_CONFIG);
+        if (bridgeTunnelEntries.size() <= 1) {
+            ITMBatchingUtils.delete(bridgeEntryIid, ITMBatchingUtils.EntityType.DEFAULT_CONFIG);
+        }
+    }
+
+    // if the node is shutdown, there will be stale ofTep state entries,
+    // with unknown op-state, clear them.
+    private void cleanUpOfTepWithUnknownState(String ofTepName, TypedReadWriteTransaction<Configuration> tx)
+            throws ReadFailedException {
+        Optional<OfTep> ofTepList = ofTepStateCache.get(ofTepName);
+        if (ofTepList.isPresent() && ofTepList.get().getOfTepState() == TunnelOperStatus.Unknown) {
+            LOG.debug("cleaning up dpnTep for {}, since the oper-status is {}", ofTepName,
+                    ofTepList.get().getOfTepState());
+            directTunnelUtils.deleteOfTepStateEntry(ofTepName);
+        }
     }
+
 }
index 0dea8af64d9aea07ad7bd64973ec8638ea4af0ca..5b353bc2ea7805b1ca34e3c82c4f5f1b4c71f916 100644 (file)
@@ -848,14 +848,15 @@ public final class ItmUtils {
         return TUNNEL_TYPE_MAP.get(tunnelType);
     }
 
-    public static List<TzMembership> removeTransportZoneMembership(TunnelEndPoints endPts, Map<TzMembershipKey,
-            TzMembership> zones) {
+    public static List<TzMembership> removeTransportZoneMembership(TunnelEndPoints endPts,
+                                                                                   Map<TzMembershipKey,
+                                                                                           TzMembership> zones) {
         LOG.trace(" RemoveTransportZoneMembership TEPs {}, Membership to be removed {} ", endPts, zones);
         List<TzMembership> existingTzList = new ArrayList<>(endPts.nonnullTzMembership().values());
         for (TzMembership membership : zones.values()) {
-            existingTzList.remove(new TzMembershipBuilder().setZoneName(membership.getZoneName()).build());
+            existingTzList.remove(membership);
         }
-        LOG.debug("Modified Membership List {}", existingTzList);
+        LOG.debug("Modified Membership Map {}", existingTzList);
         return existingTzList;
     }
 
index 1c08ebf025e1eecadfea974cfe2ecfdf1c55eb44..31b14e446bca8a635d4354cb7618a7ea8c62cba7 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.genius.itm.itmdirecttunnels.listeners;
 
+import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
 import static org.opendaylight.mdsal.binding.util.Datastore.OPERATIONAL;
 
 import com.google.common.util.concurrent.ListenableFuture;
@@ -14,7 +15,6 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.concurrent.Callable;
@@ -48,6 +48,7 @@ import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.util.Datastore.Operational;
 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.mdsal.binding.util.TypedReadWriteTransaction;
 import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.common.api.ReadFailedException;
@@ -57,6 +58,9 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.
 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.itm.op.rev160406.dpn.tep.config.OfDpnTep;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTep;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTepBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTepKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
@@ -124,30 +128,37 @@ public class TunnelInventoryStateListener extends
     public void remove(@NonNull InstanceIdentifier<FlowCapableNodeConnector> key,
                        @NonNull FlowCapableNodeConnector flowCapableNodeConnector) {
         String portName = flowCapableNodeConnector.getName();
+        NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
         LOG.debug("InterfaceInventoryState Remove for {}", portName);
         EVENT_LOGGER.debug("ITM-TunnelInventoryState,REMOVE DTCN received for {}",
                 flowCapableNodeConnector.getName());
-        // ITM Direct Tunnels Return if its not tunnel port and if its not Internal
-        if (!DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName) && !portName.startsWith("of")) {
+
+        if (!directTunnelUtils.isEntityOwner()) {
+            return;
+        }
+        // ITM Direct Tunnels Return if its not tunnel port or of-ports
+        if (portName.startsWith("of") && interfaceManager.isItmOfTunnelsEnabled()) {
+            LOG.debug("OfPortState REMOVE for {}", portName);
+            EVENT_LOGGER.debug("ITM-OfPortStateState Entity Owner, REMOVE {} {}", nodeConnectorId.getValue(), portName);
+            OfPortStateRemoveWorker ofPortStateRemoveWorker = new OfPortStateRemoveWorker(nodeConnectorId,
+                    null, flowCapableNodeConnector, portName);
+            coordinator.enqueueJob(portName, ofPortStateRemoveWorker, ITMConstants.JOB_MAX_RETRIES);
+            return;
+        } else if (!DirectTunnelUtils.TUNNEL_PORT_PREDICATE.test(portName)) {
             LOG.debug("Node Connector Remove - {} Interface is not a tunnel I/f, so no-op", portName);
             return;
-        } else {
-            try {
-                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;
-                }
-            } catch (ReadFailedException e) {
-                LOG.error("Tunnel {} is not present in operational DS ", portName);
+        }
+
+        try {
+            if (!tunnelStateCache.isInternalBasedOnState(portName)) {
+                LOG.debug("Node Connector Remove {} Interface is not a internal tunnel I/f, so no-op", portName);
                 return;
             }
-        }
-        if (!directTunnelUtils.isEntityOwner()) {
+        } catch (ReadFailedException e) {
+            LOG.error("Tunnel {} is not present in operational DS ", portName);
             return;
         }
         LOG.debug("Received NodeConnector Remove Event: {}, {}", key, flowCapableNodeConnector);
-        NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
         remove(nodeConnectorId, flowCapableNodeConnector, portName);
     }
 
@@ -381,6 +392,32 @@ public class TunnelInventoryStateListener extends
                 Interface.OperStatus.Unknown);
     }
 
+    private void updateOfTepStateOnNodeRemove(Uint64 srcDpn, String ofTepName,
+                                              FlowCapableNodeConnector flowCapableNodeConnector,
+                                              TypedReadWriteTransaction<Operational> tx) throws ReadFailedException {
+        LOG.debug("Updating oftep oper-status to UNKNOWN for : {}", ofTepName);
+        Optional<OfDpnTep> dpnTepInfo = ofDpnTepConfigCache.get(srcDpn.toJava());
+        if (dpnTepInfo == null || !ofTepName.equals(flowCapableNodeConnector.getName())) {
+            return;
+        }
+        handleOfTepStateUpdates(dpnTepInfo, tx, true, ofTepName,
+                Interface.OperStatus.Unknown);
+    }
+
+    private void handleOfTepStateUpdates(Optional<OfDpnTep> dpnTepInfo, TypedReadWriteTransaction<Operational> tx,
+                                         boolean opStateModified, String ofTepName, Interface.OperStatus opState) {
+        LOG.debug("updating oftep state entry for {}", ofTepName);
+        InstanceIdentifier<OfTep> ofTepStateId = ItmUtils.buildStateOfTepListId(new OfTepKey(ofTepName));
+        OfTepBuilder ofTepBuilder = new OfTepBuilder();
+        ofTepBuilder.withKey(new OfTepKey(ofTepName));
+        if (opStateModified) {
+            LOG.debug("updating oftep oper status as {} for {}", opState.getName(), ofTepName);
+            ofTepBuilder.setOfTepState(DirectTunnelUtils.convertInterfaceToTunnelOperState(opState));
+            LOG.trace("updated to {} for {}",opState.getName(), ofTepName);
+        }
+        tx.merge(ofTepStateId, ofTepBuilder.build());
+    }
+
     private Interface.OperStatus getOpState(FlowCapableNodeConnector flowCapableNodeConnector) {
         return flowCapableNodeConnector.getState().isLive()
                 && !flowCapableNodeConnector.getConfiguration().isPORTDOWN()
@@ -433,36 +470,64 @@ public class TunnelInventoryStateListener extends
             //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"
 
-            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, Uint64.valueOf(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(Uint64.valueOf(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 {
-                futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
-                    tx -> updateInterfaceStateOnNodeRemove(tx, interfaceName, flowCapableNodeConnector)));
-            }
+            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);
+                }));
+            } else {
+                LOG.error("DPNTEPInfo is null for Tunnel Interface {}", interfaceName);
+            }
             EVENT_LOGGER.debug("ITM-TunnelInventoryState,REMOVE Table 0 flow for {} completed", interfaceName);
-            // removing interfaces are already done in delete worker
-            meshedMap.remove(dpId.toString());
         }
         return futures;
     }
 
+    @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
+            justification = "https://github.com/spotbugs/spotbugs/issues/811")
+    private List<? extends ListenableFuture<?>> removeOfTepStateConfiguration(NodeConnectorId nodeConnectorIdNew,
+                                                                       NodeConnectorId nodeConnectorIdOld,
+                                                                       String ofTepName,
+                                                                       FlowCapableNodeConnector
+                                                                               fcNodeConnectorOld) {
+        List<ListenableFuture<?>> futures = new ArrayList<>();
+
+        NodeConnectorId nodeConnectorId = (nodeConnectorIdOld != null && !nodeConnectorIdNew.equals(nodeConnectorIdOld))
+                ? nodeConnectorIdOld : nodeConnectorIdNew;
+
+        Uint64 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
+            // scenario, and should be treated as port removal.
+        if (fcNodeConnectorOld.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.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, tx -> {
+                updateOfTepStateOnNodeRemove(dpId, ofTepName, fcNodeConnectorOld, tx);
+            }));
+        } else {
+            LOG.debug("removing oftep state for oftep: {}", ofTepName);
+            futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+                directTunnelUtils.deleteOfTepStateEntry(ofTepName);
+                directTunnelUtils.removeLportTagInterfaceMap(ofTepName);
+                directTunnelUtils.removeTunnelIngressFlow(tx, dpId, ofTepName);
+            }));
+            EVENT_LOGGER.debug("ITM-OfTepInventoryState,REMOVE Table 0 flow for {} completed", ofTepName);
+        }
+
+        return futures;
+    }
+
     private class TunnelInterfaceStateUpdateWorker implements Callable<List<? extends ListenableFuture<?>>> {
         private final InstanceIdentifier<FlowCapableNodeConnector> key;
         private final FlowCapableNodeConnector fcNodeConnectorOld;
@@ -554,4 +619,34 @@ public class TunnelInventoryStateListener extends
         }));
         return futures;
     }
+
+    private class OfPortStateRemoveWorker implements Callable<List<? extends ListenableFuture<?>>> {
+
+        private final NodeConnectorId nodeconnectorIdNew;
+        private final NodeConnectorId nodeconnectorIdOld;
+        private final FlowCapableNodeConnector fcNodeConnectorOld;
+        private final String ofTepName;
+
+        OfPortStateRemoveWorker(NodeConnectorId nodeconnectorIdNew, NodeConnectorId nodeconnectorIdOld,
+                                FlowCapableNodeConnector fcNodeConnectorOld, String ofTepName) {
+            this.nodeconnectorIdNew = nodeconnectorIdNew;
+            this.nodeconnectorIdOld = nodeconnectorIdOld;
+            this.fcNodeConnectorOld = fcNodeConnectorOld;
+            this.ofTepName = ofTepName;
+        }
+
+        @Override
+        public List<? extends ListenableFuture<?>> call() throws Exception {
+            // If another renderer(for eg : OVS) needs to be supported, check can be performed here
+            // to call the respective helpers.
+            return removeOfTepStateConfiguration(nodeconnectorIdNew, nodeconnectorIdOld, ofTepName, fcNodeConnectorOld);
+        }
+
+        @Override
+        public String toString() {
+            return "OfTepStateRemoveWorker{nodeConnectorInfo=" + nodeconnectorIdNew + ", nodeConnectorIdOld="
+                    + nodeconnectorIdOld + ", fcNodeConnectorOld=" + fcNodeConnectorOld + ", ofTepName='"
+                    + ofTepName + '\'' + '}';
+        }
+    }
 }
index d879309a1ccab44d698081005157849fdc2ff141..f53faeb7e31898027f6b8e58dad97e7d69b46a73 100644 (file)
@@ -24,6 +24,7 @@ import java.util.regex.Pattern;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
 import org.opendaylight.genius.itm.globals.ITMConstants;
 import org.opendaylight.genius.itm.impl.ITMBatchingUtils;
@@ -46,9 +47,12 @@ import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchTunnelSourceIp;
 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
 import org.opendaylight.infrautils.utils.concurrent.NamedLocks;
 import org.opendaylight.infrautils.utils.concurrent.NamedSimpleReentrantLock.Acquired;
+import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.util.Datastore.Configuration;
 import org.opendaylight.mdsal.binding.util.TypedReadWriteTransaction;
 import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
 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.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
@@ -82,11 +86,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.b
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.ovs.bridge.entry.OvsBridgeTunnelEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnTepConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnTepsState;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTep;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTepKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.DpnsTeps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.DpnsTepsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.dpns.teps.RemoteDpns;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTep;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTepKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
@@ -605,4 +614,22 @@ public final class DirectTunnelUtils {
         return "of" + UUID.nameUUIDFromBytes(trunkInterfaceName.getBytes(StandardCharsets.UTF_8)).toString()
                 .substring(0, 12).replace("-", "");
     }
+
+    public void deleteOfTepStateEntry(String ofTepName) {
+        LOG.debug("deleteOfTepStateEntry ofTeps state for {}", ofTepName);
+        InstanceIdentifier<OfTep> ofTeplId =
+                ItmUtils.buildStateOfTepListId(new OfTepKey(ofTepName));
+        ITMBatchingUtils.delete(ofTeplId, ITMBatchingUtils.EntityType.DEFAULT_OPERATIONAL);
+    }
+
+    public static void removeOfTepFromDpnsTepConfigDS(DataBroker dataBroker, Uint64 srcDpnId)
+            throws TransactionCommitFailedException {
+        // The source DPn id is the one to be removed
+        InstanceIdentifier<OfDpnTep> dpntepII = buildDpnTepInstanceIdentifier(srcDpnId);
+        SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, dpntepII);
+    }
+
+    private static InstanceIdentifier<OfDpnTep> buildDpnTepInstanceIdentifier(Uint64 srcDpnId) {
+        return InstanceIdentifier.builder(DpnTepConfig.class).child(OfDpnTep.class, new OfDpnTepKey(srcDpnId)).build();
+    }
 }
index daad3646ff11abd4b91c1483a7a942416f12922b..4785d0032d60b7165c7a51a65e3a0b70dcb612fb 100644 (file)
@@ -27,7 +27,9 @@ import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackReg
 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.OfDpnTepConfigCache;
 import org.opendaylight.genius.itm.cache.OfEndPointCache;
+import org.opendaylight.genius.itm.cache.OfTepStateCache;
 import org.opendaylight.genius.itm.cache.OvsBridgeEntryCache;
 import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache;
 import org.opendaylight.genius.itm.cache.TunnelStateCache;
@@ -111,6 +113,8 @@ public class TransportZoneListener extends AbstractSyncDataTreeChangeListener<Tr
     private final IInterfaceManager interfaceManager;
     private final ItmOfTunnelAddWorker itmOfTunnelAddWorker;
     private final ItmOfTunnelDeleteWorker itmOfTunnelDeleteWorker;
+    private final OfDpnTepConfigCache ofDpnTepConfigCache;
+    private final OfTepStateCache ofTepStateCache;
 
     @Inject
     public TransportZoneListener(final DataBroker dataBroker,
@@ -126,7 +130,9 @@ public class TransportZoneListener extends AbstractSyncDataTreeChangeListener<Tr
                                  final OfEndPointCache ofEndPointCache,
                                  final ServiceRecoveryRegistry serviceRecoveryRegistry,
                                  final DataTreeEventCallbackRegistrar eventCallbacks,
-                                 final TombstonedNodeManager tombstonedNodeManager) {
+                                 final TombstonedNodeManager tombstonedNodeManager,
+                                 final OfDpnTepConfigCache ofDpnTepConfigCache,
+                                 final OfTepStateCache ofTepStateCache) {
         super(dataBroker, LogicalDatastoreType.CONFIGURATION,
                 InstanceIdentifier.create(TransportZones.class).child(TransportZone.class));
         this.dataBroker = dataBroker;
@@ -138,10 +144,11 @@ public class TransportZoneListener extends AbstractSyncDataTreeChangeListener<Tr
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.eventCallbacks = eventCallbacks;
         initializeTZNode();
+        this.ofDpnTepConfigCache = ofDpnTepConfigCache;
+        this.ofTepStateCache = ofTepStateCache;
         this.itmInternalTunnelDeleteWorker = new ItmInternalTunnelDeleteWorker(dataBroker, jobCoordinator,
                 tunnelMonitoringConfig, interfaceManager, dpnTepStateCache, ovsBridgeEntryCache,
-                ovsBridgeRefEntryCache, tunnelStateCache, directTunnelUtils, ofEndPointCache, itmConfig,
-                tombstonedNodeManager);
+                ovsBridgeRefEntryCache, tunnelStateCache, directTunnelUtils, tombstonedNodeManager);
         this.itmInternalTunnelAddWorker = new ItmInternalTunnelAddWorker(dataBroker, jobCoordinator,
                 tunnelMonitoringConfig, itmConfig, directTunnelUtils, interfaceManager,
                 ovsBridgeRefEntryCache, ofEndPointCache, eventCallbacks);
@@ -149,8 +156,9 @@ public class TransportZoneListener extends AbstractSyncDataTreeChangeListener<Tr
         this.interfaceManager = interfaceManager;
         this.itmOfTunnelAddWorker = new ItmOfTunnelAddWorker(dataBroker, jobCoordinator,itmConfig,
                 directTunnelUtils, ovsBridgeRefEntryCache, eventCallbacks);
-        this.itmOfTunnelDeleteWorker = new ItmOfTunnelDeleteWorker(dataBroker, jobCoordinator,itmConfig,
-                directTunnelUtils, ovsBridgeRefEntryCache, eventCallbacks);
+        this.itmOfTunnelDeleteWorker = new ItmOfTunnelDeleteWorker(dataBroker, ofDpnTepConfigCache,
+                tombstonedNodeManager, interfaceManager, directTunnelUtils, ovsBridgeRefEntryCache, ovsBridgeEntryCache,
+                ofTepStateCache);
         serviceRecoveryRegistry.addRecoverableListener(ItmServiceRecoveryHandler.getServiceRegistryKey(),
                 this);
     }
@@ -183,47 +191,58 @@ public class TransportZoneListener extends AbstractSyncDataTreeChangeListener<Tr
         LOG.debug("Received Transport Zone Remove Event: {}", transportZone);
         boolean allowTunnelDeletion;
 
-        // check if TZ received for removal is default-transport-zone,
-        // if yes, then check if it is received from northbound, then
-        // do not entertain request and skip tunnels remove operation
-        // if def-tz removal request is due to def-tz-enabled flag is disabled or
-        // due to change in def-tz-tunnel-type, then allow def-tz tunnels deletion
-        if (ITMConstants.DEFAULT_TRANSPORT_ZONE.equalsIgnoreCase(transportZone.getZoneName())) {
-            // Get TunnelTypeBase object for tunnel-type configured in config file
-            Class<? extends TunnelTypeBase> tunType = ItmUtils.getTunnelType(itmConfig.getDefTzTunnelType());
+        if (interfaceManager.isItmOfTunnelsEnabled()) {
+            Map<OfDpnTepKey, OfDpnTep> dpnTepMap = createOfTepInfo(transportZone);
 
-            if (!itmConfig.isDefTzEnabled() || !Objects.equals(transportZone.getTunnelType(), tunType)) {
-                allowTunnelDeletion = true;
+            if (!dpnTepMap.isEmpty()) {
+                jobCoordinator.enqueueJob(transportZone.getZoneName(),
+                        new ItmOfPortRemoveWorker(dpnTepMap, itmOfTunnelDeleteWorker));
             } else {
-                // this is case when def-tz removal request is from Northbound.
-                allowTunnelDeletion = false;
-                LOG.error("Deletion of {} is an incorrect usage",ITMConstants.DEFAULT_TRANSPORT_ZONE);
+                EVENT_LOGGER.debug("DPN List in TZ is empty");
             }
         } else {
-            allowTunnelDeletion = true;
-        }
-
-        if (allowTunnelDeletion) {
-            //TODO : DPList code can be refactor with new specific class
-            // which implement TransportZoneValidator
-            EVENT_LOGGER.debug("ITM-Transportzone,TunnelDeletion {}", transportZone.getZoneName());
-            List<DPNTEPsInfo> opDpnList = createDPNTepInfo(transportZone);
-            List<HwVtep> hwVtepList = createhWVteps(transportZone);
-            LOG.trace("Delete: Invoking deleteTunnels in ItmManager with DpnList {}", opDpnList);
-            if (!opDpnList.isEmpty() || !hwVtepList.isEmpty()) {
-                LOG.trace("Delete: Invoking ItmManager with hwVtep List {} ", hwVtepList);
-                jobCoordinator.enqueueJob(transportZone.getZoneName(),
-                        new ItmTepRemoveWorker(opDpnList, hwVtepList, transportZone, mdsalManager,
-                                itmInternalTunnelDeleteWorker, dpnTEPsInfoCache, txRunner, itmConfig));
+            // check if TZ received for removal is default-transport-zone,
+            // if yes, then check if it is received from northbound, then
+            // do not entertain request and skip tunnels remove operation
+            // if def-tz removal request is due to def-tz-enabled flag is disabled or
+            // due to change in def-tz-tunnel-type, then allow def-tz tunnels deletion
+            if (ITMConstants.DEFAULT_TRANSPORT_ZONE.equalsIgnoreCase(transportZone.getZoneName())) {
+                // Get TunnelTypeBase object for tunnel-type configured in config file
+                Class<? extends TunnelTypeBase> tunType = ItmUtils.getTunnelType(itmConfig.getDefTzTunnelType());
+
+                if (!itmConfig.isDefTzEnabled() || !Objects.equals(transportZone.getTunnelType(), tunType)) {
+                    allowTunnelDeletion = true;
+                } else {
+                    // this is case when def-tz removal request is from Northbound.
+                    allowTunnelDeletion = false;
+                    LOG.error("Deletion of {} is an incorrect usage", ITMConstants.DEFAULT_TRANSPORT_ZONE);
+                }
+            } else {
+                allowTunnelDeletion = true;
+            }
 
-                if (transportZone.getVteps() != null && !transportZone.getVteps().isEmpty()) {
-                    Map<UnknownVtepsKey, UnknownVteps> unknownVteps =
-                            convertVtepListToUnknownVtepList(transportZone.getVteps());
-                    LOG.trace("Moving Transport Zone {} to tepsInNotHostedTransportZone Oper Ds.",
-                            transportZone.getZoneName());
+            if (allowTunnelDeletion) {
+                //TODO : DPList code can be refactor with new specific class
+                // which implement TransportZoneValidator
+                EVENT_LOGGER.debug("ITM-Transportzone,TunnelDeletion {}", transportZone.getZoneName());
+                List<DPNTEPsInfo> opDpnList = createDPNTepInfo(transportZone);
+                List<HwVtep> hwVtepList = createhWVteps(transportZone);
+                LOG.trace("Delete: Invoking deleteTunnels in ItmManager with DpnList {}", opDpnList);
+                if (!opDpnList.isEmpty() || !hwVtepList.isEmpty()) {
+                    LOG.trace("Delete: Invoking ItmManager with hwVtep List {} ", hwVtepList);
                     jobCoordinator.enqueueJob(transportZone.getZoneName(),
-                            new ItmTepsNotHostedAddWorker(unknownVteps, transportZone.getZoneName(),
-                                    dataBroker, txRunner));
+                            new ItmTepRemoveWorker(opDpnList, hwVtepList, transportZone, mdsalManager,
+                                    itmInternalTunnelDeleteWorker, dpnTEPsInfoCache, txRunner, itmConfig));
+
+                    if (transportZone.getVteps() != null && !transportZone.getVteps().isEmpty()) {
+                        Map<UnknownVtepsKey, UnknownVteps> unknownVteps =
+                                convertVtepListToUnknownVtepList(transportZone.getVteps());
+                        LOG.trace("Moving Transport Zone {} to tepsInNotHostedTransportZone Oper Ds.",
+                                transportZone.getZoneName());
+                        jobCoordinator.enqueueJob(transportZone.getZoneName(),
+                                new ItmTepsNotHostedAddWorker(unknownVteps, transportZone.getZoneName(),
+                                        dataBroker, txRunner));
+                    }
                 }
             }
         }
@@ -386,7 +405,7 @@ public class TransportZoneListener extends AbstractSyncDataTreeChangeListener<Tr
 
         if (!oldDpnTepList.isEmpty() && !equalLists) {
             jobCoordinator.enqueueJob(updatedTransportZone.getZoneName(),
-                    new ItmOfPortRemoveWorker(oldDpnTepMap, dataBroker, itmOfTunnelDeleteWorker));
+                    new ItmOfPortRemoveWorker(oldDpnTepMap, itmOfTunnelDeleteWorker));
         }
     }
 
index fa07f4dafab6c924db354868d5e0489de2db932d..6c5ff616991f0dce1c512664bffc30744a0fe137 100644 (file)
@@ -115,8 +115,7 @@ public class ItmTepInstanceRecoveryHandler implements ServiceRecoveryInterface {
                 dpntePsInfoCache);
         this.itmInternalTunnelDeleteWorker = new ItmInternalTunnelDeleteWorker(dataBroker, jobCoordinator,
                 tunnelMonitoringConfig, interfaceManager, dpnTepStateCache, ovsBridgeEntryCache,
-                ovsBridgeRefEntryCache, tunnelStateCache, directTunnelUtils, ofEndPointCache, itmConfig,
-                tombstonedNodeManager);
+                ovsBridgeRefEntryCache, tunnelStateCache, directTunnelUtils, tombstonedNodeManager);
         serviceRecoveryRegistry.registerServiceRecoveryRegistry(getServiceRegistryKey(), this);
         this.interfaceManager = interfaceManager;
         this.dpnTepStateCache = dpnTepStateCache;
index 01a33ba905ef7a27c815a19b646dffa7d08b6e7f..3b826b7bd707ca4d4398d29bc677b951146af838 100644 (file)
@@ -187,4 +187,24 @@ public final class BindServiceUtils {
                 .child(ServicesInfo.class, new ServicesInfoKey(interfaceName, serviceMode))
                 .child(BoundServices.class, new BoundServicesKey(servicePriority)).build();
     }
+
+    public static void unbindService(List<ListenableFuture<Void>> futures,
+                                     ManagedNewTransactionRunner txRunner,
+                                     String interfaceName) {
+        LOG.info("Unbinding service for : {}", interfaceName);
+        futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+            tx -> tx.delete(buildDefaultServiceId(interfaceName))));
+    }
+
+    public static InstanceIdentifier<BoundServices> buildDefaultServiceId(String interfaceName) {
+        return buildServiceId(interfaceName, ServiceIndex.getIndex(NwConstants.DEFAULT_EGRESS_SERVICE_NAME,
+                NwConstants.DEFAULT_EGRESS_SERVICE_INDEX), ServiceModeEgress.class);
+    }
+
+    public static InstanceIdentifier<BoundServices> buildServiceId(String interfaceName, short serviceIndex,
+                                                                   Class<? extends ServiceModeBase> serviceMode) {
+        return InstanceIdentifier.builder(ServiceBindings.class)
+                .child(ServicesInfo.class, new ServicesInfoKey(interfaceName, serviceMode))
+                .child(BoundServices.class, new BoundServicesKey(Uint8.valueOf(serviceIndex))).build();
+    }
 }
index b60e9b54a0fad832ee1ab2b1f915640f0cc3a40d..ada0f2ef09b21caadfbeaa40f913d86bfd817194 100644 (file)
@@ -171,7 +171,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, ofEndPointCache, itmConfig, tombstonedNodeManager);
+            directTunnelUtils, tombstonedNodeManager);
     }
 
     @After
index c275fb2581dfd4715ee9a44c75212a128627f0a7..5648a2cb51e55a03409b1d6129fc8431cd2c8b3b 100644 (file)
@@ -237,7 +237,7 @@ public class ItmManagerRpcServiceTest {
                 new GuavaCacheProvider(new CacheManagersRegistryImpl()), directTunnelUtils, unprocessedOFNCCache);
 
         OfTepStateCache ofTepStateCache = new OfTepStateCache(dataBroker, new GuavaCacheProvider(
-                new CacheManagersRegistryImpl()));
+                new CacheManagersRegistryImpl()), interfaceManager, directTunnelUtils);
 
         itmManagerRpcService = new ItmManagerRpcService(dataBroker, mdsalApiManager, itmConfig,
             dpntePsInfoCache, interfaceManager, dpnTepStateCache, tunnelStateCache, interfaceManagerService,