Upgrade ietf-{inet,yang}-types to 2013-07-15
[vpnservice.git] / neutronvpn / neutronvpn-impl / src / main / java / org / opendaylight / vpnservice / neutronvpn / NeutronvpnManager.java
index a04c7ec6040460b08523e2c2631f8f1cbc4da0b7..72c4a08c30a30e3958539417e1161bd85723603b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -7,11 +7,11 @@
  */
 package org.opendaylight.vpnservice.neutronvpn;
 
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.l3.attributes.Routes;
-
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.SettableFuture;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.controller.md.sal.binding.api.NotificationService;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
@@ -31,45 +31,36 @@ 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.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;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.AdjacenciesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.Adjacency;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.RouterInterfacesMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.router.interfaces.map.RouterInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.router.interfaces.map.RouterInterfacesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.router.interfaces.map.RouterInterfacesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.router.interfaces.map.router.interfaces.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.router.interfaces.map.router.interfaces.InterfacesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.router.interfaces.map.router.interfaces.InterfacesKey;
+
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.l3.attributes.Routes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
 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.ports.rev150712.ports.attributes.ports.PortKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInstances;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.LockManagerService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.AssociateNetworksInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.AssociateNetworksOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.AssociateNetworksOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.AssociateRouterInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.CreateL3VPNInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.CreateL3VPNOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.CreateL3VPNOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.DeleteL3VPNInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.DeleteL3VPNOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.DeleteL3VPNOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.DissociateNetworksInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.DissociateNetworksOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.DissociateNetworksOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.DissociateRouterInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.GetL3VPNInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.GetL3VPNInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.GetL3VPNOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.GetL3VPNOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.L3vpnInstance;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NeutronvpnService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.Subnetmaps;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.VpnMaps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.createl3vpn.input.L3vpn;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.getl3vpn.output.L3vpnInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.getl3vpn.output
