Do not use char[]-based union access
[netvirt.git] / neutronvpn / impl / src / main / java / org / opendaylight / netvirt / neutronvpn / NeutronvpnManager.java
index 1f01ddeb0117a46b7e4bf826d258efc174bae65a..ebf370d56d84599eeeb0d2e9065c6a3006de172e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2015, 2017 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright © 2015, 2018 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,
@@ -8,9 +8,8 @@
 package org.opendaylight.netvirt.neutronvpn;
 
 import static java.util.Collections.singletonList;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL;
 import static org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker.syncReadOptional;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
@@ -45,13 +44,14 @@ import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.infra.Datastore;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.infrautils.utils.concurrent.KeyedLocks;
 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
@@ -93,6 +93,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.lea
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry.BgpvpnType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
@@ -201,6 +202,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
     private final NeutronEvpnUtils neutronEvpnUtils;
     private final JobCoordinator jobCoordinator;
     private final NeutronvpnUtils neutronvpnUtils;
+    private final IVpnManager vpnManager;
     private final ConcurrentHashMap<Uuid, Uuid> unprocessedPortsMap = new ConcurrentHashMap<>();
     private final NeutronvpnAlarms neutronvpnAlarm = new NeutronvpnAlarms();
     private final KeyedLocks<Uuid> vpnLock = new KeyedLocks<>();
@@ -224,6 +226,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         neutronEvpnUtils = new NeutronEvpnUtils(dataBroker, vpnManager, jobCoordinator);
         this.jobCoordinator = jobCoordinator;
         this.neutronvpnUtils = neutronvpnUtils;
+        this.vpnManager = vpnManager;
 
         configureFeatures();
     }
