yang change to make remove deprecated leaf-elements
[netvirt.git] / vpnservice / neutronvpn / neutronvpn-impl / src / main / java / org / opendaylight / netvirt / neutronvpn / NeutronvpnManager.java
index 40d965602ba34f232a440b62bf755d8f357ca388..b5ac341b7d93fb5c4592745b33b42cced847bf39 100644 (file)
@@ -11,7 +11,6 @@ import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.SettableFuture;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EventListener;
@@ -19,6 +18,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
@@ -26,8 +26,8 @@ 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.genius.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
-import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.netvirt.elanmanager.api.IElanService;
 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
@@ -74,7 +74,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev15060
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.L3vpnInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterAssociatedToVpn;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterAssociatedToVpnBuilder;
@@ -110,6 +109,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtension;
 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.Subnet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
@@ -128,24 +128,20 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
     private final NotificationPublishService notificationPublishService;
     private final VpnRpcService vpnRpcService;
     private final NeutronFloatingToFixedIpMappingChangeListener floatingIpMapListener;
-    private final NeutronvpnConfig neutronvpnConfig;
-    private final IMdsalApiManager mdsalUtil;
     private final IElanService elanService;
+    private final NeutronvpnConfig neutronvpnConfig;
 
     public NeutronvpnManager(
-            final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
-            final NotificationPublishService notiPublishService, final NeutronvpnNatManager vpnNatMgr,
-            final VpnRpcService vpnRpcSrv, final IElanService elanService,
+            final DataBroker dataBroker, final NotificationPublishService notiPublishService,
+            final NeutronvpnNatManager vpnNatMgr, final VpnRpcService vpnRpcSrv, final IElanService elanService,
             final NeutronFloatingToFixedIpMappingChangeListener neutronFloatingToFixedIpMappingChangeListener,
             final NeutronvpnConfig neutronvpnConfig) {
         this.dataBroker = dataBroker;
-        mdsalUtil = mdsalManager;
         nvpnNatManager = vpnNatMgr;
         notificationPublishService = notiPublishService;
         vpnRpcService = vpnRpcSrv;
         this.elanService = elanService;
         floatingIpMapListener = neutronFloatingToFixedIpMappingChangeListener;
-        LOG.info("neutronvpnConfig: {}", neutronvpnConfig);
         this.neutronvpnConfig = neutronvpnConfig;
     }
 
