Merge "Neutron port listener updated to support allowed address pair with security...
[netvirt.git] / vpnservice / neutronvpn / neutronvpn-impl / src / main / java / org / opendaylight / netvirt / neutronvpn / NeutronvpnManager.java
index ac52bcd9e7f7d950610883683005a044a0b16bcf..075d6843b7e0a9df8268178306cb4084b3fa801c 100644 (file)
@@ -21,14 +21,12 @@ import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev14081
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargetsBuilder;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets
-        .VpnTargetBuilder;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetBuilder;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetKey;
 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.VpnInstanceBuilder;
 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.instances.vpn.instance
-        .Ipv4FamilyBuilder;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance.Ipv4FamilyBuilder;
 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.VpnInterfaceBuilder;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
@@ -39,7 +37,39 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adj
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateRouterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateRouterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInput;
+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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterDisassociatedFromVpn;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterDisassociatedFromVpnBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterInterfacesMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetAddedToVpnBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetDeletedFromVpnBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetUpdatedInVpnBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfacesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfacesKey;
@@ -55,17 +85,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.por
 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.rev150712.Neutron;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.createl3vpn.input.L3vpn;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output.L3vpnInstances;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output
-        .L3vpnInstancesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output.L3vpnInstancesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
@@ -89,7 +115,7 @@ import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
-public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , EventListener{
+public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, EventListener {
 
     private static final Logger logger = LoggerFactory.getLogger(NeutronvpnManager.class);
     private final DataBroker broker;
@@ -98,6 +124,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
     IMdsalApiManager mdsalUtil;
     private NotificationPublishService notificationPublishService;
     private NotificationService notificationService;
+    private NeutronFloatingToFixedIpMappingChangeListener floatingIpMapListener;
     Boolean isExternalVpn;
 
     /**
@@ -105,12 +132,14 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
      * @param mdsalManager - MDSAL Util API access
      */
     public NeutronvpnManager(final DataBroker db, IMdsalApiManager mdsalManager,NotificationPublishService notiPublishService,
-                             NotificationService notiService, NeutronvpnNatManager vpnNatMgr) {
+                             NotificationService notiService, NeutronvpnNatManager vpnNatMgr,
+                             NeutronFloatingToFixedIpMappingChangeListener neutronFloatingToFixedIpMappingChangeListener) {
         broker = db;
         mdsalUtil = mdsalManager;
         nvpnNatManager = vpnNatMgr;
         notificationPublishService = notiPublishService;
         notificationService = notiService;
+        floatingIpMapListener = neutronFloatingToFixedIpMappingChangeListener;
     }
 
     public void setLockManager(LockManagerService lockManager) {
@@ -123,7 +152,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
     }
 
     protected Subnetmap updateSubnetNode(Uuid subnetId, String subnetIp, Uuid tenantId, Uuid networkId, Uuid routerId,
-                                         Uuid vpnId, Uuid portId) {
+                                         Uuid vpnId) {
         Subnetmap subnetmap = null;
         SubnetmapBuilder builder = null;
         boolean isLockAcquired = false;
@@ -156,15 +185,6 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
                 builder.setTenantId(tenantId);
             }
 
-            if (portId != null) {
-                List<Uuid> portList = builder.getPortList();
-                if (portList == null) {
-                    portList = new ArrayList<Uuid>();
-                }
-                portList.add(portId);
-                builder.setPortList(portList);
-            }
-
             subnetmap = builder.build();
             isLockAcquired = NeutronvpnUtils.lock(lockManager, subnetId.getValue());
             logger.debug("Creating/Updating subnetMap node: {} ", subnetId.getValue());
@@ -220,6 +240,92 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         return subnetmap;
     }
 
+    protected Subnetmap updateSubnetmapNodeWithPorts(Uuid subnetId, Uuid portId, Uuid directPortId) {
+        Subnetmap subnetmap = null;
+        boolean isLockAcquired = false;
+        InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
+                new SubnetmapKey(subnetId)).build();
+        try {
+            Optional<Subnetmap> sn = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, id);
+            if (sn.isPresent()) {
+                SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
+                if (null != portId) {
+                    List<Uuid> portList = builder.getPortList();
+                    if (null == portList) {
+                        portList = new ArrayList<Uuid>();
+                    }
+                    portList.add(portId);
+                    builder.setPortList(portList);
+                    logger.debug("Updating existing subnetmap node {} with port {}", subnetId.getValue(),
+                            portId.getValue());
+                }
+                if (null != directPortId) {
+                    List<Uuid> directPortList = builder.getDirectPortList();
+                    if (null == directPortList) {
+                        directPortList = new ArrayList<Uuid>();
+                    }
+                    directPortList.add(directPortId);
+                    builder.setDirectPortList(directPortList);
+                    logger.debug("Updating existing subnetmap node {} with port {}", subnetId.getValue(),
+                            directPortId.getValue());
+                }
+                subnetmap = builder.build();
+                isLockAcquired = NeutronvpnUtils.lock(lockManager, subnetId.getValue());
+                MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
+            } else {
+                logger.error("Trying to update non-existing subnetmap node {} ", subnetId.getValue());
+            }
+        } catch (Exception e) {
+            logger.error("Updating port list of a given subnetMap failed for node: {} with exception{}",
+                    subnetId.getValue(), e);
+        } finally {
+            if (isLockAcquired) {
+                NeutronvpnUtils.unlock(lockManager, subnetId.getValue());
+            }
+        }
+        return subnetmap;
+    }
+
+    protected Subnetmap removePortsFromSubnetmapNode(Uuid subnetId, Uuid portId, Uuid directPortId) {
+        Subnetmap subnetmap = null;
+        boolean isLockAcquired = false;
+        InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
+                new SubnetmapKey(subnetId)).build();
+        try {
+            Optional<Subnetmap> sn = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, id);
+            if (sn.isPresent()) {
+                SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
+                if (null != portId && null != builder.getPortList()) {
+                    List<Uuid> portList = builder.getPortList();
+                    portList.remove(portId);
+                    builder.setPortList(portList);
+                    logger.debug("Removing port {} from existing subnetmap node: {} ", portId.getValue(),
+                            subnetId.getValue());
+                }
+                if (null != directPortId && null != builder.getDirectPortList()) {
+                    List<Uuid> directPortList = builder.getDirectPortList();
+                    directPortList.remove(directPortId);
+                    builder.setDirectPortList(directPortList);
+                    logger.debug("Removing direct port {} from existing subnetmap node: {} ", directPortId.getValue(),
+                            subnetId.getValue());
+                }
+                subnetmap = builder.build();
+                isLockAcquired = NeutronvpnUtils.lock(lockManager, subnetId.getValue());
+                MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
+            } else {
+                logger.error("Trying to remove port from non-existing subnetmap node {}", subnetId.getValue());
+            }
+        } catch (Exception e) {
+            logger.error("Removing a port from port list of a subnetmap failed for node: {} with expection {}",
+                    subnetId.getValue(), e);
+        } finally {
+            if (isLockAcquired) {
+                NeutronvpnUtils.unlock(lockManager, subnetId.getValue());
+            }
+        }
+        return subnetmap;
+    }
+
     protected void deleteSubnetMapNode(Uuid subnetId) {
         boolean isLockAcquired = false;
         InstanceIdentifier<Subnetmap> subnetMapIdentifier = InstanceIdentifier.builder(Subnetmaps.class)
@@ -240,7 +346,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
     private void updateVpnInstanceNode(String vpnName, List<String> rd, List<String> irt, List<String> ert) {
 
         VpnInstanceBuilder builder = null;
-        List<VpnTarget> vpnTargetList = new ArrayList<VpnTarget>();
+        List<VpnTarget> vpnTargetList = new ArrayList<>();
         boolean isLockAcquired = false;
         InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class).
                 child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
@@ -256,7 +362,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
             }
             if (irt != null && !irt.isEmpty()) {
                 if (ert != null && !ert.isEmpty()) {
-                    List<String> commonRT = new ArrayList<String>(irt);
+                    List<String> commonRT = new ArrayList<>(irt);
                     commonRT.retainAll(ert);
 
                     for (String common : commonRT) {
@@ -346,7 +452,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
             if (networks != null) {
                 List<Uuid> nwList = builder.getNetworkIds();
                 if (nwList == null) {
-                    nwList = new ArrayList<Uuid>();
+                    nwList = new ArrayList<>();
                 }
                 nwList.addAll(networks);
                 builder.setNetworkIds(nwList);
@@ -446,7 +552,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
             return;
         }
         String infName = port.getUuid().getValue();
-        List<Adjacency> adjList = new ArrayList<Adjacency>();
+        List<Adjacency> adjList = new ArrayList<>();
         InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
 
         // find router associated to vpn
@@ -463,7 +569,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
             StringBuilder IpPrefixBuild = new StringBuilder(ip.getIpAddress().getIpv4Address().getValue());
             String IpPrefix = IpPrefixBuild.append("/32").toString();
             Adjacency vmAdj = new AdjacencyBuilder().setKey(new AdjacencyKey(IpPrefix)).setIpAddress(IpPrefix)
-                    .setMacAddress(port.getMacAddress()).build();
+                    .setMacAddress(port.getMacAddress().getValue()).build();
             adjList.add(vmAdj);
             // create extra route adjacency
             if (rtr != null && rtr.getRoutes() != null) {
@@ -542,6 +648,44 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         }
     }
 
+    public void createL3InternalVpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt, List<String> ert,
+                                    Uuid router, List<Uuid> networks) {
+
+        // Update VPN Instance node
+        updateVpnInstanceNode(vpn.getValue(), rd, irt, ert);
+
+        // Update local vpn-subnet DS
+        updateVpnMaps(vpn, name, router, tenant, networks);
+
+        if (router != null) {
+            Uuid existingVpn = NeutronvpnUtils.getVpnForRouter(broker, router, true);
+            if (existingVpn != null) {
+                List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, router);
+                if (routerSubnets != null) {
+                    // Update the router interfaces alone and exit
+                    for (Uuid subnetId : routerSubnets) {
+                        InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).
+                                child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
+                        Optional<Subnetmap> snMap = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, id);
+                        if (snMap.isPresent()) {
+                            Subnetmap sn = snMap.get();
+                            List<Uuid> portList = sn.getPortList();
+                            if (portList != null) {
+                                for (Uuid port : sn.getPortList()) {
+                                    addToNeutronRouterInterfacesMap(router, port.getValue());
+                                }
+                            }
+                        }
+                    }
+                }
+                logger.info("Creation of Internal L3VPN skipped for VPN {} due to router {} already associated to " +
+                        "external VPN {}", vpn.getValue(), router.getValue(), existingVpn.getValue());
+                return;
+            }
+            associateRouterToInternalVpn(vpn, router);
+        }
+    }
+
     public void createL3Vpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt, List<String> ert,
                             Uuid router, List<Uuid> networks) {
 
@@ -564,7 +708,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
 
         CreateL3VPNOutputBuilder opBuilder = new CreateL3VPNOutputBuilder();
         SettableFuture<RpcResult<CreateL3VPNOutput>> result = SettableFuture.create();
-        List<RpcError> errorList = new ArrayList<RpcError>();
+        List<RpcError> errorList = new ArrayList<>();
         int failurecount = 0;
         int warningcount = 0;
 
@@ -673,7 +817,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         GetL3VPNOutputBuilder opBuilder = new GetL3VPNOutputBuilder();
         SettableFuture<RpcResult<GetL3VPNOutput>> result = SettableFuture.create();
         Uuid inputVpnId = input.getId();
-        List<VpnInstance> vpns = new ArrayList<VpnInstance>();
+        List<VpnInstance> vpns = new ArrayList<>();
 
         try {
             if (inputVpnId == null) {
@@ -712,7 +856,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
                             .withWarning(ErrorType.PROTOCOL, "invalid-value", message).build());
                 }
             }