@@ -81,10 +72,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev15
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMapBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMapKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import java.util.EventListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import java.util.ArrayList;
@@ -93,20 +86,26 @@ import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
-public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
+public class NeutronvpnManager implements NeutronvpnService, AutoCloseable , EventListener{
 
     private static final Logger logger = LoggerFactory.getLogger(NeutronvpnManager.class);
     private final DataBroker broker;
     private LockManagerService lockManager;
     IMdsalApiManager mdsalUtil;
+    private NotificationPublishService notificationPublishService;
+    private NotificationService notificationService;
+    Boolean isExternalVpn;
 
     /**
      * @param db           - dataBroker reference
      * @param mdsalManager - MDSAL Util API access
      */
-    public NeutronvpnManager(final DataBroker db, IMdsalApiManager mdsalManager) {
+    public NeutronvpnManager(final DataBroker db, IMdsalApiManager mdsalManager,NotificationPublishService notiPublishService,
+                             NotificationService notiService) {
         broker = db;
         mdsalUtil = mdsalManager;
+        notificationPublishService = notiPublishService;
+        notificationService = notiService;
     }
 
     public void setLockManager(LockManagerService lockManager) {
@@ -118,8 +117,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         logger.info("Neutron VPN Manager Closed");
     }
 
-    protected Subnetmap updateSubnetNode(Uuid subnetId, Uuid tenantId, Uuid networkId, Uuid routerId, Uuid vpnId,
-                                         Uuid portId) {
+    protected Subnetmap updateSubnetNode(Uuid subnetId, String subnetIp, Uuid tenantId, Uuid networkId, Uuid routerId,
+                                         Uuid vpnId, Uuid portId) {
         Subnetmap subnetmap = null;
         SubnetmapBuilder builder = null;
         boolean isLockAcquired = false;
@@ -136,6 +135,9 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
                 logger.debug("updating Subnet :new: ");
             }
 
+            if (subnetIp != null) {
+                builder.setSubnetIp(subnetIp);
+            }
             if (routerId != null) {
                 builder.setRouterId(routerId);
             }
@@ -213,6 +215,23 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         return subnetmap;
     }
 
+    protected void deleteSubnetMapNode(Uuid subnetId) {
+        boolean isLockAcquired = false;
+        InstanceIdentifier<Subnetmap> subnetMapIdentifier = InstanceIdentifier.builder(Subnetmaps.class)
+                .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
+        logger.debug("removing subnetMap node: {} ", subnetId.getValue());
+        try {
+            isLockAcquired = NeutronvpnUtils.lock(lockManager, subnetId.getValue());
+            MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, subnetMapIdentifier);
+        } catch (Exception e) {
+            logger.error("Delete subnetMap node failed for subnet : {} ", subnetId.getValue());
+        } finally {
+            if (isLockAcquired) {
+                NeutronvpnUtils.unlock(lockManager, subnetId.getValue());
+            }
+        }
+    }
+
     private void updateVpnInstanceNode(String vpnName, List<String> rd, List<String> irt, List<String> ert) {
 
         VpnInstanceBuilder builder = null;
@@ -421,10 +440,10 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         if (vpnId == null || port == null) {
             return;
         }
-        String portname = NeutronvpnUtils.uuidToTapPortName(port.getUuid());
+        String infName = port.getUuid().getValue();
         List<Adjacency> adjList = new ArrayList<Adjacency>();
-        InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
-                child(VpnInterface.class, new VpnInterfaceKey(portname)).build();
+        InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
+
         // find router associated to vpn
         Uuid routerId = NeutronvpnUtils.getRouterforVpn(broker, vpnId);
         Router rtr = null;
@@ -439,12 +458,12 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
             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) {
                 List<Routes> routeList = rtr.getRoutes();
-                List<Adjacency> erAdjList = addAdjacencyforExtraRoute(routeList, false, portname);
+                List<Adjacency> erAdjList = addAdjacencyforExtraRoute(routeList, false, infName);
                 if (erAdjList != null && !erAdjList.isEmpty()) {
                     adjList.addAll(erAdjList);
                 }
@@ -452,19 +471,19 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         }
         // create vpn-interface on this neutron port
         Adjacencies adjs = new AdjacenciesBuilder().setAdjacency(adjList).build();
-        VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(portname)).
-                setName(portname).setVpnInstanceName(vpnId.getValue()).addAugmentation(Adjacencies.class, adjs);
+        VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName)).
+                setName(infName).setVpnInstanceName(vpnId.getValue()).addAugmentation(Adjacencies.class, adjs);
         VpnInterface vpnIf = vpnb.build();
 
         try {
-            isLockAcquired = NeutronvpnUtils.lock(lockManager, portname);
+            isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
             logger.debug("Creating vpn interface {}", vpnIf);
             MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
         } catch (Exception ex) {
-            logger.error("Creation of vpninterface {} failed due to {}", portname, ex);
+            logger.error("Creation of vpninterface {} failed due to {}", infName, ex);
         } finally {
             if (isLockAcquired) {
-                NeutronvpnUtils.unlock(lockManager, portname);
+                NeutronvpnUtils.unlock(lockManager, infName);
             }
         }
     }
@@ -473,23 +492,51 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
 
         if (port != null) {
             boolean isLockAcquired = false;
-            String pname = NeutronvpnUtils.uuidToTapPortName(port.getUuid());
-            InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
-                    child(VpnInterface.class, new VpnInterfaceKey(pname)).build();
+            String infName = port.getUuid().getValue();
+            InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
+
             try {
-                isLockAcquired = NeutronvpnUtils.lock(lockManager, pname);
-                logger.debug("Deleting vpn interface {}", pname);
+                isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
+                logger.debug("Deleting vpn interface {}", infName);
                 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
             } catch (Exception ex) {
-                logger.error("Deletion of vpninterface {} failed due to {}", pname, ex);
+                logger.error("Deletion of vpninterface {} failed due to {}", infName, ex);
             } finally {
                 if (isLockAcquired) {
-                    NeutronvpnUtils.unlock(lockManager, pname);
+                    NeutronvpnUtils.unlock(lockManager, infName);
                 }
             }
         }
     }
 