@@ -160,55 +156,32 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
 
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
-    protected void updateSubnetNodeWithFixedIps(Uuid subnetId, Uuid routerId,
-                                                Uuid routerInterfaceName, String fixedIp,
-                                                String routerIntfMacAddress) {
-        Subnetmap subnetmap = null;
-        SubnetmapBuilder builder = null;
-        InstanceIdentifier<Subnetmap> id =
-            InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
+    protected void createSubnetmapNode(Uuid subnetId, String subnetIp, Uuid tenantId, Uuid networkId) {
         try {
+            InstanceIdentifier<Subnetmap> subnetMapIdentifier = NeutronvpnUtils.buildSubnetMapIdentifier(subnetId);
             synchronized (subnetId.getValue().intern()) {
-                Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+                Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                        subnetMapIdentifier);
+                SubnetmapBuilder subnetmapBuilder = null;
                 if (sn.isPresent()) {
-                    builder = new SubnetmapBuilder(sn.get());
-                    LOG.debug("WithRouterFixedIPs: Updating existing subnetmap node for subnet ID {}",
-                        subnetId.getValue());
-                } else {
-                    builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
-                    LOG.debug("WithRouterFixedIPs: creating new subnetmap node for subnet ID {}",
-                        subnetId.getValue());
-                }
-
-                builder.setRouterId(routerId);
-                builder.setRouterInterfaceName(routerInterfaceName);
-                builder.setRouterIntfMacAddress(routerIntfMacAddress);
-
-                if (fixedIp != null) {
-                    List<String> fixedIps = builder.getRouterInterfaceFixedIps();
-                    if (fixedIps == null) {
-                        fixedIps = new ArrayList<>();
-                    }
-                    fixedIps.add(fixedIp);
-                    builder.setRouterInterfaceFixedIps(fixedIps);
+                    LOG.error("subnetmap node for subnet ID {} already exists, returning", subnetId.getValue());
+                    return;
                 } else {
-                    builder.setRouterInterfaceFixedIps(null);
+                    subnetmapBuilder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId)
+                            .setSubnetIp(subnetIp).setTenantId(tenantId).setNetworkId(networkId);
+                    LOG.debug("Adding a new subnet node in Subnetmaps DS for subnet {}", subnetId.getValue());
                 }
-                subnetmap = builder.build();
-                LOG.debug("WithRouterFixedIPs Creating/Updating subnetMap node for Router FixedIps: {} ",
-                    subnetId.getValue());
-                MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
+                SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                        subnetMapIdentifier, subnetmapBuilder.build());
             }
         } catch (Exception e) {
-            LOG.error("WithRouterFixedIPs: Updation of subnetMap for Router FixedIps failed for node: {}",
-                subnetId.getValue());
+            LOG.error("Creating subnetmap node failed for subnet {}", subnetId.getValue());
         }
     }
 
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
-    protected Subnetmap updateSubnetNode(Uuid subnetId, String subnetIp, Uuid tenantId, Uuid networkId, Uuid routerId,
-                                         Uuid vpnId) {
+    private Subnetmap updateSubnetNode(Uuid subnetId, Uuid routerId, Uuid vpnId) {
         Subnetmap subnetmap = null;
         SubnetmapBuilder builder = null;
         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
@@ -221,29 +194,19 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                     builder = new SubnetmapBuilder(sn.get());
                     LOG.debug("updating existing subnetmap node for subnet ID {}", subnetId.getValue());
                 } else {
-                    builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
-                    LOG.debug("creating new subnetmap node for subnet ID {}", subnetId.getValue());
-                }
-
-                if (subnetIp != null) {
-                    builder.setSubnetIp(subnetIp);
+                    LOG.error("subnetmap node for subnet {} does not exist, returning", subnetId.getValue());
+                    return null;
                 }
                 if (routerId != null) {
                     builder.setRouterId(routerId);
                 }
-                if (networkId != null) {
-                    builder.setNetworkId(networkId);
-                }
                 if (vpnId != null) {
                     builder.setVpnId(vpnId);
                 }
-                if (tenantId != null) {
-                    builder.setTenantId(tenantId);
-                }
 
                 subnetmap = builder.build();
                 LOG.debug("Creating/Updating subnetMap node: {} ", subnetId.getValue());
-                MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
+                SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
             }
         } catch (Exception e) {
             LOG.error("Updation of subnetMap failed for node: {}", subnetId.getValue());
@@ -253,42 +216,47 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
 
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
-    protected Subnetmap removeFromSubnetNode(Uuid subnetId, Uuid networkId, Uuid routerId, Uuid vpnId, Uuid portId) {
+    protected void updateSubnetNodeWithFixedIps(Uuid subnetId, Uuid routerId,
+                                                Uuid routerInterfaceName, String fixedIp,
+                                                String routerIntfMacAddress) {
         Subnetmap subnetmap = null;
-        InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
-                .child(Subnetmap.class, new SubnetmapKey(subnetId))
-                .build();
+        SubnetmapBuilder builder = null;
+        InstanceIdentifier<Subnetmap> id =
+            InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
         try {
             synchronized (subnetId.getValue().intern()) {
                 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
                 if (sn.isPresent()) {
-                    SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
-                    if (routerId != null) {
-                        builder.setRouterId(null);
-                    }
-                    if (networkId != null) {
-                        builder.setNetworkId(null);
-                    }
-                    if (vpnId != null) {
-                        builder.setVpnId(null);
-                    }
-                    if (portId != null && builder.getPortList() != null) {
-                        List<Uuid> portList = builder.getPortList();
-                        portList.remove(portId);
-                        builder.setPortList(portList);
+                    builder = new SubnetmapBuilder(sn.get());
+                    LOG.debug("WithRouterFixedIPs: Updating existing subnetmap node for subnet ID {}",
+                        subnetId.getValue());
+                } else {
+                    builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
+                    LOG.debug("WithRouterFixedIPs: creating new subnetmap node for subnet ID {}",
+                        subnetId.getValue());
+                }
+                builder.setRouterId(routerId);
+                builder.setRouterInterfaceName(routerInterfaceName);
+                builder.setRouterIntfMacAddress(routerIntfMacAddress);
+                if (fixedIp != null) {
+                    List<String> fixedIps = builder.getRouterInterfaceFixedIps();
+                    if (fixedIps == null) {
+                        fixedIps = new ArrayList<>();
                     }
-
-                    subnetmap = builder.build();
-                    LOG.debug("Removing from existing subnetmap node: {} ", subnetId.getValue());
-                    MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
+                    fixedIps.add(fixedIp);
+                    builder.setRouterInterfaceFixedIps(fixedIps);
                 } else {
-                    LOG.warn("removing from non-existing subnetmap node: {} ", subnetId.getValue());
+                    builder.setRouterInterfaceFixedIps(null);
                 }
+                subnetmap = builder.build();
+                LOG.debug("WithRouterFixedIPs Creating/Updating subnetMap node for Router FixedIps: {} ",
+                    subnetId.getValue());
+                SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
             }
         } catch (Exception e) {
-            LOG.error("Removal from subnetmap failed for node: {}", subnetId.getValue());
+            LOG.error("WithRouterFixedIPs: Updation of subnetMap for Router FixedIps failed for node: {}",
+                subnetId.getValue());
         }
-        return subnetmap;
     }
 
     // TODO Clean up the exception handling
@@ -323,7 +291,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                                 directPortId.getValue());
                     }
                     subnetmap = builder.build();
-                    MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
+                    SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id,
+                            subnetmap);
                 } else {
                     LOG.error("Trying to update non-existing subnetmap node {} ", subnetId.getValue());
                 }