-            List<L3vpnInstances> l3vpnList = new ArrayList<L3vpnInstances>();
+            List<L3vpnInstances> l3vpnList = new ArrayList<>();
             for (VpnInstance vpnInstance : vpns) {
                 Uuid vpnId = new Uuid(vpnInstance.getVpnInstanceName());
                 // create VpnMaps id
@@ -723,8 +867,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
                 List<String> rd = Arrays.asList(vpnInstance.getIpv4Family().getRouteDistinguisher().split(","));
                 List<VpnTarget> vpnTargetList = vpnInstance.getIpv4Family().getVpnTargets().getVpnTarget();
 
-                List<String> ertList = new ArrayList<String>();
-                List<String> irtList = new ArrayList<String>();
+                List<String> ertList = new ArrayList<>();
+                List<String> irtList = new ArrayList<>();
 
                 for (VpnTarget vpnTarget : vpnTargetList) {
                     if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ExportExtcommunity) {
@@ -766,7 +910,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
 
         DeleteL3VPNOutputBuilder opBuilder = new DeleteL3VPNOutputBuilder();
         SettableFuture<RpcResult<DeleteL3VPNOutput>> result = SettableFuture.create();
-        List<RpcError> errorList = new ArrayList<RpcError>();
+        List<RpcError> errorList = new ArrayList<>();
 
         int failurecount = 0;
         int warningcount = 0;
@@ -820,12 +964,15 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
 
     protected void addSubnetToVpn(Uuid vpnId, Uuid subnet) {
         logger.debug("Adding subnet {} to vpn {}", subnet.getValue(), vpnId.getValue());
-        Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId, null);
+        Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
         boolean isLockAcquired = false;
         String lockName = vpnId.getValue() + subnet.getValue();
         String elanInstanceName = sn.getNetworkId().getValue();
-        InstanceIdentifier<ElanInstance>elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
-        Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
+        InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child
+                (ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
+        Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
+                elanIdentifierId);
+        //TODO: Cache it in add so can reuse it in update and delete. Best would be to cache in some ElanUtils
         long elanTag = elanInstance.get().getElanTag();
         Uuid routerId = NeutronvpnUtils.getVpnMap(broker, vpnId).getRouterId();
         if (vpnId.equals(routerId)) {
@@ -850,25 +997,31 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
             for (Uuid port : sn.getPortList()) {
                 logger.debug("adding vpn-interface for port {}", port.getValue());
                 createVpnInterface(vpnId, NeutronvpnUtils.getNeutronPort(broker, port));
+                if (routerId != null) {
+                    addToNeutronRouterInterfacesMap(routerId, port.getValue());
+                }
             }
         }
     }
 
     protected void updateVpnForSubnet(Uuid vpnId, Uuid subnet, boolean isBeingAssociated) {
         logger.debug("Updating VPN {} for subnet {}", vpnId.getValue(), subnet.getValue());
-        Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId, null);
+        Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
         boolean isLockAcquired = false;
         String lockName = vpnId.getValue() + subnet.getValue();
         String elanInstanceName = sn.getNetworkId().getValue();
-        InstanceIdentifier<ElanInstance>elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
-        Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
+        InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child
+                (ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
+        Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
+                elanIdentifierId);
         long elanTag = elanInstance.get().getElanTag();
         try {
             isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
-            checkAndPublishSubnetUpdNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isBeingAssociated, elanTag);
+            checkAndPublishSubnetUpdNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isBeingAssociated,
+                    elanTag);
             logger.debug("Subnet updated in Vpn notification sent");