+    protected void updateVpnInterface(Uuid vpnId, Port port) {
+        if (vpnId == null || port == null) {
+            return;
+        }
+        boolean isLockAcquired = false;
+        String infName = port.getUuid().getValue();
+        InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
+        try {
+            Optional<VpnInterface> optionalVpnInterface = NeutronvpnUtils.read(broker, LogicalDatastoreType
+                    .CONFIGURATION, vpnIfIdentifier);
+            if (optionalVpnInterface.isPresent()) {
+                VpnInterfaceBuilder vpnIfBuilder = new VpnInterfaceBuilder(optionalVpnInterface.get());
+                VpnInterface vpnIf = vpnIfBuilder.setVpnInstanceName(vpnId.getValue()).build();
+                isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
+                logger.debug("Updating vpn interface {}", vpnIf);
+                MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
+            } else {
+                logger.error("VPN Interface {} not found", infName);
+            }
+        } catch (Exception ex) {
+            logger.error("Updation of vpninterface {} failed due to {}", infName, ex);
+        } finally {
+            if (isLockAcquired) {
+                NeutronvpnUtils.unlock(lockManager, infName);
+            }
+        }
+    }
+
     public void createL3Vpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt, List<String> ert,
                             Uuid router, List<Uuid> networks) {
 
@@ -518,7 +565,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
 
         List<L3vpn> vpns = input.getL3vpn();
         for (L3vpn vpn : vpns) {
-            RpcError error;
+            RpcError error = null;
             String msg;
             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",
@@ -538,12 +585,57 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
                 warningcount++;
                 continue;
             }
+            if (vpn.getRouterId() != null) {
+                if (NeutronvpnUtils.getNeutronRouter(broker, vpn.getRouterId()) == null) {
+                    msg = String.format("Creation of L3VPN failed for VPN %s due to router not found %s",
+                            vpn.getId().getValue(), vpn.getRouterId().getValue());
+                    logger.warn(msg);
+                    error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
+                    errorList.add(error);
+                    warningcount++;
+                    continue;
+                }
+                Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, vpn.getRouterId(), true);
+                if (vpnId != null) {
+                    msg = String.format("Creation of L3VPN failed for VPN %s due to router %s already associated to " +
+                            "another VPN %s", vpn.getId().getValue(), vpn.getRouterId().getValue(), vpnId.getValue());
+                    logger.warn(msg);
+                    error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
+                    errorList.add(error);
+                    warningcount++;
+                    continue;
+                }
+            }
+            if (vpn.getNetworkIds() != null) {
+                for (Uuid nw : vpn.getNetworkIds()) {
+                    Network network = NeutronvpnUtils.getNeutronNetwork(broker, nw);
+                    Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(broker, nw);
+                    if (network == null) {
+                        msg = String.format("Creation of L3VPN failed for VPN %s due to network not found %s",
+                                vpn.getId().getValue(), nw.getValue());
+                        logger.warn(msg);
+                        error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
+                        errorList.add(error);
+                        warningcount++;
+                    } else if (vpnId != null) {
+                        msg = String.format("Creation of L3VPN failed for VPN %s due to network %s already associated" +
+                                " to another VPN %s", vpn.getId().getValue(), nw.getValue(), vpnId.getValue());
+                        logger.warn(msg);
+                        error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
+                        errorList.add(error);
+                        warningcount++;
+                    }
+                }
+                if (error != null) {
+                    continue;
+                }
+            }
             try {
                 createL3Vpn(vpn.getId(), vpn.getName(), vpn.getTenantId(), vpn.getRouteDistinguisher(),
                         vpn.getImportRT(), vpn.getExportRT(), vpn.getRouterId(), vpn.getNetworkIds());
             } catch (Exception ex) {
                 msg = String.format("Creation of L3VPN failed for VPN %s", vpn.getId().getValue());
-                logger.error(msg, ex.getMessage());
+                logger.error(msg, ex);
                 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
                 errorList.add(error);
                 failurecount++;
@@ -585,9 +677,12 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
                         InstanceIdentifier.builder(VpnInstances.class).build();
                 Optional<VpnInstances> optionalVpns = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
                         vpnsIdentifier);
-                if (optionalVpns.isPresent()) {
+                if (optionalVpns.isPresent() && optionalVpns.get().getVpnInstance() != null) {
                     for (VpnInstance vpn : optionalVpns.get().getVpnInstance()) {
-                        vpns.add(vpn);
+                        // eliminating internal VPNs from getL3VPN output
+                        if (vpn.getIpv4Family().getRouteDistinguisher() != null) {
+                            vpns.add(vpn);
+                        }
                     }
                 } else {
                     // No VPN present
@@ -616,9 +711,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
             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();
+                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(","));
@@ -656,10 +750,9 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
 
         } catch (Exception ex) {
             String message = String.format("GetL3VPN failed due to %s", ex.getMessage());
-            logger.error(message);
+            logger.error(message, ex);
             result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withError(ErrorType.APPLICATION, message).build());
         }