@@ -335,6 +304,47 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         return subnetmap;
     }
 
+    // TODO Clean up the exception handling
+    @SuppressWarnings("checkstyle:IllegalCatch")
+    protected Subnetmap removeFromSubnetNode(Uuid subnetId, Uuid networkId, Uuid routerId, Uuid vpnId, Uuid portId) {
+        Subnetmap subnetmap = null;
+        InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
+                .child(Subnetmap.class, new SubnetmapKey(subnetId))
+                .build();
+        try {
+            synchronized (subnetId.getValue().intern()) {
+                Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+                if (sn.isPresent()) {
+                    SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
+                    if (routerId != null) {
+                        builder.setRouterId(null);
+                    }
+                    if (networkId != null) {
+                        builder.setNetworkId(null);
+                    }
+                    if (vpnId != null) {
+                        builder.setVpnId(null);
+                    }
+                    if (portId != null && builder.getPortList() != null) {
+                        List<Uuid> portList = builder.getPortList();
+                        portList.remove(portId);
+                        builder.setPortList(portList);
+                    }
+
+                    subnetmap = builder.build();
+                    LOG.debug("Removing from existing subnetmap node: {} ", subnetId.getValue());
+                    SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id,
+                            subnetmap);
+                } else {
+                    LOG.warn("removing from non-existing subnetmap node: {} ", subnetId.getValue());
+                }
+            }
+        } catch (Exception e) {
+            LOG.error("Removal from subnetmap failed for node: {}", subnetId.getValue());
+        }
+        return subnetmap;
+    }
+
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
     protected Subnetmap removePortsFromSubnetmapNode(Uuid subnetId, Uuid portId, Uuid directPortId) {
@@ -361,7 +371,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                                 .getValue(), subnetId.getValue());
                     }
                     subnetmap = builder.build();
-                    MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
+                    SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id,
+                            subnetmap);
                 } else {
                     LOG.error("Trying to remove port from non-existing subnetmap node {}", subnetId.getValue());
                 }