@@ -786,7 +789,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
     }
 
     protected Adjacencies createPortIpAdjacencies(Port port, Boolean isRouterInterface,
-                                  WriteTransaction wrtConfigTxn, Subnetmap sn, VpnInterface vpnIface) {
+                                                  TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn,
+                                                  Subnetmap sn, VpnInterface vpnIface) {
         List<Adjacency> adjList = new ArrayList<>();
         if (vpnIface != null) {
             adjList = vpnIface.augmentation(Adjacencies.class).getAdjacency();
@@ -794,7 +798,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         String infName = port.getUuid().getValue();
         LOG.trace("neutronVpnManager: create config adjacencies for Port: {}", infName);
         for (FixedIps ip : port.getFixedIps()) {
-            String ipValue = String.valueOf(ip.getIpAddress().getValue());
+            String ipValue = ip.getIpAddress().stringValue();
             String ipPrefix = ip.getIpAddress().getIpv4Address() != null ? ipValue + "/32" : ipValue + "/128";
             if (sn != null && !FibHelper.doesPrefixBelongToSubnet(ipPrefix, sn.getSubnetIp(), false)) {
                 continue;
@@ -834,7 +838,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         return new AdjacenciesBuilder().setAdjacency(adjList).build();
     }
 
-    protected void createVpnInterface(Collection<Uuid> vpnIds, Port port, WriteTransaction wrtConfigTxn) {
+    protected void createVpnInterface(Collection<Uuid> vpnIds, Port port,
+                                      TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
         boolean isRouterInterface = false;
         if (port.getDeviceOwner() != null) {
             isRouterInterface = NeutronConstants.DEVICE_OWNER_ROUTER_INF.equals(port.getDeviceOwner());
@@ -842,11 +847,11 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         Adjacencies adjs = createPortIpAdjacencies(port, isRouterInterface, wrtConfigTxn, null, null);
         String infName = port.getUuid().getValue();
         LOG.trace("createVpnInterface for Port: {}, isRouterInterface: {}", infName, isRouterInterface);
-        writeVpnInterfaceToDs(vpnIds, infName, adjs, isRouterInterface, wrtConfigTxn);
+        writeVpnInterfaceToDs(vpnIds, infName, adjs, port.getNetworkId(), isRouterInterface, wrtConfigTxn);
     }
 
     protected void withdrawPortIpFromVpnIface(Uuid vpnId, Uuid internetVpnId,
-                       Port port, Subnetmap sn, WriteTransaction wrtConfigTxn) {
+                       Port port, Subnetmap sn, TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
         String infName = port.getUuid().getValue();
         InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
         Optional<VpnInterface> optionalVpnInterface = null;
@@ -929,10 +934,12 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
 
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
-    protected void deleteVpnInterface(String infName, @Nullable String vpnId, WriteTransaction wrtConfigTxn) {
+    protected void deleteVpnInterface(String infName, @Nullable String vpnId,
+                                      TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
         if (wrtConfigTxn == null) {
             ListenableFutures.addErrorLogging(
-                    txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> deleteVpnInterface(infName, vpnId, tx)),
+                    txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+                        tx -> deleteVpnInterface(infName, vpnId, tx)),
                     LOG, "Error deleting VPN interface {} {}", infName, vpnId);
             return;
         }
@@ -965,16 +972,17 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 }
                 VpnInterfaceBuilder vpnIfBuilder = new VpnInterfaceBuilder(optionalVpnInterface.get())
                         .setVpnInstanceNames(vpnList);
-                wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIfBuilder
+                wrtConfigTxn.put(vpnIfIdentifier, vpnIfBuilder
                         .build());
             }
         }
         LOG.debug("Deleting vpn interface {}", infName);
-        wrtConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
+        wrtConfigTxn.delete(vpnIfIdentifier);
     }
 
     protected void removeVpnFromVpnInterface(Uuid vpnId, Port port,
-                                     WriteTransaction writeConfigTxn, Subnetmap sm) {
+                                             TypedWriteTransaction<Datastore.Configuration> writeConfigTxn,
+                                             Subnetmap sm) {
         if (vpnId == null || port == null) {
             return;
         }
@@ -1020,7 +1028,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 }
                 List<FixedIps> ips = port.getFixedIps();
                 for (FixedIps ip : ips) {
-                    String ipValue = String.valueOf(ip.getIpAddress().getValue());
+                    String ipValue = ip.getIpAddress().stringValue();
                     neutronvpnUtils.removeVpnPortFixedIpToPort(vpnId.getValue(),
                             ipValue, writeConfigTxn);
                 }
@@ -1030,8 +1038,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                     }
                     deleteVpnInterface(port.getUuid().getValue(), null /* vpn-id */, writeConfigTxn);
                 } else {
-                    writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIfBuilder
-                            .build());
+                    writeConfigTxn.put(vpnIfIdentifier, vpnIfBuilder.build());
                 }
             } else {
                 LOG.info("removeVpnFromVpnInterface: VPN Interface {} not found", infName);
@@ -1042,7 +1049,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
     }
 
     protected void updateVpnInterface(Uuid vpnId, Uuid oldVpnId, Port port, boolean isBeingAssociated,
-                                      boolean isSubnetIp, WriteTransaction writeConfigTxn) {
+                                      boolean isSubnetIp,
+                                      TypedWriteTransaction<Datastore.Configuration> writeConfigTxn) {
         if (vpnId == null || port == null) {
             return;
         }
@@ -1098,7 +1106,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 }
                 List<FixedIps> ips = port.getFixedIps();
                 for (FixedIps ip : ips) {
-                    String ipValue = String.valueOf(ip.getIpAddress().getValue());
+                    String ipValue = ip.getIpAddress().stringValue();
                     if (oldVpnId != null) {
                         neutronvpnUtils.removeVpnPortFixedIpToPort(oldVpnId.getValue(),
                                 ipValue, writeConfigTxn);
@@ -1106,8 +1114,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                     neutronvpnUtils.createVpnPortFixedIpToPort(vpnId.getValue(), ipValue, infName, port
                             .getMacAddress().getValue(), isSubnetIp, writeConfigTxn);
                 }
-                writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIfBuilder
-                        .build());
+                writeConfigTxn.put(vpnIfIdentifier, vpnIfBuilder.build());
             } else {
                 LOG.error("VPN Interface {} not found", infName);
             }