-
         return result;
     }
 
@@ -693,7 +786,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
                 }
             } catch (Exception ex) {
                 msg = String.format("Deletion of L3VPN failed when deleting for uuid %s", vpn.getValue());
-                logger.error(msg, ex.getMessage());
+                logger.error(msg, ex);
                 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
                 errorList.add(error);
                 failurecount++;
@@ -722,13 +815,113 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
 
     protected void addSubnetToVpn(Uuid vpnId, Uuid subnet) {
         logger.debug("Adding subnet {} to vpn {}", subnet.getValue(), vpnId.getValue());
-        Subnetmap sn = updateSubnetNode(subnet, null, null, null, vpnId, null);
+        Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId, null);
+        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);
+        long elanTag = elanInstance.get().getElanTag();
+        Uuid routerId = NeutronvpnUtils.getVpnMap(broker, vpnId).getRouterId();
+        if (vpnId.equals(routerId)) {
+            isExternalVpn = false;
+        } else {
+            isExternalVpn = true;
+        }
+        try {
+            isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
+            checkAndPublishSubnetAddNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isExternalVpn, elanTag);
+            logger.debug("Subnet added to Vpn notification sent");
+        }catch (Exception e){
+            logger.error("Subnet added to Vpn notification failed",e);
+        }finally {
+            if (isLockAcquired) {
+                NeutronvpnUtils.unlock(lockManager, lockName);
+            }
+        }
         // Check if there are ports on this subnet and add corresponding vpn-interfaces
         List<Uuid> portList = sn.getPortList();
         if (portList != null) {
             for (Uuid port : sn.getPortList()) {
                 logger.debug("adding vpn-interface for port {}", port.getValue());
-                createVpnInterface(vpnId, getNeutronPort(port));
+                createVpnInterface(vpnId, NeutronvpnUtils.getNeutronPort(broker, port));
+            }
+        }
+    }
+
+    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);
+        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);
+        long elanTag = elanInstance.get().getElanTag();
+        try {
+            isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
+            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);
+        }finally {
+            if (isLockAcquired) {
+                NeutronvpnUtils.unlock(lockManager, lockName);
+            }
+        }
+        // Check for ports on this subnet and update association of corresponding vpn-interfaces to external vpn
+        List<Uuid> portList = sn.getPortList();
+        if (portList != null) {
+            for (Uuid port : sn.getPortList()) {
+                logger.debug("Updating vpn-interface for port {}", port.getValue());
+                updateVpnInterface(vpnId, NeutronvpnUtils.getNeutronPort(broker, port));
+            }
+        }
+    }
+
+
+
+        // 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();
+    }
+    void addToNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
+        InstanceIdentifier<RouterInterfaces> routerInterfacesId =  getRouterInterfacesId(routerId);
+        Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
+        Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName)).setInterfaceId(interfaceName).build();
+        if(optRouterInterfaces.isPresent()) {
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces.class, new InterfacesKey(interfaceName)), routerInterface);
+        } else {
+            RouterInterfacesBuilder builder = new RouterInterfacesBuilder().setRouterId(routerId);
+            List<Interfaces> interfaces = new ArrayList<>();
+            interfaces.add(routerInterface);
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId, builder.setInterfaces(interfaces).build());
+        }
+    }
+    
+    void removeFromNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
+        InstanceIdentifier<RouterInterfaces> routerInterfacesId =  getRouterInterfacesId(routerId);
+        Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
+        Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName)).setInterfaceId(interfaceName).build();
+        if(optRouterInterfaces.isPresent()) {
+            RouterInterfaces routerInterfaces = optRouterInterfaces.get();
+            List<Interfaces> interfaces = routerInterfaces.getInterfaces();
+            if(interfaces != null && interfaces.remove(routerInterface)) {
+                if(interfaces.isEmpty()) {
+                    MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
+                } else {
+                    MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces.class, new InterfacesKey(interfaceName)));
+                }
             }
         }
     }