@@ -381,7 +392,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         LOG.debug("removing subnetMap node: {} ", subnetId.getValue());
         try {
             synchronized (subnetId.getValue().intern()) {
-                MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetMapIdentifier);
+                SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                        subnetMapIdentifier);
             }
         } catch (Exception e) {
             LOG.error("Delete subnetMap node failed for subnet : {} ", subnetId.getValue());
@@ -390,8 +402,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
 
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
-    private void updateVpnInstanceNode(String vpnName, List<String> rd, List<String> irt, List<String> ert) {
-
+    private void updateVpnInstanceNode(String vpnName, List<String> rd, List<String> irt, List<String> ert,
+                                       VpnInstance.Type type, long l3vni) {
         VpnInstanceBuilder builder = null;
         List<VpnTarget> vpnTargetList = new ArrayList<>();
         boolean isLockAcquired = false;
@@ -405,7 +417,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 builder = new VpnInstanceBuilder(optionalVpn.get());
                 LOG.debug("updating existing vpninstance node");
             } else {
-                builder = new VpnInstanceBuilder().setKey(new VpnInstanceKey(vpnName)).setVpnInstanceName(vpnName);
+                builder = new VpnInstanceBuilder().setKey(new VpnInstanceKey(vpnName)).setVpnInstanceName(vpnName)
+                        .setType(type).setL3vni(l3vni);
             }
             if (irt != null && !irt.isEmpty()) {
                 if (ert != null && !ert.isEmpty()) {
@@ -443,7 +456,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             Ipv4FamilyBuilder ipv4vpnBuilder = new Ipv4FamilyBuilder().setVpnTargets(vpnTargets);
 
             if (rd != null && !rd.isEmpty()) {
-                ipv4vpnBuilder.setRouteDistinguisher(rd.get(0));
+                ipv4vpnBuilder.setRouteDistinguisher(rd);
             }
 
             VpnInstance newVpn = builder.setIpv4Family(ipv4vpnBuilder.build()).build();
@@ -754,7 +767,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                                     List<String> ert, Uuid router, List<Uuid> networks) {
 
         // Update VPN Instance node
-        updateVpnInstanceNode(vpn.getValue(), rd, irt, ert);
+        updateVpnInstanceNode(vpn.getValue(), rd, irt, ert, VpnInstance.Type.L3, 0 /*l3vni*/);
 
         // Update local vpn-subnet DS
         updateVpnMaps(vpn, name, router, tenant, networks);
@@ -789,13 +802,15 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
      * @param ert A list of Export Route Targets
      * @param router UUID of the neutron router the VPN may be associated to
      * @param networks UUID of the neutron network the VPN may be associated to
+     * @param type Type of the VPN Instance
+     * @param l3vni L3VNI for the VPN Instance using VxLAN as the underlay
      * @throws Exception if association of L3VPN failed
      */
-    public void createL3Vpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt, List<String> ert,
-                            Uuid router, List<Uuid> networks) throws Exception {
+    public void createVpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt, List<String> ert,
+                            Uuid router, List<Uuid> networks, VpnInstance.Type type, long l3vni) throws Exception {
 
         // Update VPN Instance node
-        updateVpnInstanceNode(vpn.getValue(), rd, irt, ert);
+        updateVpnInstanceNode(vpn.getValue(), rd, irt, ert, type, l3vni);
 
         // Please note that router and networks will be filled into VPNMaps
         // by subsequent calls here to associateRouterToVpn and
@@ -808,7 +823,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         if (networks != null) {
             List<String> failStrings = associateNetworksToVpn(vpn, networks);
             if (failStrings != null &&  !failStrings.isEmpty()) {
-                LOG.error("L3VPN {} association to networks failed with error message {}. ",
+                LOG.error("VPN {} association to networks failed with error message {}. ",
                         vpn.getValue(), failStrings.get(0));
                 throw new Exception(failStrings.get(0));
             }
@@ -816,7 +831,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
     }
 
     /**
-     * It handles the invocations to the createL3VPN RPC method.
+     * It handles the invocations to the createVPN RPC method.
      */
     @Override
     // TODO Clean up the exception handling
@@ -831,9 +846,17 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
 
         List<L3vpn> vpns = input.getL3vpn();
         for (L3vpn vpn : vpns) {
-            List<String> existingRDs = NeutronvpnUtils.getExistingRDs(dataBroker);
             RpcError error = null;
             String msg;
+            if (NeutronvpnUtils.doesVpnExist(dataBroker, vpn.getId())) {
+                msg = String.format("Creation of L3VPN failed for VPN %s due to VPN with the same ID already present",
+                                vpn.getId().getValue());
+                LOG.warn(msg);
+                error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
+                errorList.add(error);
+                warningcount++;
+                continue;
+            }
             if (vpn.getRouteDistinguisher() == null || vpn.getImportRT() == null || vpn.getExportRT() == null) {
                 msg = String.format("Creation of L3VPN failed for VPN %s due to absence of RD/iRT/eRT input",
                         vpn.getId().getValue());
@@ -843,8 +866,14 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 warningcount++;
                 continue;
             }
+            VpnInstance.Type vpnInstanceType = VpnInstance.Type.L3;
+            long l3vni = 0;
+            if (vpn.getL3vni() != null) {
+                l3vni = vpn.getL3vni();
+            }
+
             if (vpn.getRouteDistinguisher().size() > 1) {
-                msg = String.format("Creation of L3VPN failed for VPN %s due to multiple RD input %s",
+                msg = String.format("Creation of VPN failed for VPN %s due to multiple RD input %s",
                         vpn.getId().getValue(), vpn.getRouteDistinguisher());
                 LOG.warn(msg);
                 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
@@ -852,6 +881,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 warningcount++;
                 continue;
             }
+            List<String> existingRDs = NeutronvpnUtils.getExistingRDs(dataBroker);
             if (existingRDs.contains(vpn.getRouteDistinguisher().get(0))) {
                 msg = String.format("Creation of L3VPN failed for VPN %s as another VPN with the same RD %s "
                     + "is already configured",
@@ -910,10 +940,11 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 }
             }
             try {
-                createL3Vpn(vpn.getId(), vpn.getName(), vpn.getTenantId(), vpn.getRouteDistinguisher(),
-                        vpn.getImportRT(), vpn.getExportRT(), vpn.getRouterId(), vpn.getNetworkIds());
+                createVpn(vpn.getId(), vpn.getName(), vpn.getTenantId(), vpn.getRouteDistinguisher(),
+                        vpn.getImportRT(), vpn.getExportRT(), vpn.getRouterId(), vpn.getNetworkIds(),
+                        vpnInstanceType, l3vni);
             } catch (Exception ex) {
-                msg = String.format("Creation of L3VPN failed for VPN %s", vpn.getId().getValue());
+                msg = String.format("Creation of VPN failed for VPN %s", vpn.getId().getValue());
                 LOG.error(msg, ex);
                 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
                 errorList.add(error);
@@ -996,11 +1027,9 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             for (VpnInstance vpnInstance : vpns) {
                 Uuid vpnId = new Uuid(vpnInstance.getVpnInstanceName());
                 // create VpnMaps id
-                InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap
-                        .class, new VpnMapKey(vpnId)).build();
                 L3vpnInstancesBuilder l3vpn = new L3vpnInstancesBuilder();
 
-                List<String> rd = Arrays.asList(vpnInstance.getIpv4Family().getRouteDistinguisher().split(","));
+                List<String> rd = vpnInstance.getIpv4Family().getRouteDistinguisher();
                 List<VpnTarget> vpnTargetList = vpnInstance.getIpv4Family().getVpnTargets().getVpnTarget();
 
                 List<String> ertList = new ArrayList<>();
@@ -1020,6 +1049,11 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 }
 
                 l3vpn.setId(vpnId).setRouteDistinguisher(rd).setImportRT(irtList).setExportRT(ertList);
+                if (vpnInstance.getL3vni() != null) {
+                    l3vpn.setL3vni(vpnInstance.getL3vni());
+                }
+                InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap
+                        .class, new VpnMapKey(vpnId)).build();
                 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
                         vpnMapIdentifier);
                 if (optionalVpnMap.isPresent()) {
@@ -1034,7 +1068,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             result.set(RpcResultBuilder.<GetL3VPNOutput>success().withResult(opBuilder.build()).build());
 
         } catch (Exception ex) {
-            String message = String.format("GetL3VPN failed due to %s", ex.getMessage());
+            String message = String.format("GetVPN failed due to %s", ex.getMessage());
             LOG.error(message, ex);
             result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withError(ErrorType.APPLICATION, message).build());
         }
@@ -1066,7 +1100,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
                         .CONFIGURATION, vpnIdentifier);
                 if (optionalVpn.isPresent()) {
-                    removeL3Vpn(vpn);
+                    removeVpn(vpn);
                 } else {
                     msg = String.format("VPN with vpnid: %s does not exist", vpn.getValue());
                     LOG.warn(msg);
@@ -1103,9 +1137,29 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         return result;
     }
 
+    public void createVpnInstanceForSubnet(Uuid subnetId) {
+        LOG.debug("Creating/Updating L3 internalVPN for subnetID {} ", subnetId);
+        createL3InternalVpn(subnetId, subnetId.getValue(), null, null, null, null, null, null);
+    }
+
+    public void removeVpnInstanceForSubnet(Uuid subnetId) {
+        LOG.debug("Removing vpn-instance for subnetID {} ", subnetId);
+        removeVpn(subnetId);
+    }
+
     protected void addSubnetToVpn(final Uuid vpnId, Uuid subnet) {
         LOG.debug("Adding subnet {} to vpn {}", subnet.getValue(), vpnId.getValue());
-        Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
+        Subnetmap sn = updateSubnetNode(subnet, null, vpnId);
+        if (sn == null) {
+            LOG.error("subnetmap is null, cannot add subnet {} to VPN {}", subnet.getValue(), vpnId.getValue());
+            return;
+        }
+        VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, vpnId);
+        if (vpnMap == null) {
+            LOG.error("No vpnMap for vpnId {}, cannot add subnet {} to VPN", vpnId.getValue(), subnet.getValue());
+            return;
+        }
+
         final Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
         // Check if there are ports on this subnet and add corresponding
         // vpn-interfaces
@@ -1149,7 +1203,11 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 }
             }
         }