@@ -1399,8 +1406,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                                 vpnIdentifier);
                 // eliminating implicitly created (router or VLAN provider external network specific) VPN from
                 // getL3VPN output
-                if (optionalVpn.isPresent() && (optionalVpn.get().getIpv4Family().getRouteDistinguisher() != null)
-                        || (optionalVpn.get().getIpv6Family().getRouteDistinguisher() != null)) {
+                if (optionalVpn.isPresent() && optionalVpn.get().getIpv4Family().getRouteDistinguisher() != null
+                        || optionalVpn.get().getIpv6Family().getRouteDistinguisher() != null) {
                     vpns.add(optionalVpn.get());
                 } else {
                     result.set(
@@ -1599,7 +1606,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 final Boolean isRouterInterface = port.getDeviceOwner()
                         .equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF) ? true : false;
                 jobCoordinator.enqueueJob("PORT-" + portId.getValue(), () -> singletonList(
-                    txRunner.callWithNewWriteOnlyTransactionAndSubmit(wrtConfigTxn -> {
+                    txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, wrtConfigTxn -> {
                         Adjacencies portAdj = createPortIpAdjacencies(port, isRouterInterface, wrtConfigTxn, sn,
                                     vpnIface);
                         if (vpnIface == null) {
@@ -1612,7 +1619,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                                 listVpn.add(internetId);
                             }
                             writeVpnInterfaceToDs(listVpn,
-                                    vpnInfName, portAdj, isRouterInterface, wrtConfigTxn);
+                                    vpnInfName, portAdj, port.getNetworkId(), isRouterInterface, wrtConfigTxn);
                             if (sn.getRouterId() != null) {
                                 addToNeutronRouterInterfacesMap(sn.getRouterId(), portId.getValue());
                             }
@@ -1689,16 +1696,17 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 LOG.debug("withdrawing subnet IP {} from vpn-interface {}", sn.getSubnetIp(), portId.getValue());
                 final Port port = neutronvpnUtils.getNeutronPort(portId);
                 jobCoordinator.enqueueJob("PORT-" + portId.getValue(),
-                    () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
-                        if (port != null) {
-                            withdrawPortIpFromVpnIface(vpnId, internetId, port, sn, tx);
-                        } else {
-                            LOG.warn(
-                                    "Cannot proceed with withdrawPortIpFromVpnIface for port {} in subnet {} since "
-                                            + "port is absent in Neutron config DS", portId.getValue(),
-                                    subnet.getValue());
-                        }
-                    })));
+                    () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
+                            CONFIGURATION, tx -> {
+                            if (port != null) {
+                                withdrawPortIpFromVpnIface(vpnId, internetId, port, sn, tx);
+                            } else {
+                                LOG.warn(
+                                        "Cannot proceed with withdrawPortIpFromVpnIface for port {} in subnet {} since "
+                                                + "port is absent in Neutron config DS", portId.getValue(),
+                                        subnet.getValue());
+                            }
+                        })));
             }
         }
         //update subnet-vpn association