@@ -741,38 +934,38 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
                 String nextHop = String.valueOf(route.getNexthop().getValue());
                 String destination = String.valueOf(route.getDestination().getValue());
 
-                String tapPortName = NeutronvpnUtils.getNeutronPortNamefromPortFixedIp(broker, nextHop);
-                logger.trace("Adding extra route with nexthop {}, destination {}, ifName {}", nextHop,
-                        destination, tapPortName);
+                String infName = NeutronvpnUtils.getNeutronPortNamefromPortFixedIp(broker, nextHop);
+                logger.trace("Adding extra route with nexthop {}, destination {}, infName {}", nextHop,
+                        destination, infName);
                 Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination).setNextHopIp(nextHop).setKey
                         (new AdjacencyKey(destination)).build();
                 if (rtrUp == false) {
-                    if (tapPortName.equals(vpnifname)) {
+                    if (infName.equals(vpnifname)) {
                         adjList.add(erAdj);
                     }
                     continue;
                 }
                 InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
-                        child(VpnInterface.class, new VpnInterfaceKey(tapPortName)).build();
+                        child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
                 try {
                     Optional<VpnInterface> optionalVpnInterface = NeutronvpnUtils.read(broker, LogicalDatastoreType
                             .CONFIGURATION, vpnIfIdentifier);
                     if (optionalVpnInterface.isPresent()) {
                         Adjacencies erAdjs = new AdjacenciesBuilder().setAdjacency(Arrays.asList(erAdj)).build();
-                        VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(tapPortName))
+                        VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
                                 .addAugmentation(Adjacencies.class, erAdjs).build();
-                        isLockAcquired = NeutronvpnUtils.lock(lockManager, vpnifname);
+                        isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
                         logger.debug("Adding extra route {}", route);
                         MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
                     } else {
                         logger.error("VM adjacency for interface {} not present ; cannot add extra route adjacency",
-                                tapPortName);
+                                infName);
                     }
                 } catch (Exception e) {
                     logger.error("exception in adding extra route: {}" + e);
                 } finally {
                     if (isLockAcquired) {
-                        NeutronvpnUtils.unlock(lockManager, vpnifname);
+                        NeutronvpnUtils.unlock(lockManager, infName);
                     }
                 }
             } else {
@@ -789,21 +982,21 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
                 String nextHop = String.valueOf(route.getNexthop().getValue());
                 String destination = String.valueOf(route.getDestination().getValue());
 
-                String tapPortName = NeutronvpnUtils.getNeutronPortNamefromPortFixedIp(broker, nextHop);
-                logger.trace("Removing extra route with nexthop {}, destination {}, ifName {}", nextHop,
-                        destination, tapPortName);
+                String infName = NeutronvpnUtils.getNeutronPortNamefromPortFixedIp(broker, nextHop);
+                logger.trace("Removing extra route with nexthop {}, destination {}, infName {}", nextHop,
+                        destination, infName);
                 InstanceIdentifier<Adjacency> adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
-                        child(VpnInterface.class, new VpnInterfaceKey(tapPortName)).augmentation(Adjacencies.class)
+                        child(VpnInterface.class, new VpnInterfaceKey(infName)).augmentation(Adjacencies.class)
                         .child(Adjacency.class, new AdjacencyKey(destination)).build();
                 try {
-                    isLockAcquired = NeutronvpnUtils.lock(lockManager, tapPortName);
+                    isLockAcquired = NeutronvpnUtils.lock(lockManager, infName);
                     MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
                     logger.trace("extra route {} deleted successfully", route);
                 } catch (Exception e) {
                     logger.error("exception in deleting extra route: {}" + e);
                 } finally {
                     if (isLockAcquired) {
-                        NeutronvpnUtils.unlock(lockManager, tapPortName);
+                        NeutronvpnUtils.unlock(lockManager, infName);
                     }
                 }
             } else {
@@ -812,11 +1005,6 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         }
     }
 
-    protected void addPortToVpn(Uuid vpnId, Uuid port) {
-        logger.debug("Adding Port to vpn node...");
-        createVpnInterface(vpnId, getNeutronPort(port));
-    }
-
     protected void removeL3Vpn(Uuid id) {
         // read VPNMaps
         VpnMap vpnMap = NeutronvpnUtils.getVpnMap(broker, id);
@@ -836,21 +1024,42 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         deleteVpnInstance(id);
     }
 