-        sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
+        sn = updateSubnetNode(subnet, null, vpnId);
+        if (sn == null) {
+            LOG.error("subnetmap is null, cannot update VPN {} for subnet {}", vpnId.getValue(), subnet.getValue());
+            return;
+        }
         // Check for ports on this subnet and update association of
         // corresponding vpn-interfaces to external vpn
         List<Uuid> portList = sn.getPortList();
@@ -1221,11 +1279,11 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
      */
     public void addInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
                                   HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
-        for ( Routes route : interVpnLinkRoutes ) {
+        for (Routes route : interVpnLinkRoutes) {
             String nexthop = String.valueOf(route.getNexthop().getValue());
             String destination = String.valueOf(route.getDestination().getValue());
             InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
-            if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
+            if (isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink)) {
                 AddStaticRouteInput rpcInput =
                         new AddStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
                                 .setVpnInstanceName(vpnName.getValue())
@@ -1234,7 +1292,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 RpcResult<AddStaticRouteOutput> rpcResult;
                 try {
                     rpcResult = labelOuputFtr.get();
-                    if ( rpcResult.isSuccessful() ) {
+                    if (rpcResult.isSuccessful()) {
                         LOG.debug("Label generated for destination {} is: {}",
                                 destination, rpcResult.getResult().getLabel());
                     } else {
@@ -1247,7 +1305,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 );
+                        String.valueOf(route.getDestination().getValue()), nexthop);
                 continue;
             }
         }
@@ -1263,11 +1321,11 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
      */
     public void removeInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
                                      HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
-        for ( Routes route : interVpnLinkRoutes ) {
+        for (Routes route : interVpnLinkRoutes) {
             String nexthop = String.valueOf(route.getNexthop().getValue());
             String destination = String.valueOf(route.getDestination().getValue());
             InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
-            if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
+            if (isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink)) {
                 RemoveStaticRouteInput rpcInput =
                         new RemoveStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
                                 .setVpnInstanceName(vpnName.getValue())
@@ -1276,7 +1334,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 );
+                        String.valueOf(route.getDestination().getValue()), nexthop);
                 continue;
             }
         }