@@ -1722,7 +1730,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         }
 
         jobCoordinator.enqueueJob("VPN-" + vpn.getValue(), () -> singletonList(
-            txRunner.callWithNewWriteOnlyTransactionAndSubmit(wrtConfigTxn -> {
+            txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, wrtConfigTxn -> {
                 if (isBeingAssociated) {
                     updateVpnInterface(vpn, null, neutronvpnUtils.getNeutronPort(
                             sm.getRouterInterfacePortId()), true, true, wrtConfigTxn);
@@ -1741,14 +1749,15 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 LOG.debug("Updating vpn-interface for port {} isBeingAssociated {}",
                         port.getValue(), isBeingAssociated);
                 jobCoordinator.enqueueJob("PORT-" + port.getValue(),
-                    () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
-                        if (isBeingAssociated) {
-                            updateVpnInterface(vpn, null, neutronvpnUtils.getNeutronPort(port),
-                                    true, false, tx);
-                        } else {
-                            removeVpnFromVpnInterface(vpn, neutronvpnUtils.getNeutronPort(port), tx, sm);
-                        }
-                    })));
+                    () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+                        tx -> {
+                            if (isBeingAssociated) {
+                                updateVpnInterface(vpn, null, neutronvpnUtils.getNeutronPort(port),
+                                        true, false, tx);
+                            } else {
+                                removeVpnFromVpnInterface(vpn, neutronvpnUtils.getNeutronPort(port), tx, sm);
+                            }
+                        })));
             }
         }
     }
@@ -1770,7 +1779,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         //Update Router Interface first synchronously.
         //CAUTION:  Please DONOT make the router interface VPN Movement as an asynchronous commit again !
         ListenableFuture<Void> future =
-                txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> updateVpnInterface(newVpnId, oldVpnId,
+                txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+                    tx -> updateVpnInterface(newVpnId, oldVpnId,
                         neutronvpnUtils.getNeutronPort(sn.getRouterInterfacePortId()),
                         isBeingAssociated, true, tx));
         Futures.addCallback(future, new FutureCallback<Void>() {
@@ -1784,7 +1794,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                         LOG.debug("Updating vpn-interface for port {} isBeingAssociated {}",
                                 port.getValue(), isBeingAssociated);
                         jobCoordinator.enqueueJob("PORT-" + port.getValue(), () -> Collections.singletonList(
-                                txRunner.callWithNewWriteOnlyTransactionAndSubmit(
+                                txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
                                     tx -> updateVpnInterface(newVpnId, oldVpnId,
                                             neutronvpnUtils.getNeutronPort(port), isBeingAssociated, false,
                                             tx))));
@@ -1878,8 +1888,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
     public void addInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
                                   HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
         for (Routes route : interVpnLinkRoutes) {
-            String nexthop = String.valueOf(route.getNexthop().getValue());
-            String destination = String.valueOf(route.getDestination().getValue());
+            String nexthop = route.getNexthop().stringValue();
+            String destination = route.getDestination().stringValue();
             InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
             if (isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink)) {
                 AddStaticRouteInput rpcInput =
@@ -1904,7 +1914,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             } else {
                 // Any other case is a fault.
                 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
-                        String.valueOf(route.getDestination().getValue()), nexthop);
+                        route.getDestination().stringValue(), nexthop);
                 continue;
             }
         }
@@ -1921,8 +1931,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
     public void removeInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
                                      HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
         for (Routes route : interVpnLinkRoutes) {
-            String nexthop = String.valueOf(route.getNexthop().getValue());
-            String destination = String.valueOf(route.getDestination().getValue());
+            String nexthop = route.getNexthop().stringValue();
+            String destination = route.getDestination().stringValue();
             InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
             if (isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink)) {
                 RemoveStaticRouteInput rpcInput =
@@ -1935,7 +1945,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             } else {
                 // Any other case is a fault.
                 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
-                        String.valueOf(route.getDestination().getValue()), nexthop);
+                        route.getDestination().stringValue(), nexthop);
                 continue;
             }
         }