-    protected void removePortFromVpn(Uuid vpnId, Uuid port) {
-        logger.debug("Removing Port from vpn node...");
-        deleteVpnInterface(getNeutronPort(port));
-    }
-
     protected void removeSubnetFromVpn(Uuid vpnId, Uuid subnet) {
         logger.debug("Removing subnet {} from vpn {}", subnet.getValue(), vpnId.getValue());
         Subnetmap sn = NeutronvpnUtils.getSubnetmap(broker, subnet);
+        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);
+        long elanTag = elanInstance.get().getElanTag();
+        Uuid routerId = NeutronvpnUtils.getVpnMap(broker, vpnId).getRouterId();
+        if (vpnId.equals(routerId)) {
+            isExternalVpn = false;
+        } else {
+            isExternalVpn = true;
+        }
+        try {
+            isLockAcquired = NeutronvpnUtils.lock(lockManager, lockName);
+            checkAndPublishSubnetDelNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isExternalVpn, elanTag);
+            logger.debug("Subnet removed from Vpn notification sent");
+        }catch (Exception e){
+            logger.error("Subnet removed from Vpn notification failed",e);
+        }finally {
+            if (isLockAcquired) {
+                NeutronvpnUtils.unlock(lockManager, lockName);
+            }
+        }
         if (sn != null) {
             // Check if there are ports on this subnet; remove corresponding vpn-interfaces
             List<Uuid> portList = sn.getPortList();
             if (portList != null) {
                 for (Uuid port : sn.getPortList()) {
                     logger.debug("removing vpn-interface for port {}", port.getValue());
-                    deleteVpnInterface(getNeutronPort(port));
+                    deleteVpnInterface(NeutronvpnUtils.getNeutronPort(broker, port));
+                    if (routerId != null) {
+                        removeFromNeutronRouterInterfacesMap(routerId, port.getValue());
+                    }
                 }
             }
             // update subnet-vpn association
@@ -861,36 +1070,30 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
     }
 
     protected void associateRouterToVpn(Uuid vpnId, Uuid routerId) {
-
+        updateVpnMaps(vpnId, null, routerId, null, null);
         List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, routerId);
-
         if (!vpnId.equals(routerId)) {
-            logger.debug("Removing subnets from internal vpn {}", routerId.getValue());
+            logger.debug("Updating association of subnets to external vpn {}", vpnId.getValue());
             if (routerSubnets != null) {
-                for (Uuid subnet : routerSubnets) {
-                    removeSubnetFromVpn(routerId, subnet);
+                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);
+            }
         }
-        logger.debug("Adding subnets to vpn {}", vpnId.getValue());
-        for (Uuid subnet : routerSubnets) {
-            addSubnetToVpn(vpnId, subnet);
-        }
-
-        updateVpnMaps(vpnId, null, routerId, null, null);
     }
 
     protected void dissociateRouterFromVpn(Uuid vpnId, Uuid routerId) {
 
-        // remove existing external vpn interfaces
         List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, routerId);
-
         if (routerSubnets != null) {
-            for (Uuid subnet : routerSubnets) {
-                logger.debug("Removing subnets from external vpn {}", vpnId.getValue());
-                removeSubnetFromVpn(vpnId, subnet);
-                logger.debug("Adding subnets to internal vpn {}", routerId.getValue());
-                addSubnetToVpn(routerId, subnet);
+            for (Uuid subnetId : routerSubnets) {
+                logger.debug("Updating association of subnets to internal vpn {}", routerId.getValue());
+                updateVpnForSubnet(routerId, subnetId,false);
             }
         }
         clearFromVpnMaps(vpnId, routerId, null);
@@ -977,7 +1180,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         } catch (Exception ex) {
             String message = String.format("associate Networks to vpn %s failed due to %s", input.getVpnId().getValue(),
                     ex.getMessage());
-            logger.error(message);
+            logger.error(message, ex);
             result.set(RpcResultBuilder.<AssociateNetworksOutput>failed().withError(ErrorType.APPLICATION, message)
                     .build());
         }
@@ -1022,7 +1225,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         } catch (Exception ex) {
             String message = String.format("associate router %s to vpn %s failed due to %s", routerId.getValue(),
                     vpnId.getValue(), ex.getMessage());
-            logger.error(message);
+            logger.error(message, ex);
             result.set(RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION, message).build());
         }
         logger.debug("associateRouter returns..");
