OptimisticLockFailedException fix for IPv6 Serv 98/75398/8
authorKarthikeyan Krishnan <karthikeyangceb007@gmail.com>
Thu, 23 Aug 2018 05:06:24 +0000 (10:36 +0530)
committerSridhar Gaddam <sgaddam@redhat.com>
Mon, 24 Sep 2018 08:16:32 +0000 (08:16 +0000)
Issue:
=======
OptimisticLockFailedException is throwing for
when IPv6 host interface service binding and
unbinding scenario. In cluster environment
this issue was observed.

Solution:
=========
As pert of this fix, have introduced JC for
IPv6 service binding and unbinding for all
the basic add(), update(), remove() methods.
This kind of JC handling has implemented already
in all the southbound events. So the same kind
of handling is implemented for all the
northbound events.

Issue: NETVIRT-1409

Change-Id: Ice777d57913cda8924ec8422eb02bbbfdd194168
Signed-off-by: Karthikeyan Krishnan <karthikeyangceb007@gmail.com>
ipv6service/impl/src/main/java/org/opendaylight/netvirt/ipv6service/IfMgr.java

index de0808e7b824a56727c177e9ff84b2079dc398c7..42fc8b8ea2ee9805c2ce566ec587458e87fe21ba 100644 (file)
@@ -32,6 +32,7 @@ import org.opendaylight.genius.ipv6util.api.Ipv6Constants.Ipv6RouterAdvertisemen
 import org.opendaylight.genius.ipv6util.api.Ipv6Util;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.netvirt.elanmanager.api.IElanService;
 import org.opendaylight.netvirt.ipv6service.api.ElementCache;
 import org.opendaylight.netvirt.ipv6service.api.IVirtualNetwork;
@@ -88,17 +89,19 @@ public class IfMgr implements ElementCache, AutoCloseable {
     private final PacketProcessingService packetService;
     private final Ipv6PeriodicTrQueue ipv6Queue = new Ipv6PeriodicTrQueue(this::transmitUnsolicitedRA);
     private final Ipv6TimerWheel timer = new Ipv6TimerWheel();
+    private final JobCoordinator jobCoordinator;
 
     @Inject
     public IfMgr(DataBroker dataBroker, IElanService elanProvider, OdlInterfaceRpcService interfaceManagerRpc,
                  PacketProcessingService packetService, Ipv6ServiceUtils ipv6ServiceUtils,
-                 Ipv6ServiceEosHandler ipv6ServiceEosHandler) {
+                 Ipv6ServiceEosHandler ipv6ServiceEosHandler, JobCoordinator jobCoordinator) {
         this.dataBroker = dataBroker;
         this.elanProvider = elanProvider;
         this.interfaceManagerRpc = interfaceManagerRpc;
         this.packetService = packetService;
         this.ipv6ServiceUtils = ipv6ServiceUtils;
         this.ipv6ServiceEosHandler = ipv6ServiceEosHandler;
+        this.jobCoordinator = jobCoordinator;
         LOG.info("IfMgr is enabled");
     }
 
@@ -365,12 +368,16 @@ public class IfMgr implements ElementCache, AutoCloseable {
         VirtualPort prevIntf = vintfs.putIfAbsent(portId, intf);
         if (prevIntf == null) {
             Long elanTag = getNetworkElanTag(networkId);
-            // Do service binding for the port and set the serviceBindingStatus to true.
-            ipv6ServiceUtils.bindIpv6Service(portId.getValue(), elanTag, NwConstants.IPV6_TABLE);
-            intf.setServiceBindingStatus(true);
+            VirtualPort virtIntf = intf;
+            jobCoordinator.enqueueJob("IPv6-" + String.valueOf(portId), () -> {
+                // Do service binding for the port and set the serviceBindingStatus to true.
+                ipv6ServiceUtils.bindIpv6Service(portId.getValue(), elanTag, NwConstants.IPV6_TABLE);
+                virtIntf.setServiceBindingStatus(true);
 
-            /* Update the intf dpnId/ofPort from the Operational Store */
-            updateInterfaceDpidOfPortInfo(portId);
+                /* Update the intf dpnId/ofPort from the Operational Store */
+                updateInterfaceDpidOfPortInfo(portId);
+                return Collections.emptyList();
+            });
 
         } else {
             intf = prevIntf;
@@ -412,13 +419,19 @@ public class IfMgr implements ElementCache, AutoCloseable {
             if (!intf.getServiceBindingStatus()) {
                 Long elanTag = getNetworkElanTag(intf.getNetworkID());
                 LOG.info("In updateHostIntf, service binding for portId {}", portId);
-                ipv6ServiceUtils.bindIpv6Service(portId.getValue(), elanTag, NwConstants.IPV6_TABLE);
-                intf.setServiceBindingStatus(true);
+                jobCoordinator.enqueueJob("IPv6-" + String.valueOf(portId), () -> {
+                    ipv6ServiceUtils.bindIpv6Service(portId.getValue(), elanTag, NwConstants.IPV6_TABLE);
+                    intf.setServiceBindingStatus(true);
+                    return Collections.emptyList();
+                });
             }
         } else {
             LOG.info("In updateHostIntf, removing service binding for portId {}", portId);
-            ipv6ServiceUtils.unbindIpv6Service(portId.getValue());
-            intf.setServiceBindingStatus(false);
+            jobCoordinator.enqueueJob("IPv6-" + String.valueOf(portId), () -> {
+                ipv6ServiceUtils.unbindIpv6Service(portId.getValue());
+                intf.setServiceBindingStatus(false);
+                return Collections.emptyList();
+            });
         }
     }
 
@@ -493,14 +506,17 @@ public class IfMgr implements ElementCache, AutoCloseable {
                 LOG.debug("Reset the periodic RA Timer for intf {}", intf.getIntfUUID());
             } else {
                 LOG.info("In removePort for host interface, portId {}", portId);
-                // Remove the serviceBinding entry for the port.
-                ipv6ServiceUtils.unbindIpv6Service(portId.getValue());
-                // Remove the portId from the (network <--> List[dpnIds, List <ports>]) cache.
-                VirtualNetwork vnet = getNetwork(networkID);
-                if (null != vnet) {
-                    BigInteger dpId = intf.getDpId();
-                    vnet.updateDpnPortInfo(dpId, intf.getOfPort(), Ipv6ServiceConstants.DEL_ENTRY);
-                }
+                jobCoordinator.enqueueJob("IPv6-" + String.valueOf(portId), () -> {
+                    // Remove the serviceBinding entry for the port.
+                    ipv6ServiceUtils.unbindIpv6Service(portId.getValue());
+                    // Remove the portId from the (network <--> List[dpnIds, List <ports>]) cache.
+                    VirtualNetwork vnet = getNetwork(networkID);
+                    if (null != vnet) {
+                        BigInteger dpId = intf.getDpId();
+                        vnet.updateDpnPortInfo(dpId, intf.getOfPort(), Ipv6ServiceConstants.DEL_ENTRY);
+                    }
+                    return Collections.emptyList();
+                });
             }
         }
     }