@@ -1962,8 +1972,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             if (route == null || route.getNexthop() == null || route.getDestination() == null) {
                 LOG.error("Incorrect input received for extra route. {}", route);
             } else {
-                String nextHop = String.valueOf(route.getNexthop().getValue());
-                String destination = String.valueOf(route.getDestination().getValue());
+                String nextHop = route.getNexthop().stringValue();
+                String destination = route.getDestination().stringValue();
                 if (!nextHop.equals(fixedIp)) {
                     LOG.trace("FixedIP {} is not extra route nexthop for destination {}", fixedIp, destination);
                     continue;
@@ -1995,8 +2005,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             if (route == null || route.getNexthop() == null || route.getDestination() == null) {
                 LOG.error("Incorrect input received for extra route. {}", route);
             } else {
-                String nextHop = String.valueOf(route.getNexthop().getValue());
-                String destination = String.valueOf(route.getDestination().getValue());
+                String nextHop = route.getNexthop().stringValue();
+                String destination = route.getDestination().stringValue();
                 String infName = neutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(vpnId.getValue(),
                         nextHop);
                 if (infName != null) {
@@ -2069,22 +2079,22 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         }
         for (Routes route : routeList) {
             // count  the number of nexthops for each same route.getDestingation().getValue()
-            String destination = String.valueOf(route.getDestination().getValue());
-            String nextHop = String.valueOf(route.getNexthop().getValue());
-            List<String> nextHopList = new ArrayList();
+            String destination = route.getDestination().stringValue();
+            String nextHop = route.getNexthop().stringValue();
+            List<String> nextHopList = new ArrayList<>();
             nextHopList.add(nextHop);
             int nbNextHops = 0;
             for (Routes routeTmp : routeList) {
-                String routeDest = String.valueOf(routeTmp.getDestination().getValue());
+                String routeDest = routeTmp.getDestination().stringValue();
                 if (!destination.equals(routeDest)) {
                     continue;
                 }
-                String routeNextH = String.valueOf(routeTmp.getNexthop().getValue());
+                String routeNextH = routeTmp.getNexthop().stringValue();
                 if (nextHop.equals(routeNextH)) {
                     continue;
                 }
                 nbNextHops++;
-                nextHopList.add(new String(routeTmp.getNexthop().getValue()));
+                nextHopList.add(routeTmp.getNexthop().stringValue());
             }
             final List<String> rdList = new ArrayList<>();
             if (vpnInstance.getIpv4Family() != null
@@ -2120,7 +2130,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
 
             // 4. Prefix in question
             detailsAlarm.append(" for prefix: ");
-            detailsAlarm.append(route.getDestination().getValue());
+            detailsAlarm.append(route.getDestination().stringValue());
 
             // 5. List of NHs for the prefix
             detailsAlarm.append(" for nextHops: ");
@@ -2143,8 +2153,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         for (Routes route : routeList) {
             if (route != null && route.getNexthop() != null && route.getDestination() != null) {
                 boolean isLockAcquired = false;
-                String nextHop = String.valueOf(route.getNexthop().getValue());
-                String destination = String.valueOf(route.getDestination().getValue());
+                String nextHop = route.getNexthop().stringValue();
+                String destination = route.getDestination().stringValue();
                 String infName = neutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(vpnId.getValue(),
                         nextHop);
                 if (infName == null) {
@@ -2348,6 +2358,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                                                + "associated with", vpnId.getValue()));
                 return failedNwList;
             }
+            Set<VpnTarget> routeTargets = vpnManager.getRtListForVpn(vpnId.getValue());
             for (Uuid nw : networkList) {
                 Network network = neutronvpnUtils.getNeutronNetwork(nw);
                 if (network == null) {
@@ -2372,36 +2383,42 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                                                    + "another VPN %s", nw.getValue(), networkVpnId.getValue()));
                     continue;
                 }
-                if (neutronvpnUtils.getIsExternal(network) && !associateExtNetworkToVpn(vpnId, network)) {
+                if (NeutronvpnUtils.getIsExternal(network) && !associateExtNetworkToVpn(vpnId, network)) {
                     LOG.error("associateNetworksToVpn: Failed to associate Provider Network {} with VPN {}",
                             nw.getValue(), vpnId.getValue());
                     failedNwList.add(String.format("Failed to associate Provider Network %s with VPN %s",
                             nw.getValue(), vpnId.getValue()));
                     continue;
                 }
-                List<Uuid> networkSubnets = neutronvpnUtils.getSubnetIdsFromNetworkId(nw);
-                if (networkSubnets == null) {
+                List<Subnetmap> subnetmapList = neutronvpnUtils.getSubnetmapListFromNetworkId(nw);
+                if (subnetmapList == null || subnetmapList.isEmpty()) {
                     passedNwList.add(nw);
                     continue;
                 }
-                for (Uuid subnet : networkSubnets) {
-                    Uuid subnetVpnId = neutronvpnUtils.getVpnForSubnet(subnet);
+                if (vpnManager.checkForOverlappingSubnets(nw, subnetmapList, vpnId, routeTargets, failedNwList)) {
+                    continue;
+                }
+                for (Subnetmap subnetmap : subnetmapList) {
+                    Uuid subnetId = subnetmap.getId();
+                    Uuid subnetVpnId = neutronvpnUtils.getVpnForSubnet(subnetId);
                     if (subnetVpnId != null) {
-                        LOG.error("associateNetworksToVpn: Failed to associate subnet {} with VPN {} as it is already "
-                                  + "associated", subnet.getValue(), subnetVpnId.getValue());
-                        failedNwList.add(String.format("Failed to associate subnet %s with VPN %s as it is already "
-                                                       + "associated", subnet.getValue(), vpnId.getValue()));
+                        LOG.error("associateNetworksToVpn: Failed to associate subnet {} with VPN {}"
+                                + " as it is already associated", subnetId.getValue(), subnetVpnId.getValue());
+                        failedNwList.add(String.format("Failed to associate subnet %s with VPN %s"
+                                + " as it is already associated", subnetId.getValue(), vpnId.getValue()));
                         continue;
                     }
-                    Subnetmap sm = neutronvpnUtils.getSubnetmap(subnet);
-                    if (neutronvpnUtils.shouldVpnHandleIpVersionChangeToAdd(sm, vpnId)) {
+                    if (neutronvpnUtils.shouldVpnHandleIpVersionChangeToAdd(subnetmap, vpnId)) {
                         neutronvpnUtils.updateVpnInstanceWithIpFamily(vpnId.getValue(),
-                                NeutronvpnUtils.getIpVersionFromString(sm.getSubnetIp()), true);
+                                NeutronvpnUtils.getIpVersionFromString(subnetmap.getSubnetIp()), true);
                     }
-                    if (!neutronvpnUtils.getIsExternal(network)) {
-                        LOG.debug("associateNetworksToVpn: Add subnet {} to VPN {}", subnet.getValue(),
+                    if (!NeutronvpnUtils.getIsExternal(network)) {
+                        LOG.debug("associateNetworksToVpn: Add subnet {} to VPN {}", subnetId.getValue(),
+                                vpnId.getValue());
+                        addSubnetToVpn(vpnId, subnetId, null);
+                        vpnManager.updateRouteTargetsToSubnetAssociation(routeTargets, subnetmap.getSubnetIp(),
                                 vpnId.getValue());
-                        addSubnetToVpn(vpnId, subnet, null);
+                        passedNwList.add(nw);
                     }
                 }
                 passedNwList.add(nw);
@@ -2464,6 +2481,11 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             return failedNwList;
         }
         for (Uuid nw : networkList) {
+            List<Uuid> networkSubnets = neutronvpnUtils.getSubnetIdsFromNetworkId(nw);
+            if (networkSubnets == null) {
+                passedNwList.add(nw);
+                continue;
+            }
             Network network = neutronvpnUtils.getNeutronNetwork(nw);
             if (network == null) {
                 LOG.error("dissociateNetworksFromVpn: Network {} not found in ConfigDS");
@@ -2498,22 +2520,20 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                     continue;
                 }
             }
-            List<Uuid> networkSubnets = neutronvpnUtils.getSubnetIdsFromNetworkId(nw);
-            if (networkSubnets == null) {
-                passedNwList.add(nw);
-                continue;
-            }
+            Set<VpnTarget> routeTargets = vpnManager.getRtListForVpn(vpnId.getValue());
             for (Uuid subnet : networkSubnets) {
-                Subnetmap sm = neutronvpnUtils.getSubnetmap(subnet);
-                if (neutronvpnUtils.shouldVpnHandleIpVersionChangeToRemove(sm, vpnId)) {
+                Subnetmap subnetmap = neutronvpnUtils.getSubnetmap(subnet);
+                if (neutronvpnUtils.shouldVpnHandleIpVersionChangeToRemove(subnetmap, vpnId)) {
                     IpVersionChoice ipVersionsToRemove = IpVersionChoice.UNDEFINED;
-                    IpVersionChoice ipVersion = NeutronvpnUtils.getIpVersionFromString(sm.getSubnetIp());
+                    IpVersionChoice ipVersion = NeutronvpnUtils.getIpVersionFromString(subnetmap.getSubnetIp());
                     neutronvpnUtils.updateVpnInstanceWithIpFamily(vpnId.getValue(),
                         ipVersionsToRemove.addVersion(ipVersion), false);
                 }
                 LOG.debug("dissociateNetworksFromVpn: Withdraw subnet {} from VPN {}", subnet.getValue(),
                           vpnId.getValue());
                 removeSubnetFromVpn(vpnId, subnet, null);
+                vpnManager.removeRouteTargetsToSubnetAssociation(routeTargets, subnetmap.getSubnetIp(),
+                        vpnId.getValue());
                 passedNwList.add(nw);
             }
         }
@@ -2668,7 +2688,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             if (port != null) {
                 List<FixedIps> fixedIPs = port.getFixedIps();
                 for (FixedIps ip : fixedIPs) {
-                    fixedIPList.add(String.valueOf(ip.getIpAddress().getValue()));
+                    fixedIPList.add(ip.getIpAddress().stringValue());
                 }
             } else {
                 returnMsg.append("neutron port: ").append(portId.getValue()).append(" not found");
@@ -2872,7 +2892,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         result.add("-------------------------------------------------------------------------------------------");
         InstanceIdentifier<Ports> portidentifier = InstanceIdentifier.create(Neutron.class).child(Ports.class);
 
-        Optional<Ports> ports = syncReadOptional(dataBroker, CONFIGURATION, portidentifier);
+        Optional<Ports> ports = syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, portidentifier);
         if (ports.isPresent() && ports.get().getPort() != null) {
             for (Port port : ports.get().getPort()) {
                 List<FixedIps> fixedIPs = port.getFixedIps();
@@ -2982,7 +3002,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             return;
         }
 
-        ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+        ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
             for (String elanInterface : extElanInterfaces) {
                 createExternalVpnInterface(extNetId, elanInterface, tx);
             }
@@ -2997,32 +3017,33 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             LOG.error("No external ports attached for external network {}", extNetId.getValue());
             return;
         }
-        ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+        ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
             for (String elanInterface : extElanInterfaces) {
                 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils
                         .buildVpnInterfaceIdentifier(elanInterface);
                 LOG.info("Removing vpn interface {}", elanInterface);
-                tx.delete(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
+                tx.delete(vpnIfIdentifier);
             }
         }), LOG, "Error removing external VPN interfaces for {}", extNetId);
     }
 
-    private void createExternalVpnInterface(Uuid vpnId, String infName, WriteTransaction wrtConfigTxn) {
-        writeVpnInterfaceToDs(Collections.singletonList(vpnId), infName, null,
+    private void createExternalVpnInterface(Uuid vpnId, String infName,
+                                            TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
+        writeVpnInterfaceToDs(Collections.singletonList(vpnId), infName, null, vpnId /* external network id */,
                 false /* not a router iface */, wrtConfigTxn);
     }
 
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
     private void writeVpnInterfaceToDs(@Nonnull Collection<Uuid> vpnIdList, String infName, Adjacencies adjacencies,
-            Boolean isRouterInterface, WriteTransaction wrtConfigTxn) {
+            Uuid networkUuid, Boolean isRouterInterface, TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
         if (vpnIdList.isEmpty() || infName == null) {
-            LOG.error("vpn id or interface is null");
+            LOG.error("vpnid is empty or interface({}) is null", infName);
             return;
         }
         if (wrtConfigTxn == null) {
-            ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
-                tx -> writeVpnInterfaceToDs(vpnIdList, infName, adjacencies, isRouterInterface, tx)), LOG,
+            ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+                tx -> writeVpnInterfaceToDs(vpnIdList, infName, adjacencies, networkUuid, isRouterInterface, tx)), LOG,
                 "Error writing VPN interface");
             return;
         }
@@ -3038,26 +3059,38 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 .setName(infName)
                 .setVpnInstanceNames(vpnIdListStruct)
                 .setRouterInterface(isRouterInterface);
+        LOG.info("Network Id is {}", networkUuid);
+        if (networkUuid != null) {
+            Network portNetwork = neutronvpnUtils.getNeutronNetwork(networkUuid);
+            ProviderTypes providerType = NeutronvpnUtils.getProviderNetworkType(portNetwork);
+            NetworkAttributes.NetworkType networkType = (providerType != null)
+                    ? NetworkAttributes.NetworkType.valueOf(providerType.getName()) : null;
+            String segmentationId = NeutronvpnUtils.getSegmentationIdFromNeutronNetwork(portNetwork);
+            vpnb.setNetworkId(networkUuid).setNetworkType(networkType)
+                .setSegmentationId(segmentationId != null ? Long.parseLong(segmentationId) : 0L);
+        }
+
         if (adjacencies != null) {
             vpnb.addAugmentation(Adjacencies.class, adjacencies);
         }
         VpnInterface vpnIf = vpnb.build();
         try {
             LOG.info("Creating vpn interface {}", vpnIf);
-            wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
+            wrtConfigTxn.put(vpnIfIdentifier, vpnIf);
         } catch (Exception ex) {
             LOG.error("Creation of vpninterface {} failed", infName, ex);
         }
     }
 
     private void updateVpnInterfaceWithAdjacencies(Uuid vpnId, String infName, Adjacencies adjacencies,
-            WriteTransaction wrtConfigTxn) {
+                                                   TypedWriteTransaction<Datastore.Configuration> wrtConfigTxn) {
         if (vpnId == null || infName == null) {
             LOG.error("vpn id or interface is null");
             return;
         }
         if (wrtConfigTxn == null) {
-            ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+            LOG.error("updateVpnInterfaceWithAdjancies called with wrtConfigTxn as null");
+            ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
                 updateVpnInterfaceWithAdjacencies(vpnId, infName, adjacencies, tx);
             }), LOG, "Error updating VPN interface with adjacencies");
             return;
@@ -3099,7 +3132,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                     vpnIfBuilder.setVpnInstanceNames(listVpnInstances);
                 }
                 LOG.info("Updating vpn interface {} with new adjacencies", infName);
-                wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIfBuilder.build());
+                wrtConfigTxn.put(vpnIfIdentifier, vpnIfBuilder.build());
             }
         } catch (IllegalStateException | ReadFailedException ex) {
             LOG.error("Update of vpninterface {} failed", infName, ex);
@@ -3215,7 +3248,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         Optional<VpnInstanceOpDataEntry> vpnInstanceOpDataOptional;
         try {
             vpnInstanceOpDataOptional = SingleTransactionDataBroker
-                    .syncReadOptional(dataBroker, OPERATIONAL, neutronvpnUtils.getVpnOpDataIdentifier(primaryRd));
+                .syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                    neutronvpnUtils.getVpnOpDataIdentifier(primaryRd));
         } catch (ReadFailedException e) {
             LOG.error("getExistingOperationalVpn: Exception while checking operational status of vpn with rd {}",
                     primaryRd, e);