@@ -1052,7 +1255,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
                 returnMsg.append("VPN not found : ").append(vpnId.getValue());
             }
             if (returnMsg.length() != 0) {
-                String message = String.format("disssociate Networks to vpn %s failed due to %s", vpnId.getValue(),
+                String message = String.format("dissociate Networks to vpn %s failed due to %s", vpnId.getValue(),
                         returnMsg);
                 logger.error(message);
                 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: " +
@@ -1065,7 +1268,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         } catch (Exception ex) {
             String message = String.format("dissociate Networks to vpn %s failed due to %s", input.getVpnId().
                     getValue(), ex.getMessage());
-            logger.error(message);
+            logger.error(message, ex);
             result.set(RpcResultBuilder.<DissociateNetworksOutput>failed().withError(ErrorType.APPLICATION, message)
                     .build());
         }
@@ -1096,7 +1299,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
                 returnMsg.append("VPN not found : ").append(vpnId.getValue());
             }
             if (returnMsg.length() != 0) {
-                String message = String.format("disssociate router %s to vpn %s failed due to %s", routerId.getValue(),
+                String message = String.format("dissociate router %s to vpn %s failed due to %s", routerId.getValue(),
                         vpnId.getValue(), returnMsg);
                 logger.error(message);
                 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: " +
@@ -1109,7 +1312,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         } catch (Exception ex) {
             String message = String.format("disssociate router %s to vpn %s failed due to %s", routerId.getValue(),
                     vpnId.getValue(), ex.getMessage());
-            logger.error(message);
+            logger.error(message, ex);
             result.set(RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION, message).build());
         }
         logger.debug("dissociateRouter returns..");
@@ -1117,6 +1320,45 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         return result;
     }
 
+    @Override
+    public Future<RpcResult<GetFixedIPsForNeutronPortOutput>> getFixedIPsForNeutronPort(GetFixedIPsForNeutronPortInput
+                                                                                                input) {
+        GetFixedIPsForNeutronPortOutputBuilder opBuilder = new GetFixedIPsForNeutronPortOutputBuilder();
+        SettableFuture<RpcResult<GetFixedIPsForNeutronPortOutput>> result = SettableFuture.create();
+        Uuid portId = input.getPortId();
+        StringBuilder returnMsg = new StringBuilder();
+        try {
+            List<String> fixedIPList = new ArrayList<>();
+            Port port = NeutronvpnUtils.getNeutronPort(broker, portId);
+            if (port != null) {
+                List<FixedIps> fixedIPs = port.getFixedIps();
+                for (FixedIps ip : fixedIPs) {
+                    fixedIPList.add(ip.getIpAddress().getIpv4Address().getValue());
+                }
+            } else {
+                returnMsg.append("neutron port: ").append(portId.getValue()).append(" not found");
+            }
+            if (returnMsg.length() != 0) {
+                String message = String.format("Retrieval of FixedIPList for neutron port failed due to %s", returnMsg);
+                logger.error(message);
+                result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>failed().withWarning(ErrorType.PROTOCOL,
+                        "invalid-value", message).build());
+            } else {
+                opBuilder.setFixedIPs(fixedIPList);
+                result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>success().withResult(opBuilder.build())
+                        .build());
+                result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>success().build());
+            }
+        } catch (Exception ex) {
+            String message = String.format("Retrieval of FixedIPList for neutron port %s failed due to %s", portId
+                    .getValue(), ex.getMessage());
+            logger.error(message, ex);
+            result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>failed().withError(ErrorType.APPLICATION,
+                    message).build());
+        }
+        return result;
+    }
+
     protected void handleNeutronRouterDeleted(Uuid routerId, List<Uuid> routerSubnetIds) {
         // check if the router is associated to some VPN
         Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId, true);
