NeutronVpn: Robust handling of (lock, ID allocation/release) failures 79/87479/3
authorAshik Alias <ashik.alias@ericsson.com>
Thu, 6 Feb 2020 11:07:43 +0000 (16:37 +0530)
committerKarthikeyan Krishnan <karthikeyangceb007@gmail.com>
Wed, 12 Feb 2020 12:23:37 +0000 (12:23 +0000)
Change-Id: Ic4fd1c8a558bc5f9351b3d06dc2258c6fc4f6d9c
Signed-off-by: Ashik Alias <ashik.alias@ericsson.com>
neutronvpn/api/src/main/java/org/opendaylight/netvirt/neutronvpn/api/utils/NeutronConstants.java
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronBgpvpnChangeListener.java
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnUtils.java

index 1a044284e72f8d921633a564f244094f55bdad99..d50ebb1f2ad205862b3458191997d07e62c1f26b 100644 (file)
@@ -36,6 +36,7 @@ public interface NeutronConstants {
     String BINDING_PROFILE_CAPABILITIES = "capabilities";
     String SWITCHDEV = "switchdev";
     int MAX_ROUTERS_PER_BGPVPN = 2;
+    int INVALID_ID = 0;
 
     Predicate<Port> IS_DHCP_PORT = port -> port != null
             && DEVICE_OWNER_DHCP.equals(port.getDeviceOwner());
index 5c64ca84b250e1f5cbc09861c977e3452a3b0d48..6501d325604284962b01b9e6c414c3bf5d51eb54 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.netvirt.neutronvpn;
 
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -29,12 +30,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.bgpvpns.rev150903.BgpvpnTypeBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.bgpvpns.rev150903.BgpvpnTypeL3;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.bgpvpns.rev150903.bgpvpns.attributes.Bgpvpns;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.bgpvpns.rev150903.bgpvpns.attributes.bgpvpns.Bgpvpn;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
@@ -173,12 +176,25 @@ public class NeutronBgpvpnChangeListener extends AsyncDataTreeChangeListenerBase
     @Override
     protected void remove(InstanceIdentifier<Bgpvpn> identifier, Bgpvpn input) {
         LOG.trace("Removing Bgpvpn : key: {}, value={}", identifier, input);
+        Uuid vpnId = input.getUuid();
         if (isBgpvpnTypeL3(input.getType())) {
+            VpnMap vpnMap = neutronvpnUtils.getVpnMap(vpnId);
+            if (vpnMap == null) {
+                LOG.error("Failed to handle BGPVPN Remove for VPN {} as that VPN is not configured"
+                        + " yet as a VPN Instance", vpnId.getValue());
+                return;
+            }
             nvpnManager.removeVpn(input.getUuid());
             // Release RD Id in pool
-            neutronvpnUtils.releaseRDId(NeutronConstants.RD_IDPOOL_NAME, input.getUuid().toString());
+            List<String> rd = input.getRouteDistinguishers();
+            if (rd == null || rd.isEmpty()) {
+                int releasedId = neutronvpnUtils.releaseId(NeutronConstants.RD_IDPOOL_NAME, vpnId.getValue());
+                if (releasedId == NeutronConstants.INVALID_ID) {
+                    LOG.error("NeutronBgpvpnChangeListener remove: Unable to release ID for key {}", vpnId.getValue());
+                }
+            }
         } else {
-            LOG.warn("BGPVPN type for VPN {} is not L3", input.getUuid().getValue());
+            LOG.warn("BGPVPN type for VPN {} is not L3", vpnId.getValue());
         }
     }
 
@@ -325,11 +341,19 @@ public class NeutronBgpvpnChangeListener extends AsyncDataTreeChangeListenerBase
                 .setHigh(new BigInteger(NeutronConstants.RD_IDPOOL_SIZE).longValue()).build();
         try {
             Future<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
-            if (result != null && result.get().isSuccessful()) {
+            Collection<RpcError> rpcErrors = null;
+            if (result != null && result.get() != null) {
+                RpcResult<CreateIdPoolOutput> rpcResult = result.get();
                 LOG.info("Created IdPool for Bgpvpn RD");
-            } else {
+                if (rpcResult.isSuccessful()) {
+                    LOG.info("Created IdPool for Bgpvpn RD");
+                    return;
+                }
+                rpcErrors = rpcResult.getErrors();
                 LOG.error("Failed to create ID pool for BGPVPN RD, result future returned {}", result);
             }
+            LOG.error("createIdPool: Failed to create ID pool for BGPVPN RD, the call returned with RPC errors {}",
+                    rpcErrors != null ? rpcErrors : "RpcResult is null");
         } catch (InterruptedException | ExecutionException e) {
             LOG.error("Failed to create idPool for Bgpvpn RD", e);
         }
index 4ef97678cba656d4c9aaeb7c674342dd4e7bd694..e5b147a6c90931c8b064b673419deb7a1823f0a5 100644 (file)
@@ -32,6 +32,7 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 import java.util.concurrent.locks.ReentrantLock;
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -53,6 +54,7 @@ import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
 import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
+import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
@@ -1153,19 +1155,21 @@ public class NeutronvpnUtils {
         return Optional.absent();
     }
 
-    protected void releaseRDId(String poolName, String idKey) {
+    protected Integer releaseId(String poolName, String idKey) {
         ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
         try {
-            RpcResult<ReleaseIdOutput> rpcResult = idManager.releaseId(idInput).get();
-            if (!rpcResult.isSuccessful()) {
-                LOG.error("RPC Call to Get Unique Id returned with errors for poolname {} and ID Key {}: {}",
-                        poolName, idKey, rpcResult.getErrors());
+            Future<RpcResult<ReleaseIdOutput>> result = idManager.releaseId(idInput);
+            if (result == null || result.get() == null || !result.get().isSuccessful()) {
+                LOG.error("releaseId: RPC Call to release Id from pool {} with key {} returned with Errors {}",
+                        poolName, idKey, (result != null && result.get() != null) ? result.get().getErrors() :
+                                "RpcResult is null");
             } else {
-                LOG.info("ID {} for RD released successfully", idKey);
+                return result.get().getResult().getIdValues().get(0).intValue();
             }
         } catch (InterruptedException | ExecutionException e) {
-            LOG.error("Exception when trying to release ID for poolname {} and ID Key {}", poolName, idKey, e);
+            LOG.error("releaseId: Exception when releasing Id for key {} from pool {}", idKey, poolName, e);
         }
+        return NeutronConstants.INVALID_ID;
     }
 
     protected static IpAddress getIpv6LinkLocalAddressFromMac(MacAddress mac) {