Bug 5315 - NPE while creating Neutron Router w/o interface attached to it
[vpnservice.git] / neutronvpn / neutronvpn-impl / src / main / java / org / opendaylight / vpnservice / neutronvpn / NeutronvpnUtils.java
index 993a465337852a2a0ab1c53124b37ad4539f8c8c..b23120e4508aa645fb2e1b5994f5cec75b1cce0d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2016 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,
@@ -13,6 +13,9 @@ import com.google.common.base.Optional;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
@@ -25,6 +28,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.LockManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TimeUnits;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TryLockInput;
@@ -37,7 +43,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev15
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.VpnMaps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.networkmaps.NetworkMap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.networkmaps.NetworkMapKey;
-
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data
         .PortFixedipToPortName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data
@@ -80,10 +85,9 @@ public class NeutronvpnUtils {
     }
 
     protected static VpnMap getVpnMap(DataBroker broker, Uuid id) {
-        InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
-                .child(VpnMap.class, new VpnMapKey(id)).build();
-        Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION,
-                vpnMapIdentifier);
+        InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class,
+                new VpnMapKey(id)).build();
+        Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
         if (optionalVpnMap.isPresent()) {
             return optionalVpnMap.get();
         }
@@ -93,11 +97,9 @@ public class NeutronvpnUtils {
 
     protected static Uuid getVpnForNetwork(DataBroker broker, Uuid network) {
         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
-        Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
-                vpnMapsIdentifier);
-        if (optionalVpnMaps.isPresent()) {
-            VpnMaps vpnMaps = optionalVpnMaps.get();
-            List<VpnMap> allMaps = vpnMaps.getVpnMap();
+        Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
+        if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
+            List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
             for (VpnMap vpnMap : allMaps) {
                 if (vpnMap.getNetworkIds().contains(network)) {
                     return vpnMap.getVpnId();
@@ -107,17 +109,25 @@ public class NeutronvpnUtils {
         return null;
     }
 
-    protected static Uuid getVpnForRouter(DataBroker broker, Uuid router) {
+    // true for external vpn, false for internal vpn
+    protected static Uuid getVpnForRouter(DataBroker broker, Uuid routerId, Boolean externalVpn) {
         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
         Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
                 vpnMapsIdentifier);
-        if (optionalVpnMaps.isPresent()) {
-            VpnMaps vpnNets = optionalVpnMaps.get();
-            List<VpnMap> allMaps = vpnNets.getVpnMap();
-            if (router != null) {
+        if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
+            List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
+            if (routerId != null) {
                 for (VpnMap vpnMap : allMaps) {
-                    if (router.equals(vpnMap.getRouterId())) {
-                        return vpnMap.getVpnId();
+                    if (routerId.equals(vpnMap.getRouterId())) {
+                        if (externalVpn == true) {
+                            if (!routerId.equals(vpnMap.getVpnId())) {
+                                return vpnMap.getVpnId();
+                            }
+                        } else {
+                            if (routerId.equals(vpnMap.getVpnId())) {
+                                return vpnMap.getVpnId();
+                            }
+                        }
                     }
                 }
             }
@@ -128,8 +138,7 @@ public class NeutronvpnUtils {
     protected static Uuid getRouterforVpn(DataBroker broker, Uuid vpnId) {
         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
                 .child(VpnMap.class, new VpnMapKey(vpnId)).build();
-        Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION,
-                vpnMapIdentifier);
+        Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
         if (optionalVpnMap.isPresent()) {
             VpnMap vpnMap = optionalVpnMap.get();
             return vpnMap.getRouterId();
@@ -158,8 +167,7 @@ public class NeutronvpnUtils {
 
     protected static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
         InstanceIdentifier id = buildNetworkMapIdentifier(networkId);
-        Optional<NetworkMap> optionalNetworkMap = read(broker, LogicalDatastoreType.CONFIGURATION,
-                id);
+        Optional<NetworkMap> optionalNetworkMap = read(broker, LogicalDatastoreType.CONFIGURATION, id);
         if (optionalNetworkMap.isPresent()) {
             return optionalNetworkMap.get().getSubnetIdList();
         }
@@ -184,9 +192,8 @@ public class NeutronvpnUtils {
 
     protected static Router getNeutronRouter(DataBroker broker, Uuid routerId) {
 
-        InstanceIdentifier<Router> inst = InstanceIdentifier.create(Neutron.class).
-                child(Routers.class).child(Router.class, new RouterKey(routerId));
-
+        InstanceIdentifier<Router> inst = InstanceIdentifier.create(Neutron.class).child(Routers.class).child(Router
+                .class, new RouterKey(routerId));
         Optional<Router> rtr = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
         if (rtr.isPresent()) {
             return rtr.get();
@@ -196,9 +203,8 @@ public class NeutronvpnUtils {
 
     protected static Network getNeutronNetwork(DataBroker broker, Uuid networkId) {
         logger.debug("getNeutronNetwork for {}", networkId.getValue());
-        InstanceIdentifier<Network> inst = InstanceIdentifier.create(Neutron.class).
-                child(Networks.class).child(Network.class, new NetworkKey(networkId));
-
+        InstanceIdentifier<Network> inst = InstanceIdentifier.create(Neutron.class).child(Networks.class).child
+                (Network.class, new NetworkKey(networkId));
         Optional<Network> net = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
         if (net.isPresent()) {
             return net.get();
@@ -209,20 +215,20 @@ public class NeutronvpnUtils {
     protected static List<Uuid> getNeutronRouterSubnetIds(DataBroker broker, Uuid routerId) {
         logger.info("getNeutronRouterSubnetIds for {}", routerId.getValue());
 
-        List<Uuid> subnetNames = new ArrayList<Uuid>();
+        List<Uuid> subnetIdList = new ArrayList<Uuid>();
         Router router = getNeutronRouter(broker, routerId);
         if (router != null) {
             List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router
-                    .Interfaces> ifs = router.getInterfaces();
-            if (!ifs.isEmpty()) {
+                    .Interfaces> interfacesList = router.getInterfaces();
+            if (interfacesList != null) {
                 for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers
-                        .router.Interfaces iff : ifs) {
-                    subnetNames.add(iff.getSubnetId());
+                        .router.Interfaces interfaces : interfacesList) {
+                    subnetIdList.add(interfaces.getSubnetId());
                 }
             }
         }
         logger.info("returning from getNeutronRouterSubnetIds for {}", routerId.getValue());
-        return subnetNames;
+        return subnetIdList;
     }
 
     protected static String uuidToTapPortName(Uuid id) {
@@ -230,37 +236,72 @@ public class NeutronvpnUtils {
         return new StringBuilder().append("tap").append(tapId).toString();
     }
 
-    protected static void lockVpnInterface(LockManagerService lockManager, String vpnInterfaceName) {
-        TryLockInput input = new TryLockInputBuilder().setLockName(vpnInterfaceName).setTime(5L).setTimeUnit
+    protected static boolean lock(LockManagerService lockManager, String lockName) {
+        TryLockInput input = new TryLockInputBuilder().setLockName(lockName).setTime(5L).setTimeUnit
                 (TimeUnits.Milliseconds).build();
-        Future<RpcResult<Void>> result = lockManager.tryLock(input);
+        boolean islockAcquired = false;
         try {
+            Future<RpcResult<Void>> result = lockManager.tryLock(input);
             if ((result != null) && (result.get().isSuccessful())) {
-                logger.debug("Acquired lock for vpninterface {}", vpnInterfaceName);
+                logger.debug("Acquired lock for {}", lockName);
+                islockAcquired = true;
             } else {
-                throw new RuntimeException(String.format("Unable to getLock for vpninterface %s", vpnInterfaceName));
+                logger.error("Unable to acquire lock for  {}", lockName);
             }
         } catch (InterruptedException | ExecutionException e) {
-            logger.error("Unable to getLock for vpninterface {}", vpnInterfaceName);
-            throw new RuntimeException(String.format("Unable to getLock for vpninterface %s", vpnInterfaceName), e
-                    .getCause());
+            logger.error("Unable to acquire lock for  {}", lockName);
+            throw new RuntimeException(String.format("Unable to acquire lock for %s", lockName), e.getCause());
         }
+        return islockAcquired;
     }
 
-    protected static void unlockVpnInterface(LockManagerService lockManager, String vpnInterfaceName) {
-        UnlockInput input = new UnlockInputBuilder().setLockName(vpnInterfaceName).build();
-        Future<RpcResult<Void>> result = lockManager.unlock(input);
+    protected static boolean unlock(LockManagerService lockManager, String lockName) {
+        UnlockInput input = new UnlockInputBuilder().setLockName(lockName).build();
+        boolean islockAcquired = false;
         try {
+            Future<RpcResult<Void>> result = lockManager.unlock(input);
             if ((result != null) && (result.get().isSuccessful())) {
-                logger.debug("Unlocked vpninterface{}", vpnInterfaceName);
+                logger.debug("Unlocked {}", lockName);
+                islockAcquired = true;
             } else {
-                logger.debug("Unable to unlock vpninterface {}", vpnInterfaceName);
+                logger.error("Unable to unlock {}", lockName);
             }
         } catch (InterruptedException | ExecutionException e) {
-            logger.error("Unable to unlock vpninterface {}", vpnInterfaceName);
-            throw new RuntimeException(String.format("Unable to unlock vpninterface %s", vpnInterfaceName), e
-                    .getCause());
+            logger.error("Unable to unlock {}", lockName);
+            throw new RuntimeException(String.format("Unable to unlock %s", lockName), e.getCause());
         }
+        return islockAcquired;
+    }
+
+    protected static Short getIPPrefixFromPort(DataBroker broker, Port port) {
+        Short prefix = new Short((short) 0);
+        String cidr = "";
+        try {
+            Uuid subnetUUID = port.getFixedIps().get(0).getSubnetId();
+
+            SubnetKey subnetkey = new SubnetKey(subnetUUID);
+            InstanceIdentifier<Subnet> subnetidentifier = InstanceIdentifier.create(Neutron.class).child(Subnets
+                    .class).child(Subnet.class, subnetkey);
+            Optional<Subnet> subnet = read(broker, LogicalDatastoreType.CONFIGURATION,subnetidentifier);
+            if (subnet.isPresent()) {
+                cidr = subnet.get().getCidr();
+                // Extract the prefix length from cidr
+                String[] parts = cidr.split("/");
+                if ((parts.length == 2)) {
+                    prefix = Short.valueOf(parts[1]);
+                    return prefix;
+                } else {
+                    logger.trace("Could not retrieve prefix from subnet CIDR");
+                    System.out.println("Could not retrieve prefix from subnet CIDR");
+                }
+            } else {
+                logger.trace("Unable to read on subnet datastore");
+            }
+        } catch (Exception e) {
+            logger.error("Failed to retrieve IP prefix from port : ", e);
+            System.out.println("Failed to retrieve IP prefix from port : " + e.getMessage());
+        }
+        return null;
     }
 
     static InstanceIdentifier<PortNameToPortUuid> buildPortNameToPortUuidIdentifier(String portname) {
@@ -281,6 +322,12 @@ public class NeutronvpnUtils {
         return id;
     }
 
+    static InstanceIdentifier<VpnInterface> buildVpnInterfaceIdentifier(String ifName) {
+        InstanceIdentifier<VpnInterface> id = InstanceIdentifier.builder(VpnInterfaces.class).
+                child(VpnInterface.class, new VpnInterfaceKey(ifName)).build();
+        return id;
+    }
+
     static InstanceIdentifier<Subnetmap> buildSubnetMapIdentifier(Uuid subnetId) {
         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class, new
                 SubnetmapKey(subnetId)).build();