@@ -1159,28 +1401,11 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
     }
 
     protected Port getNeutronPort(String name) {
-        Uuid portId = NeutronvpnUtils.getNeutronPortIdfromPortName(broker, name);
-        if (portId != null) {
-            InstanceIdentifier<Port> pid = InstanceIdentifier.create(Neutron.class).
-                    child(Ports.class).child(Port.class, new PortKey(portId));
-            Optional<Port> optPort = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, pid);
-            if (optPort.isPresent()) {
-                return optPort.get();
-            }
-        } else {
-            logger.error("Port {} not Found!!", name);
-        }
-        return null;
+        return NeutronvpnUtils.getNeutronPort(broker, new Uuid(name));
     }
 
     protected Port getNeutronPort(Uuid portId) {
-        InstanceIdentifier<Port> pid = InstanceIdentifier.create(Neutron.class).
-                child(Ports.class).child(Port.class, new PortKey(portId));
-        Optional<Port> optPort = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, pid);
-        if (optPort.isPresent()) {
-            return optPort.get();
-        }
-        return null;
+        return NeutronvpnUtils.getNeutronPort(broker, portId);
     }
 
     protected List<Uuid> getSubnetsforVpn(Uuid vpnid) {
@@ -1189,9 +1414,8 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
         Optional<Subnetmaps> subnetmaps = NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
                 subnetmapsid);
-        if (subnetmaps.isPresent()) {
-            Subnetmaps smaps = subnetmaps.get();
-            List<Subnetmap> subnetMapList = smaps.getSubnetmap();
+        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());
@@ -1203,18 +1427,18 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
 
     public List<String> showNeutronPortsCLI() {
         List<String> result = new ArrayList<String>();
-        result.add(String.format(" %-22s  %-22s  %-22s  %-6s ", "PortName", "Mac Address", "IP Address",
+        result.add(String.format(" %-34s  %-22s  %-22s  %-6s ", "PortName", "Mac Address", "IP Address",
                 "Prefix Length"));
         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()) {
+            if (ports.isPresent() && ports.get().getPort() != null) {
                 List<Port> portList = ports.get().getPort();
                 for (Port port : portList) {
-                    result.add(String.format(" %-22s  %-22s  %-22s  %-6s ", NeutronvpnUtils.uuidToTapPortName(port
-                            .getUuid()), port.getMacAddress(), port.getFixedIps().get(0).getIpAddress().getIpv4Address()
-                            .getValue(), NeutronvpnUtils.getIPPrefixFromPort(broker, port)));
+                    result.add(String.format(" %-34s  %-22s  %-22s  %-6s ", port.getUuid().getValue(), port
+                            .getMacAddress(), port.getFixedIps().get(0).getIpAddress().getIpv4Address().getValue(),
+                            NeutronvpnUtils.getIPPrefixFromPort(broker, port)));
                 }
             }
         } catch (Exception e) {
@@ -1297,4 +1521,46 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         return help.toString();
     }
 
+    private void checkAndPublishSubnetAddNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
+        SubnetAddedToVpnBuilder builder = new SubnetAddedToVpnBuilder();
+
+        logger.info("publish notification called");
+
+        builder.setSubnetId(subnetId);
+        builder.setSubnetIp(subnetIp);
+        builder.setVpnName(vpnName);
+        builder.setExternalVpn(isExternalvpn);
+        builder.setElanTag(elanTag);
+
+        notificationPublishService.putNotification(builder.build());
+    }
+
+    private void checkAndPublishSubnetDelNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
+        SubnetDeletedFromVpnBuilder builder = new SubnetDeletedFromVpnBuilder();
+
+        logger.info("publish notification called");
+
+        builder.setSubnetId(subnetId);
+        builder.setSubnetIp(subnetIp);
+        builder.setVpnName(vpnName);
+        builder.setExternalVpn(isExternalvpn);
+        builder.setElanTag(elanTag);
+
+        notificationPublishService.putNotification(builder.build());
+    }
+
+    private void checkAndPublishSubnetUpdNotification(Uuid subnetId, String subnetIp, String vpnName, Boolean isExternalvpn, Long elanTag)throws InterruptedException{
+        SubnetUpdatedInVpnBuilder builder = new SubnetUpdatedInVpnBuilder();
+
+        logger.info("publish notification called");
+
+        builder.setSubnetId(subnetId);
+        builder.setSubnetIp(subnetIp);
+        builder.setVpnName(vpnName);
+        builder.setExternalVpn(isExternalvpn);
+        builder.setElanTag(elanTag);
+
+        notificationPublishService.putNotification(builder.build());
+    }
+
 }