Handling RACE conditions in bind/unbind service
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / renderer / ovs / statehelpers / OvsInterfaceStateRemoveHelper.java
index f1ee9ed722c284b76e30c1881a8b0376484be93a..0233e6cc4b7eb194d84839ab4a4c801afab50255 100644 (file)
@@ -8,6 +8,9 @@
 package org.opendaylight.genius.interfacemanager.renderer.ovs.statehelpers;
 
 import com.google.common.util.concurrent.ListenableFuture;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.genius.interfacemanager.IfmUtil;
@@ -18,70 +21,75 @@ import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilit
 import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-
 public class OvsInterfaceStateRemoveHelper {
     private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateRemoveHelper.class);
 
-    public static List<ListenableFuture<Void>> removeInterfaceStateConfiguration(IdManagerService idManager, IMdsalApiManager mdsalApiManager,
-                                                                                 AlivenessMonitorService alivenessMonitorService,
-                                                                                 NodeConnectorId nodeConnectorIdNew, NodeConnectorId nodeConnectorIdOld,
-                                                                                 DataBroker dataBroker, String interfaceName,
-                                                                                 FlowCapableNodeConnector fcNodeConnectorOld) {
-        LOG.debug("Removing interface-state information for interface: {}", interfaceName);
+    public static List<ListenableFuture<Void>> removeInterfaceStateConfiguration(IdManagerService idManager,
+            IMdsalApiManager mdsalApiManager, AlivenessMonitorService alivenessMonitorService,
+            NodeConnectorId nodeConnectorIdNew, NodeConnectorId nodeConnectorIdOld, DataBroker dataBroker,
+            String interfaceName, FlowCapableNodeConnector fcNodeConnectorOld, boolean isNodePresent,
+            String parentInterface) {
+        LOG.debug("Removing interface-state information for interface: {} {}", interfaceName, isNodePresent);
         List<ListenableFuture<Void>> futures = new ArrayList<>();
-        WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
+        WriteTransaction defaultOperationalShardTransaction = dataBroker.newWriteOnlyTransaction();
 
         //VM Migration: Use old nodeConnectorId to delete the interface entry
-        NodeConnectorId nodeConnectorId = nodeConnectorIdOld != null && !nodeConnectorIdNew.equals(nodeConnectorIdOld) ?
-                nodeConnectorIdOld : nodeConnectorIdNew;
+        NodeConnectorId nodeConnectorId = nodeConnectorIdOld != null && !nodeConnectorIdNew.equals(nodeConnectorIdOld)
+                nodeConnectorIdOld : nodeConnectorIdNew;
         // delete the port entry from interface operational DS
-        BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+        BigInteger dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId);
 
         //VM Migration: Update the interface state to unknown only if remove event received for same switch
-        if(!InterfaceManagerCommonUtils.isNodePresent(dataBroker,nodeConnectorId) && nodeConnectorIdNew.equals(nodeConnectorIdOld)){
+        if (!isNodePresent && nodeConnectorIdNew.equals(nodeConnectorIdOld)) {
             //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"
-            OvsInterfaceStateUpdateHelper.updateInterfaceStateOnNodeRemove(interfaceName, fcNodeConnectorOld, dataBroker,
-                    alivenessMonitorService, transaction);
-        }else{
-            InterfaceManagerCommonUtils.deleteStateEntry(interfaceName, transaction);
+            OvsInterfaceStateUpdateHelper.updateInterfaceStateOnNodeRemove(interfaceName, fcNodeConnectorOld,
+                    dataBroker, alivenessMonitorService, defaultOperationalShardTransaction);
+        } else {
+            InterfaceManagerCommonUtils.deleteStateEntry(interfaceName, defaultOperationalShardTransaction);
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
+                .Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
 
-            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
-                    InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
-            if(iface != null) {
+            if (iface != null) {
                 // If this interface is a tunnel interface, remove the tunnel ingress flow and stop lldp monitoring
                 if (InterfaceManagerCommonUtils.isTunnelInterface(iface)) {
-                    InterfaceMetaUtils.removeLportTagInterfaceMap(idManager, transaction, interfaceName);
+                    InterfaceMetaUtils.removeLportTagInterfaceMap(idManager, defaultOperationalShardTransaction,
+                            interfaceName);
                     handleTunnelMonitoringRemoval(alivenessMonitorService, mdsalApiManager, dataBroker, dpId,
-                            iface.getName(), iface.getAugmentation(IfTunnel.class), transaction,
+                            iface.getName(), iface.getAugmentation(IfTunnel.class), defaultOperationalShardTransaction,
                             nodeConnectorId, futures);
                     return futures;
                 }
             }
-            FlowBasedServicesUtils.removeIngressFlow(interfaceName, dpId, transaction);
+            // remove ingress flow only for northbound configured interfaces
+            // skip this check for non-unique ports(Ex: br-int,br-ex)
+            if (iface != null || iface == null && !interfaceName.contains(fcNodeConnectorOld.getName())) {
+                FlowBasedServicesUtils.removeIngressFlow(interfaceName, dpId, dataBroker, futures);
+            }
+
+            // Delete the Vpn Interface from DpnToInterface Op DS.
+            InterfaceManagerCommonUtils.deleteDpnToInterface(dataBroker, dpId, interfaceName,
+                    defaultOperationalShardTransaction);
         }
-        futures.add(transaction.submit());
+        futures.add(defaultOperationalShardTransaction.submit());
         return futures;
     }
 
-    public static void handleTunnelMonitoringRemoval(AlivenessMonitorService alivenessMonitorService, IMdsalApiManager mdsalApiManager,
-                                                     DataBroker dataBroker, BigInteger dpId, String interfaceName,
-                                                     IfTunnel ifTunnel, WriteTransaction transaction,
-                                                     NodeConnectorId nodeConnectorId, List<ListenableFuture<Void>> futures){
-        long portNo = Long.valueOf(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
-        InterfaceManagerCommonUtils.makeTunnelIngressFlow(futures, mdsalApiManager, ifTunnel, dpId, portNo, interfaceName, -1,
-                NwConstants.DEL_FLOW);
+    public static void handleTunnelMonitoringRemoval(AlivenessMonitorService alivenessMonitorService,
+            IMdsalApiManager mdsalApiManager, DataBroker dataBroker, BigInteger dpId, String interfaceName,
+            IfTunnel ifTunnel, WriteTransaction transaction, NodeConnectorId nodeConnectorId,
+            List<ListenableFuture<Void>> futures) {
+        long portNo = IfmUtil.getPortNumberFromNodeConnectorId(nodeConnectorId);
+        InterfaceManagerCommonUtils.makeTunnelIngressFlow(futures, mdsalApiManager, ifTunnel, dpId, portNo,
+                interfaceName, -1, NwConstants.DEL_FLOW);
         futures.add(transaction.submit());
         AlivenessMonitorUtils.stopLLDPMonitoring(alivenessMonitorService, dataBroker, ifTunnel, interfaceName);
     }
-}
\ No newline at end of file
+}