@@ -1289,10 +1347,10 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
     private boolean isNexthopTheOtherVpnLinkEndpoint(String nexthop, String thisVpnUuid, InterVpnLink interVpnLink) {
         return
                 interVpnLink != null
-                        && (   (interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(thisVpnUuid)
+                        && ((interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(thisVpnUuid)
                         && interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(nexthop))
-                        || (interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(thisVpnUuid )
-                        && interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(nexthop)) );
+                        || (interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(thisVpnUuid)
+                        && interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(nexthop)));
     }
 
     protected List<Adjacency> getAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList, String fixedIp) {
@@ -1443,7 +1501,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         }
     }
 
-    protected void removeL3Vpn(Uuid id) {
+    protected void removeVpn(Uuid id) {
         // read VPNMaps
         VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, id);
         Uuid router = (vpnMap != null) ? vpnMap.getRouterId() : null;
@@ -1464,7 +1522,14 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
 
     protected void removeSubnetFromVpn(final Uuid vpnId, Uuid subnet) {
         LOG.debug("Removing subnet {} from vpn {}", subnet.getValue(), vpnId.getValue());
-        final Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
+        VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, vpnId);
+        if (vpnMap == null) {
+            LOG.error("No vpnMap for vpnId {}, cannot remove subnet {} from VPN",
+                    vpnId.getValue(), subnet.getValue());
+            return;
+        }
+
+        final Uuid routerId = vpnMap.getRouterId();
         Subnetmap sn = NeutronvpnUtils.getSubnetmap(dataBroker, subnet);
         if (sn != null) {
             // Check if there are ports on this subnet; remove corresponding vpn-interfaces
@@ -1553,6 +1618,14 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             // process corresponding subnets for VPN
             for (Uuid nw : networks) {
                 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
+                NetworkProviderExtension providerExtension = network.getAugmentation(NetworkProviderExtension.class);
+                if (providerExtension.getSegments() != null && providerExtension.getSegments().size() > 1) {
+                    LOG.error("MultiSegmented networks not supported in VPN. Failed to associate network {} on vpn {}",
+                            nw.getValue(), vpn.getValue());
+                    failedNwList.add(String.format("Failed to associate network %s on vpn %s as it is multisegmented.",
+                            nw.getValue(), vpn.getValue()));
+                    continue;
+                }
                 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
                 if (network == null) {
                     failedNwList.add(String.format("network %s not found", nw.getValue()));
@@ -1925,21 +1998,12 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         return NeutronvpnUtils.getNeutronPort(dataBroker, portId);
     }
 
-    protected List<Uuid> getSubnetsforVpn(Uuid vpnid) {
-        List<Uuid> subnets = new ArrayList<>();
-        // read subnetmaps
-        InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
-        Optional<Subnetmaps> subnetmaps = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
-                subnetmapsid);
-        if (subnetmaps.isPresent() && subnetmaps.get().getSubnetmap() != null) {
-            List<Subnetmap> subnetMapList = subnetmaps.get().getSubnetmap();
-            for (Subnetmap subnetMap : subnetMapList) {
-                if (subnetMap.getVpnId() != null && subnetMap.getVpnId().equals(vpnid)) {
-                    subnets.add(subnetMap.getId());
-                }
-            }
-        }
-        return subnets;
+    protected Uuid getNetworkForSubnet(Uuid subnetId) {
+        return NeutronvpnUtils.getNetworkForSubnet(dataBroker, subnetId);
+    }
+
+    protected List<Uuid> getNetworksForVpn(Uuid vpnId) {
+        return NeutronvpnUtils.getNetworksforVpn(dataBroker, vpnId);
     }
 
     /**
@@ -2024,7 +2088,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 result.add("------------------------------------------------------------------------------------");
                 result.add("");
                 List<L3vpnInstances> vpnList = rpcResult.getResult().getL3vpnInstances();
-                for (L3vpnInstance vpn : vpnList) {
+                for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
+                            .rev150602.VpnInstance vpn : vpnList) {
                     String tenantId = vpn.getTenantId() != null ? vpn.getTenantId().getValue()
                             : "\"                 " + "                  \"";
                     result.add(String.format(" %-37s %-37s %-7s ", vpn.getId().getValue(), tenantId,
@@ -2036,7 +2101,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                     result.add("");
 
                     Uuid vpnid = vpn.getId();
-                    List<Uuid> subnetList = getSubnetsforVpn(vpnid);
+                    List<Uuid> subnetList = NeutronvpnUtils.getSubnetsforVpn(dataBroker, vpnid);
                     if (!subnetList.isEmpty()) {
                         for (Uuid subnetuuid : subnetList) {
                             result.add(String.format(" %-76s ", subnetuuid.getValue()));
@@ -2050,10 +2115,10 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 }
             } else {
                 String errortag = rpcResult.getErrors().iterator().next().getTag();
-                if (errortag == "") {
+                if (Objects.equals(errortag, "")) {
                     System.out.println("");
                     System.out.println("No VPN has been configured yet");
-                } else if (errortag == "invalid-value") {
+                } else if (Objects.equals(errortag, "invalid-value")) {
                     System.out.println("");
                     System.out.println("VPN " + vpnuuid.getValue() + " is not present");
                 } else {