NETVIRT-1630 migrate to md-sal APIs
[netvirt.git] / neutronvpn / impl / src / main / java / org / opendaylight / netvirt / neutronvpn / NeutronvpnUtils.java
index 0ed48979e3a07a38c92500109c4fd173d6ad9e5c..3231943ad0d2adf0a681f10d317883a5249a9aa9 100644 (file)
@@ -5,14 +5,14 @@
  * 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.netvirt.neutronvpn;
 
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
 
 import com.google.common.base.Function;
-import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
@@ -25,24 +25,21 @@ import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 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;
 import org.apache.commons.lang3.StringUtils;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
-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.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.infra.Datastore;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
@@ -53,14 +50,12 @@ import org.opendaylight.genius.utils.JvmGlobalLocks;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.ReadTransaction;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 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;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
-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.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
@@ -110,6 +105,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterfaceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortIdSubportData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
@@ -176,14 +178,25 @@ public class NeutronvpnUtils {
             .put(NetworkTypeVxlan.class, SegmentTypeVxlan.class)
             .build();
 
-    private static final Set<Class<? extends NetworkTypeBase>> SUPPORTED_NETWORK_TYPES = new HashSet<>();
-
-    static {
-        SUPPORTED_NETWORK_TYPES.add(NetworkTypeFlat.class);
-        SUPPORTED_NETWORK_TYPES.add(NetworkTypeVlan.class);
-        SUPPORTED_NETWORK_TYPES.add(NetworkTypeVxlan.class);
-        SUPPORTED_NETWORK_TYPES.add(NetworkTypeGre.class);
-    }
+    private static final ImmutableSet<Class<? extends NetworkTypeBase>> SUPPORTED_NETWORK_TYPES = ImmutableSet.of(
+        NetworkTypeFlat.class,
+        NetworkTypeVlan.class,
+        NetworkTypeVxlan.class,
+        NetworkTypeGre.class);
+
+
+    private static final InstanceIdentifier<VpnInstanceOpData> VPN_INSTANCE_OP_DATA_IID =
+            InstanceIdentifier.create(VpnInstanceOpData.class);
+    private static final InstanceIdentifier<VpnMaps> VPN_MAPS_IID = InstanceIdentifier.create(VpnMaps.class);
+    private static final InstanceIdentifier<Subnetmaps> SUBNETMAPS_IID = InstanceIdentifier.create(Subnetmaps.class);
+    private static final InstanceIdentifier<Networks> NEUTRON_NETWORKS_IID = InstanceIdentifier.builder(Neutron.class)
+            .child(Networks.class).build();
+    private static final InstanceIdentifier<Ports> NEUTRON_PORTS_IID = InstanceIdentifier.builder(Neutron.class)
+            .child(Ports.class).build();
+    private static final InstanceIdentifier<Routers> NEUTRON_ROUTERS_IID = InstanceIdentifier.builder(Neutron.class)
+            .child(Routers.class).build();
+    private static final InstanceIdentifier<Subnets> NEUTRON_SUBNETS_IID = InstanceIdentifier.builder(Neutron.class)
+            .child(Subnets.class).build();
 
     private final ConcurrentMap<Uuid, Network> networkMap = new ConcurrentHashMap<>();
     private final ConcurrentMap<Uuid, Router> routerMap = new ConcurrentHashMap<>();
@@ -222,9 +235,7 @@ public class NeutronvpnUtils {
 
     @Nullable
     public VpnMap getVpnMap(Uuid id) {
-        InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class,
-                new VpnMapKey(id)).build();
-        Optional<VpnMap> optionalVpnMap = read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
+        Optional<VpnMap> optionalVpnMap = read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier(id));
         if (optionalVpnMap.isPresent()) {
             return optionalVpnMap.get();
         }
@@ -234,8 +245,7 @@ public class NeutronvpnUtils {
 
     @Nullable
     protected Uuid getVpnForNetwork(Uuid network) {
-        InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
-        Optional<VpnMaps> optionalVpnMaps = read(LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
+        Optional<VpnMaps> optionalVpnMaps = read(LogicalDatastoreType.CONFIGURATION, VPN_MAPS_IID);
         if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().nonnullVpnMap() != null) {
             for (VpnMap vpnMap : new ArrayList<>(optionalVpnMaps.get().nonnullVpnMap())) {
                 List<Uuid> netIds = vpnMap.getNetworkIds();
@@ -279,8 +289,7 @@ public class NeutronvpnUtils {
             return null;
         }
 
-        InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
-        Optional<VpnMaps> optionalVpnMaps = read(LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
+        Optional<VpnMaps> optionalVpnMaps = read(LogicalDatastoreType.CONFIGURATION, VPN_MAPS_IID);
         if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().nonnullVpnMap() != null) {
             for (VpnMap vpnMap : new ArrayList<>(optionalVpnMaps.get().nonnullVpnMap())) {
                 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.vpnmap
@@ -289,12 +298,8 @@ public class NeutronvpnUtils {
                     continue;
                 }
                 // Skip router vpnId fetching from internet BGP-VPN
-                if (vpnMap.getNetworkIds() != null && !vpnMap.getNetworkIds().isEmpty()) {
-                    // We only need to check the first network; if it’s not an external network there’s no
-                    // need to check the rest of the VPN’s network list
-                    if (getIsExternal(getNeutronNetwork(vpnMap.getNetworkIds().iterator().next()))) {
-                        continue;
-                    }
+                if (hasExternalNetwork(vpnMap.getNetworkIds())) {
+                    continue;
                 }
                 // FIXME: NETVIRT-1503: this check can be replaced by a ReadOnlyTransaction.exists()
                 if (routerIdsList.stream().anyMatch(routerIds -> routerId.equals(routerIds.getRouterId()))) {
@@ -314,11 +319,29 @@ public class NeutronvpnUtils {
         return null;
     }
 
+    // We only need to check the first network; if it’s not an external network there’s no
+    // need to check the rest of the VPN’s network list. Note that some UUIDs may point to unknown networks, in which
+    // case we check more  and assume false.
+    private boolean hasExternalNetwork(List<Uuid> uuids) {
+        if (uuids != null) {
+            for (Uuid uuid : uuids) {
+                final Network network = getNeutronNetwork(uuid);
+                if (network != null) {
+                    if (Boolean.TRUE.equals(getIsExternal(network))) {
+                        return true;
+                    }
+                } else {
+                    LOG.debug("hasExternalNetwork: cannot find network for {}", uuid);
+                }
+            }
+        }
+        return false;
+    }
+
+
     @Nullable
     protected List<Uuid> getRouterIdListforVpn(Uuid vpnId) {
-        InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class,
-                new VpnMapKey(vpnId)).build();
-        Optional<VpnMap> optionalVpnMap = read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
+        Optional<VpnMap> optionalVpnMap = read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier(vpnId));
         if (optionalVpnMap.isPresent()) {
             VpnMap vpnMap = optionalVpnMap.get();
             return NeutronUtils.getVpnMapRouterIdsListUuid(vpnMap.getRouterIds());
@@ -329,9 +352,7 @@ public class NeutronvpnUtils {
 
     @Nullable
     protected List<Uuid> getNetworksForVpn(Uuid vpnId) {
-        InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class,
-                new VpnMapKey(vpnId)).build();
-        Optional<VpnMap> optionalVpnMap = read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
+        Optional<VpnMap> optionalVpnMap = read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier(vpnId));
         if (optionalVpnMap.isPresent()) {
             VpnMap vpnMap = optionalVpnMap.get();
             if (vpnMap.getNetworkIds() != null && !vpnMap.getNetworkIds().isEmpty()) {
@@ -347,8 +368,7 @@ public class NeutronvpnUtils {
     protected List<Uuid> getSubnetsforVpn(Uuid vpnid) {
         List<Uuid> subnets = new ArrayList<>();
         // read subnetmaps
-        InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
-        Optional<Subnetmaps> subnetmaps = read(LogicalDatastoreType.CONFIGURATION, subnetmapsid);
+        Optional<Subnetmaps> subnetmaps = read(LogicalDatastoreType.CONFIGURATION, SUBNETMAPS_IID);
         if (subnetmaps.isPresent() && subnetmaps.get().getSubnetmap() != null) {
             List<Subnetmap> subnetMapList = subnetmaps.get().getSubnetmap();
             for (Subnetmap candidateSubnetMap : subnetMapList) {
@@ -388,9 +408,7 @@ public class NeutronvpnUtils {
         if (router != null) {
             return router;
         }
-        InstanceIdentifier<Router> inst = InstanceIdentifier.create(Neutron.class).child(Routers.class).child(Router
-                .class, new RouterKey(routerId));
-        Optional<Router> rtr = read(LogicalDatastoreType.CONFIGURATION, inst);
+        Optional<Router> rtr = read(LogicalDatastoreType.CONFIGURATION, getNeutronRouterIid(routerId));
         if (rtr.isPresent()) {
             router = rtr.get();
         }
@@ -398,40 +416,27 @@ public class NeutronvpnUtils {
     }
 
     public InstanceIdentifier<Router> getNeutronRouterIid(Uuid routerId) {
-        return InstanceIdentifier.create(Neutron.class).child(Routers.class).child(Router
-                .class, new RouterKey(routerId));
-
+        return NEUTRON_ROUTERS_IID.child(Router.class, new RouterKey(routerId));
     }
 
-    protected Network getNeutronNetwork(Uuid networkId) {
-        Network network = null;
-        network = networkMap.get(networkId);
+    protected @Nullable Network getNeutronNetwork(Uuid networkId) {
+        Network network = networkMap.get(networkId);
         if (network != null) {
             return network;
         }
         LOG.debug("getNeutronNetwork for {}", networkId.getValue());
-        InstanceIdentifier<Network> inst = InstanceIdentifier.create(Neutron.class).child(Networks.class)
-            .child(Network.class, new NetworkKey(networkId));
-        Optional<Network> net = read(LogicalDatastoreType.CONFIGURATION, inst);
-        if (net.isPresent()) {
-            network = net.get();
-        }
-        return network;
+        InstanceIdentifier<Network> inst = NEUTRON_NETWORKS_IID.child(Network.class, new NetworkKey(networkId));
+        return read(LogicalDatastoreType.CONFIGURATION, inst).orElse(null);
     }
 
-    protected Port getNeutronPort(Uuid portId) {
+    protected @Nullable Port getNeutronPort(Uuid portId) {
         Port prt = portMap.get(portId);
         if (prt != null) {
             return prt;
         }
         LOG.debug("getNeutronPort for {}", portId.getValue());
-        InstanceIdentifier<Port> inst = InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class,
-                new PortKey(portId));
-        Optional<Port> port = read(LogicalDatastoreType.CONFIGURATION, inst);
-        if (port.isPresent()) {
-            prt = port.get();
-        }
-        return prt;
+        InstanceIdentifier<Port> inst = NEUTRON_PORTS_IID.child(Port.class, new PortKey(portId));
+        return read(LogicalDatastoreType.CONFIGURATION, inst).orElse(null);
     }
 
     public PortIdToSubport getPortIdToSubport(Uuid portId) {
@@ -781,9 +786,9 @@ public class NeutronvpnUtils {
             Subnet subnet = getNeutronSubnet(subnetId);
             if (subnet != null) {
                 Class<? extends IpVersionBase> ipVersion =
-                        NeutronSecurityRuleConstants.IP_VERSION_MAP.get(subnet.getIpVersion());
+                        NeutronSecurityGroupConstants.IP_VERSION_MAP.get(subnet.getIpVersion());
                 Class<? extends Dhcpv6Base> raMode = subnet.getIpv6RaMode() == null ? null
-                        : NeutronSecurityRuleConstants.RA_MODE_MAP.get(subnet.getIpv6RaMode());
+                        : NeutronSecurityGroupConstants.RA_MODE_MAP.get(subnet.getIpv6RaMode());
                 SubnetInfo subnetInfo = new SubnetInfoBuilder().withKey(new SubnetInfoKey(subnetId))
                         .setIpVersion(ipVersion).setIpPrefix(new IpPrefixOrAddress(subnet.getCidr()))
                         .setIpv6RaMode(raMode).setGatewayIp(subnet.getGatewayIp()).build();
@@ -798,8 +803,7 @@ public class NeutronvpnUtils {
         if (subnet != null) {
             return subnet;
         }
-        InstanceIdentifier<Subnet> inst = InstanceIdentifier.create(Neutron.class).child(Subnets.class).child(Subnet
-                .class, new SubnetKey(subnetId));
+        InstanceIdentifier<Subnet> inst = NEUTRON_SUBNETS_IID.child(Subnet.class, new SubnetKey(subnetId));
         Optional<Subnet> sn = read(LogicalDatastoreType.CONFIGURATION, inst);
 
         if (sn.isPresent()) {
@@ -811,8 +815,7 @@ public class NeutronvpnUtils {
 
     protected List<Subnetmap> getNeutronRouterSubnetMapList(Uuid routerId) {
         List<Subnetmap> subnetMapList = new ArrayList<>();
-        Optional<Subnetmaps> subnetMaps = read(LogicalDatastoreType.CONFIGURATION,
-                InstanceIdentifier.builder(Subnetmaps.class).build());
+        Optional<Subnetmaps> subnetMaps = read(LogicalDatastoreType.CONFIGURATION, SUBNETMAPS_IID);
         if (subnetMaps.isPresent() && subnetMaps.get().getSubnetmap() != null) {
             for (Subnetmap subnetmap : subnetMaps.get().getSubnetmap()) {
                 if (routerId.equals(subnetmap.getRouterId())) {
@@ -828,8 +831,7 @@ public class NeutronvpnUtils {
     protected List<Uuid> getNeutronRouterSubnetIds(Uuid routerId) {
         LOG.debug("getNeutronRouterSubnetIds for {}", routerId.getValue());
         List<Uuid> subnetIdList = new ArrayList<>();
-        Optional<Subnetmaps> subnetMaps = read(LogicalDatastoreType.CONFIGURATION,
-            InstanceIdentifier.builder(Subnetmaps.class).build());
+        Optional<Subnetmaps> subnetMaps = read(LogicalDatastoreType.CONFIGURATION, SUBNETMAPS_IID);
         if (subnetMaps.isPresent() && subnetMaps.get().getSubnetmap() != null) {
             for (Subnetmap subnetmap : subnetMaps.get().getSubnetmap()) {
                 if (routerId.equals(subnetmap.getRouterId())) {
@@ -846,11 +848,9 @@ public class NeutronvpnUtils {
     @Nullable
     protected Short getIPPrefixFromPort(Port port) {
         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(LogicalDatastoreType.CONFIGURATION, subnetidentifier);
+            // FIXME: why are we not using getNeutronSubnet() here? it does caching for us...
+            Optional<Subnet> subnet = read(LogicalDatastoreType.CONFIGURATION,
+                NEUTRON_SUBNETS_IID.child(Subnet.class, new SubnetKey(port.getFixedIps().get(0).getSubnetId())));
             if (subnet.isPresent()) {
                 String cidr = subnet.get().getCidr().stringValue();
                 // Extract the prefix length from cidr
@@ -888,8 +888,8 @@ public class NeutronvpnUtils {
             LOG.trace("Neutron port with fixedIp: {}, vpn {}, interface {}, mac {}, isSubnetIp {} added to "
                 + "VpnPortipToPort DS", fixedIp, vpnName, portName, macAddress, isSubnetIp);
         } catch (Exception e) {
-            LOG.error("Failure while creating VPNPortFixedIpToPort map for vpn {} - fixedIP {}", vpnName, fixedIp,
-                    e);
+            LOG.error("Failure while creating VPNPortFixedIpToPort map for vpn {} - fixedIP {} for port {} with "
+                    + "macAddress {}", vpnName, fixedIp, portName, macAddress, e);
         }
     }
 
@@ -1018,8 +1018,8 @@ public class NeutronvpnUtils {
     }
 
     static Boolean getIsExternal(Network network) {
-        return network.augmentation(NetworkL3Extension.class) != null
-                && network.augmentation(NetworkL3Extension.class).isExternal();
+        NetworkL3Extension ext = network.augmentation(NetworkL3Extension.class);
+        return ext != null && ext.isExternal();
     }
 
     static InstanceIdentifier<NetworkMap> buildNetworkMapIdentifier(Uuid networkId) {
@@ -1035,9 +1035,7 @@ public class NeutronvpnUtils {
     }
 
     static InstanceIdentifier<Subnetmap> buildSubnetMapIdentifier(Uuid subnetId) {
-        InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class, new
-                SubnetmapKey(subnetId)).build();
-        return id;
+        return SUBNETMAPS_IID.child(Subnetmap.class, new SubnetmapKey(subnetId));
     }
 
     static InstanceIdentifier<Interface> buildVlanInterfaceIdentifier(String interfaceName) {
@@ -1071,7 +1069,7 @@ public class NeutronvpnUtils {
     private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
         try {
             return SingleTransactionDataBroker.syncReadOptional(dataBroker, datastoreType, path);
-        } catch (ReadFailedException e) {
+        } catch (ExecutionException | InterruptedException e) {
             throw new RuntimeException(e);
         }
     }
@@ -1104,22 +1102,23 @@ public class NeutronvpnUtils {
 
     static boolean isNetworkTypeSupported(Network network) {
         NetworkProviderExtension npe = network.augmentation(NetworkProviderExtension.class);
-        return npe != null && npe.getNetworkType() != null && SUPPORTED_NETWORK_TYPES.contains(npe.getNetworkType());
+        return npe != null && SUPPORTED_NETWORK_TYPES.contains(npe.getNetworkType());
     }
 
-    static boolean isNetworkOfType(Network network, Class<? extends NetworkTypeBase> type) {
-        NetworkProviderExtension npe = network.augmentation(NetworkProviderExtension.class);
-        if (npe != null && npe.getNetworkType() != null) {
-            return type.isAssignableFrom(npe.getNetworkType());
+    static boolean isFlatOrVlanNetwork(Network network) {
+        if (network != null) {
+            NetworkProviderExtension npe = network.augmentation(NetworkProviderExtension.class);
+            if (npe != null) {
+                Class<? extends NetworkTypeBase> npeType = npe.getNetworkType();
+                if (npeType != null) {
+                    return NetworkTypeVlan.class.isAssignableFrom(npeType)
+                            || NetworkTypeFlat.class.isAssignableFrom(npeType);
+                }
+            }
         }
         return false;
     }
 
-    static boolean isFlatOrVlanNetwork(Network network) {
-        return network != null
-                && (isNetworkOfType(network, NetworkTypeVlan.class) || isNetworkOfType(network, NetworkTypeFlat.class));
-    }
-
     static boolean isVlanOrVxlanNetwork(Class<? extends NetworkTypeBase> type) {
         return type.isAssignableFrom(NetworkTypeVxlan.class) || type.isAssignableFrom(NetworkTypeVlan.class);
     }
@@ -1144,32 +1143,40 @@ public class NeutronvpnUtils {
      */
     public Optional<InterVpnLink> getInterVpnLinkByEndpointIp(String endpointIp) {
         InstanceIdentifier<InterVpnLinks> interVpnLinksIid = InstanceIdentifier.builder(InterVpnLinks.class).build();
-        Optional<InterVpnLinks> interVpnLinksOpData = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
-                interVpnLinksIid);
-        if (interVpnLinksOpData.isPresent()) {
-            for (InterVpnLink interVpnLink : interVpnLinksOpData.get().nonnullInterVpnLink()) {
-                if (interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(endpointIp)
-                        || interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(endpointIp)) {
-                    return Optional.of(interVpnLink);
+        Optional<InterVpnLinks> interVpnLinksOpData = null;
+        try {
+            interVpnLinksOpData = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    interVpnLinksIid);
+            if (interVpnLinksOpData.isPresent()) {
+                for (InterVpnLink interVpnLink : interVpnLinksOpData.get().nonnullInterVpnLink()) {
+                    if (interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(endpointIp)
+                            || interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(endpointIp)) {
+                        return Optional.of(interVpnLink);
+                    }
                 }
             }
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.error("getInterVpnLinkByEndpointIp: Exception when reading intervpn Links for endpoint Ip {} ",
+                    endpointIp, e);
         }
-        return Optional.absent();
+        return Optional.empty();
     }
 
-    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) {
@@ -1220,10 +1227,7 @@ public class NeutronvpnUtils {
         Optional<VpnInstances> vpnInstancesOptional = read(LogicalDatastoreType.CONFIGURATION, path);
         if (vpnInstancesOptional.isPresent() && vpnInstancesOptional.get().getVpnInstance() != null) {
             for (VpnInstance vpnInstance : vpnInstancesOptional.get().getVpnInstance()) {
-                if (vpnInstance.getIpv4Family() == null) {
-                    continue;
-                }
-                List<String> rds = vpnInstance.getIpv4Family().getRouteDistinguisher();
+                List<String> rds = vpnInstance.getRouteDistinguisher();
                 if (rds != null) {
                     existingRDs.addAll(rds);
                 }
@@ -1233,9 +1237,7 @@ public class NeutronvpnUtils {
     }
 
     protected boolean doesVpnExist(Uuid vpnId) {
-        InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class,
-                new VpnMapKey(vpnId)).build();
-        return read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier).isPresent();
+        return read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier(vpnId)).isPresent();
     }
 
     protected Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
@@ -1307,8 +1309,7 @@ public class NeutronvpnUtils {
      */
     protected List<Subnetmap> getNeutronRouterSubnetMaps(Uuid routerId) {
         List<Subnetmap> subnetIdList = new ArrayList<>();
-        Optional<Subnetmaps> subnetMaps = read(LogicalDatastoreType.CONFIGURATION,
-            InstanceIdentifier.builder(Subnetmaps.class).build());
+        Optional<Subnetmaps> subnetMaps = read(LogicalDatastoreType.CONFIGURATION, SUBNETMAPS_IID);
         if (subnetMaps.isPresent() && subnetMaps.get().getSubnetmap() != null) {
             for (Subnetmap subnetmap : subnetMaps.get().getSubnetmap()) {
                 if (routerId.equals(subnetmap.getRouterId())) {
@@ -1339,7 +1340,7 @@ public class NeutronvpnUtils {
         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
             .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
-                LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
+                LogicalDatastoreType.CONFIGURATION, id).map(
                 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
                         .VpnInstance::getVrfId).orElse(null);
     }
@@ -1395,8 +1396,7 @@ public class NeutronvpnUtils {
     }
 
     protected InstanceIdentifier<VpnInstanceOpDataEntry> getVpnOpDataIdentifier(String primaryRd) {
-        return InstanceIdentifier.builder(VpnInstanceOpData.class)
-                .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(primaryRd)).build();
+        return VPN_INSTANCE_OP_DATA_IID.child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(primaryRd));
     }
 
     public boolean shouldVpnHandleIpVersionChoiceChange(IpVersionChoice ipVersion, Uuid routerId, boolean add) {
@@ -1428,8 +1428,7 @@ public class NeutronvpnUtils {
         if (sm == null) {
             return false;
         }
-        InstanceIdentifier<Subnetmaps> subnetMapsId = InstanceIdentifier.builder(Subnetmaps.class).build();
-        Optional<Subnetmaps> allSubnetMaps = read(LogicalDatastoreType.CONFIGURATION, subnetMapsId);
+        Optional<Subnetmaps> allSubnetMaps = read(LogicalDatastoreType.CONFIGURATION, SUBNETMAPS_IID);
         // calculate and store in list IpVersion for each subnetMap, belonging to current VpnInstance
         List<IpVersionChoice> snIpVersions = new ArrayList<>();
         for (Subnetmap snMap : allSubnetMaps.get().nonnullSubnetmap()) {
@@ -1467,13 +1466,13 @@ public class NeutronvpnUtils {
 
     public void updateVpnInstanceWithIpFamily(String vpnName, IpVersionChoice ipVersion, boolean add) {
         jobCoordinator.enqueueJob("VPN-" + vpnName, () -> {
-            VpnInstanceOpDataEntry vpnInstanceOpDataEntry = getVpnInstanceOpDataEntryFromVpnId(vpnName);
-            if (vpnInstanceOpDataEntry == null) {
+            VpnInstance vpnInstance = getVpnInstance(dataBroker, new Uuid(vpnName));
+            if (vpnInstance == null) {
                 return Collections.emptyList();
             }
-            if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) {
+            if (vpnInstance.isL2vpn()) {
                 LOG.debug("updateVpnInstanceWithIpFamily: Update VpnInstance {} with ipFamily {}."
-                        + "VpnInstanceOpDataEntry is L2 instance. Do nothing.", vpnName, ipVersion);
+                        + "VpnInstance is L2 instance. Do nothing.", vpnName, ipVersion);
                 return Collections.emptyList();
             }
             if (ipVersion == IpVersionChoice.UNDEFINED) {
@@ -1481,26 +1480,32 @@ public class NeutronvpnUtils {
                         + "is not allowed. Do nothing", vpnName);
                 return Collections.emptyList();
             }
-            VpnInstanceOpDataEntryBuilder builder = new VpnInstanceOpDataEntryBuilder(vpnInstanceOpDataEntry);
+            VpnInstanceBuilder builder = new VpnInstanceBuilder(vpnInstance);
             boolean ipConfigured = add;
-            if (ipVersion.isIpVersionChosen(IpVersionChoice.IPV4AND6)) {
-                builder.setIpv4Configured(ipConfigured);
-                builder.setIpv6Configured(ipConfigured);
-            } else if (ipVersion.isIpVersionChosen(IpVersionChoice.IPV4)) {
-                builder.setIpv4Configured(ipConfigured);
-            } else if (ipVersion.isIpVersionChosen(IpVersionChoice.IPV6)) {
-                builder.setIpv6Configured(ipConfigured);
+
+            int originalValue = vpnInstance.getIpAddressFamilyConfigured().getIntValue();
+            int updatedValue = ipVersion.choice;
+
+            if (originalValue != updatedValue) {
+                if (ipConfigured) {
+                    originalValue = originalValue == 0 ? updatedValue : updatedValue + originalValue;
+                } else {
+                    originalValue = 10 - updatedValue;
+                }
+            } else if (!ipConfigured) {
+                originalValue = 0;
             }
+
+            builder.setIpAddressFamilyConfigured(VpnInstance.IpAddressFamilyConfigured.forValue(originalValue));
+
+            InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
+                    .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
+            LOG.info("updateVpnInstanceWithIpFamily: Successfully {} IP family {} to Vpn {}",
+                    add == true ? "added" : "removed", ipVersion, vpnName);
             return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
-                    OPERATIONAL, tx -> {
-                    InstanceIdentifier<VpnInstanceOpDataEntry> id = InstanceIdentifier
-                            .builder(VpnInstanceOpData.class).child(VpnInstanceOpDataEntry.class,
-                                        new VpnInstanceOpDataEntryKey(vpnInstanceOpDataEntry.getVrfId())).build();
-                    tx.merge(id, builder.build(), false);
-                    LOG.info("updateVpnInstanceWithIpFamily: Successfully {} {} to Vpn {}",
-                            add == true ? "added" : "removed", ipVersion, vpnName);
-                }));
+                    CONFIGURATION, tx -> tx.merge(vpnIdentifier, builder.build(), false)));
         });
+        return;
     }
 
     /**
@@ -1660,8 +1665,7 @@ public class NeutronvpnUtils {
                     + "Primary RD not found", choice, vpn.getValue());
             return;
         }
-        InstanceIdentifier<VpnInstanceOpDataEntry> id = InstanceIdentifier.builder(VpnInstanceOpData.class)
-              .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(primaryRd)).build();
+        InstanceIdentifier<VpnInstanceOpDataEntry> id = getVpnOpDataIdentifier(primaryRd);
 
         Optional<VpnInstanceOpDataEntry> vpnInstanceOpDataEntryOptional =
             read(LogicalDatastoreType.OPERATIONAL, id);
@@ -1739,7 +1743,7 @@ public class NeutronvpnUtils {
         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
                 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
-                LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
+                LogicalDatastoreType.CONFIGURATION, id).map(
                 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
                         .VpnInstance::getVpnId).orElse(null).toJava();
     }
@@ -1766,7 +1770,7 @@ public class NeutronvpnUtils {
         jobCoordinator.enqueueJob(jobKey, () -> {
             SettableFuture<Optional<T>> settableFuture = SettableFuture.create();
             List futures = Collections.singletonList(settableFuture);
-            try (ReadOnlyTransaction tx = dataBroker.newReadOnlyTransaction()) {
+            try (ReadTransaction tx = dataBroker.newReadOnlyTransaction()) {
                 Futures.addCallback(tx.read(datastoreType, iid),
                         new SettableFutureCallback<Optional<T>>(settableFuture) {
                             @Override
@@ -1781,6 +1785,10 @@ public class NeutronvpnUtils {
         }, JOB_MAX_RETRIES);
     }
 
+    private static InstanceIdentifier<VpnMap> vpnMapIdentifier(Uuid uuid) {
+        return VPN_MAPS_IID.child(VpnMap.class, new VpnMapKey(uuid));
+    }
+
     private class SettableFutureCallback<T> implements FutureCallback<T> {
 
         private final SettableFuture<T> settableFuture;