-        }catch (Exception e){
-            logger.error("Subnet updated in Vpn notification failed",e);
+        } catch (Exception e) {
+            logger.error("Subnet updated in Vpn notification failed", e);
         }finally {
             if (isLockAcquired) {
                 NeutronvpnUtils.unlock(lockManager, lockName);
@@ -884,18 +1037,6 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         }
     }
 
-
-
-        // router-interfaces-map
-//    list router-interfaces {
-//        key router-id;
-//        leaf router-id { type yang:uuid; }
-//        list interfaces {
-//            key interface-id;
-//            leaf interface-id { type yang:uuid; }
-//        }
-//    }
-////}
     InstanceIdentifier<RouterInterfaces> getRouterInterfacesId(Uuid routerId) {
         return InstanceIdentifier.builder(RouterInterfacesMap.class)
                 .child(RouterInterfaces.class, new RouterInterfacesKey(routerId)).build();
@@ -932,7 +1073,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
     }
 
     protected List<Adjacency> addAdjacencyforExtraRoute(List<Routes> routeList, boolean rtrUp, String vpnifname) {
-        List<Adjacency> adjList = new ArrayList<Adjacency>();
+        List<Adjacency> adjList = new ArrayList<>();
         for (Routes route : routeList) {
             if (route != null && route.getNexthop() != null && route.getDestination() != null) {
                 boolean isLockAcquired = false;
@@ -1035,8 +1176,10 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         boolean isLockAcquired = false;
         String lockName = vpnId.getValue() + subnet.getValue();
         String elanInstanceName = sn.getNetworkId().getValue();
-        InstanceIdentifier<ElanInstance>elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
-        Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
+        InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class).child
+                (ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
+        Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
+                elanIdentifierId);
         long elanTag = elanInstance.get().getElanTag();
         Uuid routerId = NeutronvpnUtils.getVpnMap(broker, vpnId).getRouterId();
         if (vpnId.equals(routerId)) {
@@ -1076,20 +1219,34 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
 
     protected void associateRouterToVpn(Uuid vpnId, Uuid routerId) {
         updateVpnMaps(vpnId, null, routerId, null, null);
+        logger.debug("Updating association of subnets to external vpn {}", vpnId.getValue());
         List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, routerId);
-        if (!vpnId.equals(routerId)) {
-            logger.debug("Updating association of subnets to external vpn {}", vpnId.getValue());
-            if (routerSubnets != null) {
-                for (Uuid subnetId : routerSubnets) {
-                    updateVpnForSubnet(vpnId, subnetId,true);
-                }
-            }
-        } else {
-            logger.debug("Adding subnets to internal vpn {}", vpnId.getValue());
-            for (Uuid subnet : routerSubnets) {
-                addSubnetToVpn(vpnId, subnet);
+//      if (!vpnId.equals(routerId)) {
+        if (routerSubnets != null) {
+            for (Uuid subnetId : routerSubnets) {
+                updateVpnForSubnet(vpnId, subnetId, true);
             }
         }
+        try {
+            checkAndPublishRouterAssociatedtoVpnNotification(routerId, vpnId);
+            logger.debug("notification upon association of router {} to VPN {} published", routerId.getValue(),
+                    vpnId.getValue());
+        } catch (Exception e) {
+            logger.error("publishing of notification upon association of router {} to VPN {} failed : ", routerId
+                    .getValue(), vpnId.getValue(), e);
+        }
+    }
+
+    protected void dissociatefixedIPFromFloatingIP(String fixedNeutronPortName) {
+        floatingIpMapListener.dissociatefixedIPFromFloatingIP(fixedNeutronPortName);
+    }
+
+    protected void associateRouterToInternalVpn(Uuid vpnId, Uuid routerId) {
+        List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, routerId);
+        logger.debug("Adding subnets to internal vpn {}", vpnId.getValue());
+        for (Uuid subnet : routerSubnets) {
+            addSubnetToVpn(vpnId, subnet);
+        }
     }
 
     protected void dissociateRouterFromVpn(Uuid vpnId, Uuid routerId) {
@@ -1102,60 +1259,95 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
             }
         }
         clearFromVpnMaps(vpnId, routerId, null);
+        try {
+            checkAndPublishRouterDisassociatedFromVpnNotification(routerId, vpnId);
+            logger.debug("notification upon disassociation of router {} from VPN {} published", routerId.getValue(),
+                    vpnId.getValue());
+        } catch (Exception e) {
+            logger.error("publishing of notification upon disassociation of router {} from VPN {} failed : ", routerId
+                    .getValue(), vpnId.getValue(), e);
+        }
     }
 
     protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
-        List<String> failed = new ArrayList<String>();
+
+        List<String> failedNwList = new ArrayList<String>();
+        List<Uuid> passedNwList = new ArrayList<>();
         if (!networks.isEmpty()) {
-            // store in Data Base
-            updateVpnMaps(vpn, null, null, null, networks);
             // process corresponding subnets for VPN
             for (Uuid nw : networks) {
-                Network net = NeutronvpnUtils.getNeutronNetwork(broker, nw);
-                if (net == null) {
-                    failed.add(nw.getValue());
+                Network network = NeutronvpnUtils.getNeutronNetwork(broker, nw);
+                Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(broker, nw);
+                if (network == null) {
+                    failedNwList.add(String.format("network %s not found", nw.getValue()));
+                } else if (vpnId != null) {
+                    failedNwList.add(String.format("network %s already associated to another VPN %s", nw.getValue(),
+                            vpnId.getValue()));
                 } else {
                     List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(broker, nw);
-                    logger.debug("Adding network subnets...");
+                    logger.debug("Adding network subnets...{}", networkSubnets);
                     if (networkSubnets != null) {
                         for (Uuid subnet : networkSubnets) {
-                            addSubnetToVpn(vpn, subnet);
+                            // check if subnet added as router interface to some router
+                            Uuid subnetVpnId = NeutronvpnUtils.getVpnForSubnet(broker, subnet);
+                            if (subnetVpnId == null) {
+                                addSubnetToVpn(vpn, subnet);
+                                passedNwList.add(nw);
+                            } else {
+                                failedNwList.add(String.format("subnet %s already added as router interface bound to " +
+                                        "internal/external VPN %s", subnet.getValue (), subnetVpnId.getValue()));
+                            }
                         }
                     }
-                    if (net.getAugmentation(NetworkL3Extension.class).isExternal()) {
-                        nvpnNatManager.addExternalNetworkToVpn(net, vpn);
+                    if (network.getAugmentation(NetworkL3Extension.class) != null && network.getAugmentation
+                            (NetworkL3Extension.class).isExternal()) {
+                        nvpnNatManager.addExternalNetworkToVpn(network, vpn);
                     }
                 }
             }
+            updateVpnMaps(vpn, null, null, null, passedNwList);
         }
-        return failed;
+        return failedNwList;
     }
 
     protected List<String> dissociateNetworksFromVpn(Uuid vpn, List<Uuid> networks) {
-        List<String> failed = new ArrayList<String>();
+
+        List<String> failedNwList = new ArrayList<String>();
+        List<Uuid> passedNwList = new ArrayList<>();
         if (networks != null && !networks.isEmpty()) {
-            // store in Data Base
-            clearFromVpnMaps(vpn, null, networks);
             // process corresponding subnets for VPN
             for (Uuid nw : networks) {
-                Network net = NeutronvpnUtils.getNeutronNetwork(broker, nw);
-                if (net == null) {
-                    failed.add(nw.getValue());
+                Network network = NeutronvpnUtils.getNeutronNetwork(broker, nw);
+                if (network == null) {
+                    failedNwList.add(String.format("network %s not found", nw.getValue()));
                 } else {
-                    List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(broker, nw);
-                    logger.debug("Removing network subnets...");
-                    if (networkSubnets != null) {
-                        for (Uuid subnet : networkSubnets) {
-                            removeSubnetFromVpn(vpn, subnet);
+                    Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(broker, nw);
+                    if (vpn.equals(vpnId)) {
+                        List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(broker, nw);
+                        logger.debug("Removing network subnets...");
+                        if (networkSubnets != null) {
+                            for (Uuid subnet : networkSubnets) {
+                                removeSubnetFromVpn(vpn, subnet);
+                                passedNwList.add(nw);
+                            }
+                        }
+                    } else {
+                        if (vpnId == null) {
+                            failedNwList.add(String.format("input network %s not associated to any vpn yet", nw
+                                    .getValue()));
+                        } else {
+                            failedNwList.add(String.format("input network %s associated to a another vpn %s instead " +
+                                    "of the one given as input", nw.getValue(), vpnId.getValue()));
                         }
                     }
-                    if (net.getAugmentation(NetworkL3Extension.class).isExternal()) {
-                        nvpnNatManager.removeExternalNetworkFromVpn(net);
+                    if (network.getAugmentation(NetworkL3Extension.class).isExternal()) {
+                        nvpnNatManager.removeExternalNetworkFromVpn(network);
                     }
                 }
             }
+            clearFromVpnMaps(vpn, null, passedNwList);
         }
-        return failed;
+        return failedNwList;
     }
 
     @Override
@@ -1173,7 +1365,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
                 if (netIds != null && !netIds.isEmpty()) {
                     List<String> failed = associateNetworksToVpn(vpnId, netIds);
                     if (!failed.isEmpty()) {
-                        returnMsg.append("network(s) not found : ").append(failed);
+                        returnMsg.append(failed);
                     }
                 }
             } else {
@@ -1214,9 +1406,13 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
                 Router rtr = NeutronvpnUtils.getNeutronRouter(broker, routerId);
                 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(broker, vpnId);
                 if (rtr != null && vpnMap != null) {
+                    Uuid extVpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId, true);
                     if (vpnMap.getRouterId() != null) {
                         returnMsg.append("vpn ").append(vpnId.getValue()).append(" already associated to router ")
                                 .append(vpnMap.getRouterId().getValue());
+                    } else if (extVpnId != null) {
+                        returnMsg.append("router ").append(routerId.getValue()).append(" already associated to " +
+                                "another VPN ").append(extVpnId.getValue());
                     } else {
                         associateRouterToVpn(vpnId, routerId);
                     }
@@ -1261,7 +1457,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
                 if (netIds != null && !netIds.isEmpty()) {
                     List<String> failed = dissociateNetworksFromVpn(vpnId, netIds);
                     if (!failed.isEmpty()) {
-                        returnMsg.append("netowrk(s) not found : ").append(failed);
+                        returnMsg.append(failed);
                     }
                 }
             } else {
@@ -1303,7 +1499,19 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
                 if (routerId != null) {
                     Router rtr = NeutronvpnUtils.getNeutronRouter(broker, routerId);
                     if (rtr != null) {
-                        dissociateRouterFromVpn(vpnId, routerId);
+                        Uuid routerVpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId, true);
+                        if (vpnId.equals(routerVpnId)) {
+                            dissociateRouterFromVpn(vpnId, routerId);
+                        } else {
+                            if (routerVpnId == null) {
+                                returnMsg.append("input router ").append(routerId.getValue()).append(" not associated" +
+                                        " to any vpn yet");
+                            } else {
+                                returnMsg.append("input router ").append(routerId.getValue()).append(" associated to " +
+                                        "vpn ").append(routerVpnId.getValue()).append("instead of the vpn given as " +
+                                        "input");
+                            }
+                        }
                     } else {
                         returnMsg.append("router not found : ").append(routerId.getValue());
                     }
@@ -1394,19 +1602,12 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         deleteVpnInstance(routerId);
     }
 
-    protected Subnet getNeutronSubnet(Uuid subnetId) {
-        InstanceIdentifier<Subnet> inst = InstanceIdentifier.create(Neutron.class).
-                child(Subnets.class).child(Subnet.class, new SubnetKey(subnetId));
-        Optional<Subnet> sn = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, inst);
-
-        if (sn.isPresent()) {
-            return sn.get();
-        }
-        return null;
+    protected Subnet getNeutronSubnet(Uuid subnetId){
+        return NeutronvpnUtils.getNeutronSubnet(broker, subnetId);
     }
 
     protected IpAddress getNeutronSubnetGateway(Uuid subnetId) {
-        Subnet sn = getNeutronSubnet(subnetId);
+        Subnet sn = NeutronvpnUtils.getNeutronSubnet(broker, subnetId);
         if (null != sn) {
             return sn.getGatewayIp();
         }
@@ -1422,7 +1623,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
     }
 
     protected List<Uuid> getSubnetsforVpn(Uuid vpnid) {
-        List<Uuid> subnets = new ArrayList<Uuid>();
+        List<Uuid> subnets = new ArrayList<>();
         //read subnetmaps
         InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
         Optional<Subnetmaps> subnetmaps = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
@@ -1439,19 +1640,40 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
     }
 
     public List<String> showNeutronPortsCLI() {
-        List<String> result = new ArrayList<String>();
-        result.add(String.format(" %-34s  %-22s  %-22s  %-6s ", "PortName", "Mac Address", "IP Address",
-                "Prefix Length"));
-        result.add("---------------------------------------------------------------------------------------");
+        List<String> result = new ArrayList<>();
+        result.add(String.format(" %-36s  %-19s  %-13s  %-20s ", "Port ID", "Mac Address", "Prefix Length", "IP " +
+                "Address"));
+        result.add("-------------------------------------------------------------------------------------------");
         InstanceIdentifier<Ports> portidentifier = InstanceIdentifier.create(Neutron.class).child(Ports.class);
         try {
             Optional<Ports> ports = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, portidentifier);
             if (ports.isPresent() && ports.get().getPort() != null) {
-                List<Port> portList = ports.get().getPort();
-                for (Port port : portList) {
-                    result.add(String.format(" %-34s  %-22s  %-22s  %-6s ", port.getUuid().getValue(), port
-                            .getMacAddress(), port.getFixedIps().get(0).getIpAddress().getIpv4Address().getValue(),
-                            NeutronvpnUtils.getIPPrefixFromPort(broker, port)));
+                for (Port port : ports.get().getPort()) {
+                    List<FixedIps> fixedIPs = port.getFixedIps();
+                    try {
+                        if (fixedIPs != null && !fixedIPs.isEmpty()) {
+                            List<String> ipList = new ArrayList<>();
+                            for (FixedIps fixedIp : fixedIPs) {
+                                IpAddress ipAddress = fixedIp.getIpAddress();
+                                if (ipAddress.getIpv4Address() != null) {
+                                    ipList.add(ipAddress.getIpv4Address().getValue());
+                                } else {
+                                    ipList.add((ipAddress.getIpv6Address().getValue()));
+                                }
+                            }
+                            result.add(String.format(" %-36s  %-19s  %-13s  %-20s ", port.getUuid().getValue(), port
+                                    .getMacAddress().getValue(), NeutronvpnUtils.getIPPrefixFromPort(broker, port),
+                                    ipList.toString()));
+                        } else {
+                            result.add(String.format(" %-36s  %-19s  %-13s  %-20s ", port.getUuid().getValue(), port
+                                    .getMacAddress().getValue(), "Not Assigned", "Not Assigned"));
+                        }
+                    } catch (Exception e) {
+                        logger.error("Failed to retrieve neutronPorts info for port {}: ", port.getUuid().getValue(),
+                                e);
+                        System.out.println("Failed to retrieve neutronPorts info for port: " + port.getUuid()
+                                .getValue() + ": " + e.getMessage());
+                    }
                 }
             }
         } catch (Exception e) {
@@ -1462,7 +1684,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
     }
 
     public List<String> showVpnConfigCLI(Uuid vpnuuid) {
-        List<String> result = new ArrayList<String>();
+        List<String> result = new ArrayList<>();
         if (vpnuuid == null) {
             System.out.println("");
             System.out.println("Displaying VPN config for all VPNs");
@@ -1534,7 +1756,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         return help.toString();
     }
 
-    private void checkAndPublishSubnetAddNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
+    private void checkAndPublishSubnetAddNotification(Uuid subnetId, String subnetIp, String vpnName,
+                                                      Boolean isExternalvpn, Long elanTag)throws InterruptedException {
         SubnetAddedToVpnBuilder builder = new SubnetAddedToVpnBuilder();
 
         logger.info("publish notification called");
@@ -1548,7 +1771,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         notificationPublishService.putNotification(builder.build());
     }
 
-    private void checkAndPublishSubnetDelNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
+    private void checkAndPublishSubnetDelNotification(Uuid subnetId, String subnetIp, String vpnName,
+                                                      Boolean isExternalvpn, Long elanTag) throws InterruptedException {
         SubnetDeletedFromVpnBuilder builder = new SubnetDeletedFromVpnBuilder();
 
         logger.info("publish notification called");
@@ -1562,7 +1786,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         notificationPublishService.putNotification(builder.build());
     }
 
-    private void checkAndPublishSubnetUpdNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
+    private void checkAndPublishSubnetUpdNotification(Uuid subnetId, String subnetIp, String vpnName,
+                                                      Boolean isExternalvpn, Long elanTag) throws InterruptedException {
         SubnetUpdatedInVpnBuilder builder = new SubnetUpdatedInVpnBuilder();
 
         logger.info("publish notification called");
@@ -1576,4 +1801,19 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , Eve
         notificationPublishService.putNotification(builder.build());
     }
 
+    private void checkAndPublishRouterAssociatedtoVpnNotification(Uuid routerId, Uuid vpnId) throws
+            InterruptedException {
+        RouterAssociatedToVpn routerAssociatedToVpn = new RouterAssociatedToVpnBuilder().setRouterId(routerId)
+                .setVpnId(vpnId).build();
+        logger.info("publishing notification upon association of router to VPN");
+        notificationPublishService.putNotification(routerAssociatedToVpn);
+    }
+
+    private void checkAndPublishRouterDisassociatedFromVpnNotification(Uuid routerId, Uuid vpnId) throws
+            InterruptedException {
+        RouterDisassociatedFromVpn routerDisassociatedFromVpn = new RouterDisassociatedFromVpnBuilder().setRouterId
+                (routerId).setVpnId(vpnId).build();
+        logger.info("publishing notification upon disassociation of router from VPN");
+        notificationPublishService.putNotification(routerDisassociatedFromVpn);
+    }
 }