Initial commit for NeutronVpn 71/32271/2
authorAbhinav Gupta <abhinav.gupta@ericsson.com>
Fri, 8 Jan 2016 11:54:42 +0000 (17:24 +0530)
committerAbhinav Gupta <abhinav.gupta@ericsson.com>
Fri, 8 Jan 2016 12:48:48 +0000 (18:18 +0530)
ELAN integration to be done once ELAN is in.
VLAN transparency integration to be done iff trunkport extensions are in.

Change-Id: I6db2f9b654c3146f4514c994e4f8654b1a6c7d18
Signed-off-by: Abhinav Gupta <abhinav.gupta@ericsson.com>
27 files changed:
commons/config-parent/pom.xml
features/pom.xml
features/src/main/features/features.xml
neutronvpn/neutronvpn-api/pom.xml [new file with mode: 0644]
neutronvpn/neutronvpn-api/src/main/java/org/opendaylight/vpnservice/neutronvpn/interfaces/INeutronVpnManager.java [new file with mode: 0644]
neutronvpn/neutronvpn-api/src/main/yang/neutronvpn-api.yang [new file with mode: 0644]
neutronvpn/neutronvpn-api/src/main/yang/neutronvpn.yang [new file with mode: 0644]
neutronvpn/neutronvpn-impl/pom.xml [new file with mode: 0644]
neutronvpn/neutronvpn-impl/src/main/config/default-config.xml [new file with mode: 0644]
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronBgpvpnChangeListener.java [new file with mode: 0644]
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronNetworkChangeListener.java [new file with mode: 0644]
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronPortChangeListener.java [new file with mode: 0644]
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronRouterChangeListener.java [new file with mode: 0644]
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronSubnetChangeListener.java [new file with mode: 0644]
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnManager.java [new file with mode: 0644]
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnProvider.java [new file with mode: 0644]
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnUtils.java [new file with mode: 0644]
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/neutronvpn/impl/rev150325/NeutronvpnImplModule.java [new file with mode: 0644]
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/neutronvpn/impl/rev150325/NeutronvpnImplModuleFactory.java [new file with mode: 0644]
neutronvpn/neutronvpn-impl/src/main/yang/neutronvpn-impl.yang [new file with mode: 0644]
neutronvpn/neutronvpn-shell/pom.xml [new file with mode: 0644]
neutronvpn/neutronvpn-shell/src/main/java/org/opendaylight/vpnservice/neutronvpn/shell/ConfigureL3VpnCommand.java [new file with mode: 0644]
neutronvpn/neutronvpn-shell/src/main/java/org/opendaylight/vpnservice/neutronvpn/shell/ShowNeutronPortsCommand.java [new file with mode: 0644]
neutronvpn/neutronvpn-shell/src/main/java/org/opendaylight/vpnservice/neutronvpn/shell/ShowVpnConfigCommand.java [new file with mode: 0644]
neutronvpn/neutronvpn-shell/src/main/resources/OSGI-INF/blueprint/blueprint.xml [new file with mode: 0644]
neutronvpn/pom.xml [new file with mode: 0644]
pom.xml

index a3fff3a867789594a107034ccef69c52195ee293..1d3575388661383b8dbd82d75fa668a0d6e3b672 100644 (file)
@@ -31,6 +31,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
     <vpns.ovsdb.version>1.2.1-SNAPSHOT</vpns.ovsdb.version>
     <liblldp.version>0.10.0-SNAPSHOT</liblldp.version>
+    <karaf.shell.console.version>3.0.3</karaf.shell.console.version>
     <neutron.version>0.6.0-SNAPSHOT</neutron.version>
   </properties>
 
index 569c136bed4013133fd2bfb6293d2cc7861c50ee..87365a7907435c622ca844a5bd4658ac4d1a5505 100644 (file)
@@ -39,6 +39,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <lockmanager.version>${vpnservices.version}</lockmanager.version>
     <idmanager.version>${vpnservices.version}</idmanager.version>
     <itm.version>${vpnservices.version}</itm.version>
+    <neutronvpn.version>${vpnservices.version}</neutronvpn.version>
   </properties>
   <dependencyManagement>
     <dependencies>
@@ -318,6 +319,28 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <artifactId>dhcpservice-api</artifactId>
       <version>${vpnservices.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>neutronvpn-api</artifactId>
+      <version>${neutronvpn.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>neutronvpn-impl</artifactId>
+      <version>${neutronvpn.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>neutronvpn-impl</artifactId>
+      <version>${neutronvpn.version}</version>
+      <classifier>config</classifier>
+      <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>neutronvpn-shell</artifactId>
+      <version>${neutronvpn.version}</version>
+    </dependency>
     <dependency>
       <groupId>org.apache.thrift</groupId>
       <artifactId>libthrift</artifactId>
index 7268183e35becc94ecdefb52696d33d7a73eaf82..92e6865b56673467c8accefd5fbe563f04f3cc6c 100644 (file)
@@ -34,6 +34,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <bundle>mvn:org.opendaylight.vpnservice/vpnmanager-api/${vpnmanager.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/fibmanager-api/${fibmanager.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/itm-api/${itm.version}</bundle>
+    <bundle>mvn:org.opendaylight.vpnservice/neutronvpn-api/${neutronvpn.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/dhcpservice-api/${vpnservices.version}</bundle>
   </feature>
   <feature name='odl-vpnservice-impl' version='${project.version}' description='OpenDaylight :: vpnservice :: impl '>
@@ -56,6 +57,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <bundle>mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/fibmanager-impl/${fibmanager.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/itm-impl/${itm.version}</bundle>
+    <bundle>mvn:org.opendaylight.vpnservice/neutronvpn-impl/${neutronvpn.version}</bundle>
+    <bundle>mvn:org.opendaylight.vpnservice/neutronvpn-shell/${neutronvpn.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/dhcpservice-impl/${vpnservices.version}</bundle>
 
     <!--<bundle>mvn:org.opendaylight.vpnservice.third-party/org.apache.thriftlib/1.0.1-SNAPSHOT</bundle>-->
@@ -72,6 +75,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <configfile finalname="vpnmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}/xml/config</configfile>
     <configfile finalname="fibmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/fibmanager-impl/${fibmanager.version}/xml/config</configfile>
     <configfile finalname="itm-impl-default-config.xml">mvn:org.opendaylight.vpnservice/itm-impl/${itm.version}/xml/config</configfile>
+    <configfile finalname="neutronvpn-impl-default-config.xml">mvn:org.opendaylight.vpnservice/neutronvpn-impl/${neutronvpn.version}/xml/config</configfile>
     <configfile finalname="dhcpservice-impl-default-config.xml">mvn:org.opendaylight.vpnservice/dhcpservice-impl/${vpnservices.version}/xml/config</configfile>
   </feature>
   <feature name='odl-vpnservice-impl-rest' version='${project.version}' description='OpenDaylight :: vpnservice :: impl :: REST '>
diff --git a/neutronvpn/neutronvpn-api/pom.xml b/neutronvpn/neutronvpn-api/pom.xml
new file mode 100644 (file)
index 0000000..16d28cb
--- /dev/null
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.opendaylight.vpnservice</groupId>
+        <artifactId>config-parent</artifactId>
+        <version>0.2.0-SNAPSHOT</version>
+        <relativePath>../../commons/config-parent</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opendaylight.vpnservice</groupId>
+    <artifactId>neutronvpn-api</artifactId>
+    <version>${vpnservices.version}</version>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>yang-binding</artifactId>
+            <version>${yangtools.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-common</artifactId>
+            <version>${yangtools.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.neutron</groupId>
+            <artifactId>model</artifactId>
+            <version>${neutron.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.model</groupId>
+            <artifactId>ietf-yang-types</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.vpnservice</groupId>
+            <artifactId>mdsalutil-api</artifactId>
+            <version>${vpns.mdsalutil.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-api</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/neutronvpn/neutronvpn-api/src/main/java/org/opendaylight/vpnservice/neutronvpn/interfaces/INeutronVpnManager.java b/neutronvpn/neutronvpn-api/src/main/java/org/opendaylight/vpnservice/neutronvpn/interfaces/INeutronVpnManager.java
new file mode 100644 (file)
index 0000000..8da2670
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.neutronvpn.interfaces;
+
+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.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
+
+import java.util.List;
+
+public interface INeutronVpnManager {
+
+    public void addSubnetToVpn(Uuid vpnId, Uuid subnet);
+
+    public void removeSubnetFromVpn(Uuid vpnId, Uuid subnet);
+
+    public List<Uuid> getSubnetsforVpn(Uuid vpnid);
+
+    List<String> showVpnConfigCLI(Uuid vuuid);
+
+    List<String> showNeutronPortsCLI();
+
+    public Port getNeutronPort(String name);
+
+    public Subnet getNeutronSubnet(Uuid subnetId);
+
+    public String uuidToTapPortName(Uuid id);
+
+    public Port getNeutronPort(Uuid portId);
+
+    public IpAddress getNeutronSubnetGateway(Uuid subnetId);
+
+}
diff --git a/neutronvpn/neutronvpn-api/src/main/yang/neutronvpn-api.yang b/neutronvpn/neutronvpn-api/src/main/yang/neutronvpn-api.yang
new file mode 100644 (file)
index 0000000..ae6935d
--- /dev/null
@@ -0,0 +1,20 @@
+module neutronvpn-api {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:neutronvpn:api";
+    prefix "neutronvpn-api";
+
+    import config { prefix config; revision-date 2013-04-05; }
+
+    description
+        "Service definition for neutronvpn project";
+
+    revision "2015-08-12" {
+        description
+            "Initial revision";
+    }
+
+    identity neutronvpn-api {
+        base "config:service-type";
+        config:java-class "org.opendaylight.vpnservice.neutronvpn.interfaces.INeutronVpnManager";
+    }
+}
diff --git a/neutronvpn/neutronvpn-api/src/main/yang/neutronvpn.yang b/neutronvpn/neutronvpn-api/src/main/yang/neutronvpn.yang
new file mode 100644 (file)
index 0000000..c178534
--- /dev/null
@@ -0,0 +1,274 @@
+
+module neutronvpn {
+
+    namespace "urn:opendaylight:vpnservice:neutronvpn";
+    prefix neutronvpn;
+
+    import ietf-yang-types { prefix "yang"; }
+
+    revision "2015-06-02" {
+        description "Neutron based L3Service Module, provides integration of ODL VPN service with Neutron NSF";
+    }
+
+    container subnetmaps{
+        list subnetmap {
+            key id;
+            leaf id {
+              type    yang:uuid;
+              description "UUID representing the subnet ";
+            }
+
+            leaf tenant-id {
+                type    yang:uuid;
+                description "The UUID of the tenant that will own the subnet.";
+            }
+
+            leaf network-id {
+              type    yang:uuid;
+              description "UUID representing the network ";
+            }
+
+            leaf router-id {
+              type    yang:uuid;
+              description "router to which this subnet belongs";
+            }
+
+            leaf vpn-id {
+              type    yang:uuid;
+              description "VPN to which this subnet belongs";
+            }
+
+            leaf-list port-list {
+              type yang:uuid;
+            }
+        }
+    }
+
+    container networkMaps{
+        list networkMap {
+            key network-id;
+
+            leaf network-id {
+                type    yang:uuid;
+                description "UUID representing the network";
+            }
+
+            leaf-list subnet-id-list {
+                type    yang:uuid;
+                description "List of UUIDs representing the subnets associated to the network";
+            }
+        }
+    }
+
+    grouping l3vpn-instance{
+
+        leaf id {
+            mandatory "true";
+            type    yang:uuid;
+            description "vpn-id";
+        }
+
+        leaf name {
+          type    string;
+          description "VPN name";
+        }
+
+        leaf tenant-id {
+            type    yang:uuid;
+            description "The UUID of the tenant that will own the subnet.";
+        }
+
+        leaf-list route-distinguisher {
+            type string;
+            description
+            "configures a route distinguisher (RD) for the VPN instance.
+             Format is ASN:nn or IP-address:nn.";
+        }
+
+        leaf-list import-RT {
+            type string;
+            description
+            "configures a list of import route target.
+             Format is ASN:nn or IP-address:nn.";
+        }
+
+        leaf-list export-RT{
+            type string;
+            description
+            "configures a list of export route targets.
+             Format is ASN:nn or IP-address:nn.";
+        }
+
+        leaf router-id {
+          type    yang:uuid;
+          description "UUID of router ";
+        }
+
+        leaf-list network-ids {
+          type    yang:uuid;
+          description "UUID representing the network ";
+        }
+    }
+
+    container vpnMaps {
+        list vpnMap {
+            key vpn-id;
+            leaf vpn-id {
+                type    yang:uuid;
+                description "vpn-id";
+            }
+            leaf name {
+                type  string;
+                description "vpn name";
+            }
+            leaf tenant-id {
+                type    yang:uuid;
+                description "The UUID of the tenant that will own the subnet.";
+            }
+
+            leaf router-id {
+              type    yang:uuid;
+              description "UUID of router ";
+            }
+            leaf-list network_ids {
+              type    yang:uuid;
+              description "UUID representing the network ";
+            }
+        }
+    }
+
+    /* Data models to adhere to restart requirements */
+    container neutron-port-data {
+        list port-name-to-port-uuid {
+            key port-name;
+            leaf port-id { type yang:uuid;}
+            leaf port-name { type string;}
+        }
+        list port-fixedip-to-port-name {
+            key port-fixedip;
+            leaf port-name { type string;}
+            leaf port-fixedip { type string;}
+        }
+    }
+
+    rpc createL3VPN{
+        description "Create one or more L3 VPN";
+        input {
+            list l3vpn {
+                uses l3vpn-instance;
+            }
+        }
+        output {
+            leaf-list response {
+                type    string;
+                description "Status response for createVPN RPC";
+            }
+        }
+    }
+
+    rpc associateRouter {
+        description "associates a router with L3VPN";
+        input {
+            leaf vpn-id {
+                type    yang:uuid;
+                mandatory "true";
+                description "vpn-id";
+            }
+            leaf router-id {
+                type    yang:uuid;
+                mandatory "true";
+                description "vpn-id";
+            }
+        }
+    }
+
+    rpc dissociateRouter {
+        description "dissociates a router with L3VPN";
+        input {
+            leaf vpn-id {
+                type    yang:uuid;
+                mandatory "true";
+                description "vpn-id";
+            }
+            leaf router-id {
+                type    yang:uuid;
+                mandatory "true";
+                description "router-id";
+            }
+        }
+    }
+
+    rpc associateNetworks {
+        description "associates a list of networks with L3VPN";
+        input {
+            leaf vpn-id {
+                type    yang:uuid;
+                mandatory "true";
+                description "vpn-id";
+            }
+            leaf-list network-id {
+                type    yang:uuid;
+                description "network-id";
+            }
+        }
+        output {
+            leaf response {
+                type    string;
+                description "Status response for associateNetworks RPC";
+            }
+        }
+    }
+
+    rpc dissociateNetworks{
+        description "dissociates a list of networks with L3VPN";
+        input {
+            leaf vpn-id {
+                type    yang:uuid;
+                mandatory "true";
+                description "vpn-id";
+            }
+            leaf-list network-id {
+                type    yang:uuid;
+                description "network-id";
+            }
+        }
+        output {
+            leaf response {
+                type    string;
+                description "Status response for dissociateNetworks RPC";
+            }
+        }
+    }
+
+    rpc deleteL3VPN{
+        description "delete VPNs for specified Id list";
+        input {
+            leaf-list id {
+                type    yang:uuid;
+                description "vpn-id";
+            }
+        }
+        output {
+            leaf-list response {
+                type    string;
+                description "Status response for deleteL3VPN RPC";
+            }
+        }
+    }
+
+    rpc getL3VPN{
+        description "returns VPN configuration";
+        input {
+            leaf id {
+                type    yang:uuid;
+                description "vpn-id";
+            }
+        }
+        output {
+            list l3vpn-instances {
+                uses l3vpn-instance;
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/neutronvpn/neutronvpn-impl/pom.xml b/neutronvpn/neutronvpn-impl/pom.xml
new file mode 100644 (file)
index 0000000..8f9e42a
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: --><!--
+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,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <parent>
+        <groupId>org.opendaylight.vpnservice</groupId>
+        <artifactId>config-parent</artifactId>
+        <version>0.2.0-SNAPSHOT</version>
+        <relativePath>../../commons/config-parent</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opendaylight.vpnservice</groupId>
+    <artifactId>neutronvpn-impl</artifactId>
+    <version>${vpnservices.version}</version>
+    <packaging>bundle</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.neutron</groupId>
+            <artifactId>model</artifactId>
+            <version>${neutron.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.vpnservice</groupId>
+            <artifactId>neutronvpn-api</artifactId>
+            <version>${vpnservices.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.vpnservice</groupId>
+            <artifactId>vpnmanager-api</artifactId>
+            <version>${vpnservices.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.vpnservice</groupId>
+            <artifactId>mdsalutil-api</artifactId>
+            <version>${vpnservices.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.vpnservice</groupId>
+            <artifactId>lockmanager-api</artifactId>
+            <version>${vpnservices.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/neutronvpn/neutronvpn-impl/src/main/config/default-config.xml b/neutronvpn/neutronvpn-impl/src/main/config/default-config.xml
new file mode 100644 (file)
index 0000000..8982042
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+Copyright (c) 2015 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,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<snapshot>
+    <required-capabilities>
+        <capability>urn:opendaylight:params:xml:ns:yang:neutronvpn:impl?module=neutronvpn-impl&amp;revision=2015-03-25</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:mdsalutil:api?module=odl-mdsalutil&amp;revision=2015-04-10</capability>
+    </required-capabilities>
+    <configuration>
+
+        <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:neutronvpn:impl">prefix:neutronvpn-impl
+                    </type>
+                    <name>neutronvpn-default</name>
+                    <broker>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
+                            binding:binding-broker-osgi-registry
+                        </type>
+                        <name>binding-osgi-broker</name>
+                    </broker>
+                    <rpc-registry>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
+                            binding:binding-rpc-registry
+                        </type>
+                        <name>binding-rpc-broker</name>
+                    </rpc-registry>
+                    <mdsalutil>
+                        <type xmlns:mdsalutil="urn:opendaylight:params:xml:ns:yang:mdsalutil:api">
+                            mdsalutil:odl-mdsalutil
+                        </type>
+                        <name>mdsalutil-service</name>
+                    </mdsalutil>
+                </module>
+            </modules>
+            <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <service>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:neutronvpn:api">prefix:neutronvpn-api</type>
+                    <instance>
+                        <name>neutronvpn</name>
+                        <provider>/modules/module[type='neutronvpn-impl'][name='neutronvpn-default']</provider>
+                    </instance>
+                </service>
+            </services>
+        </data>
+    </configuration>
+</snapshot>
diff --git a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronBgpvpnChangeListener.java b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronBgpvpnChangeListener.java
new file mode 100644 (file)
index 0000000..d413a32
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.neutronvpn;
+
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
+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.neutron.bgpvpns.rev150903.bgpvpns.attributes.Bgpvpns;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.bgpvpns.rev150903.bgpvpns.attributes.bgpvpns.Bgpvpn;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class NeutronBgpvpnChangeListener extends AbstractDataChangeListener<Bgpvpn> implements AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronBgpvpnChangeListener.class);
+
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+    private NeutronvpnManager nvpnManager;
+
+
+    public NeutronBgpvpnChangeListener(final DataBroker db, NeutronvpnManager nVpnMgr) {
+        super(Bgpvpn.class);
+        nvpnManager = nVpnMgr;
+        registerListener(db);
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (final Exception e) {
+                LOG.error("Error when cleaning up DataChangeListener.", e);
+            }
+            listenerRegistration = null;
+        }
+        LOG.info("N_Bgpvpn listener Closed");
+    }
+
+
+    private void registerListener(final DataBroker db) {
+        try {
+            listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Neutron.class).child(Bgpvpns.class).child(Bgpvpn.class),
+                    NeutronBgpvpnChangeListener.this, DataChangeScope.SUBTREE);
+        } catch (final Exception e) {
+            LOG.error("Neutron Manager Bgpvpn DataChange listener registration fail!", e);
+            throw new IllegalStateException("Neutron Manager Bgpvpn DataChange listener registration failed.", e);
+        }
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<Bgpvpn> identifier, Bgpvpn input) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Adding Bgpvpn : key: " + identifier + ", value=" + input);
+        }
+        // Create internal VPN
+        // handle route-target
+        List<String> irt = new ArrayList<String>();
+        List<String> ert = new ArrayList<String>();
+        List<String> inrt = input.getRouteTargets();
+        List<String> inirt = input.getImportTargets();
+        List<String> inert = input.getExportTargets();
+        if (inrt != null && !inrt.isEmpty()) {
+            irt.addAll(inrt);
+            ert.addAll(inrt);
+        }
+        if (inirt != null && !inirt.isEmpty()) {
+            irt.addAll(inirt);
+        }
+        if (inert != null && !inert.isEmpty()) {
+            ert.addAll(inert);
+        }
+        List<String> rd = input.getRouteDistinguishers();
+
+        if (rd == null || rd.isEmpty()) {
+            // generate new RD
+        }
+        Uuid router = null;
+        if (input.getRouters() != null) {
+            // currently only one router
+            router = input.getRouters().get(0);
+        }
+        nvpnManager.createL3Vpn(input.getUuid(), input.getName(), input.getTenantId(),
+                rd, irt, ert, router, input.getNetworks());
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<Bgpvpn> identifier, Bgpvpn input) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Removing Bgpvpn : key: " + identifier + ", value=" + input);
+        }
+        nvpnManager.removeL3Vpn(input.getUuid());
+
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<Bgpvpn> identifier, Bgpvpn original, Bgpvpn update) {
+        List<Uuid> oldNetworks = original.getNetworks();
+        List<Uuid> newNetworks = update.getNetworks();
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Update Bgpvpn : key: " + identifier + ", value=" + update);
+        }
+        if (newNetworks != null && !newNetworks.isEmpty()) {
+            if (oldNetworks != null && !oldNetworks.isEmpty()) {
+                if (oldNetworks != newNetworks) {
+                    Iterator<Uuid> iter = newNetworks.iterator();
+                    while (iter.hasNext()) {
+                        Object net = iter.next();
+                        if (oldNetworks.contains(net)) {
+                            oldNetworks.remove(net);
+                            iter.remove();
+                        }
+                    }
+                    //clear removed networks
+                    if (!oldNetworks.isEmpty()) {
+                        LOG.trace("Removing old networks {} ", oldNetworks);
+                        nvpnManager.dissociateNetworksFromVpn(update.getUuid(), oldNetworks);
+                    }
+                    //add new (Delta) Networks
+                    if (!newNetworks.isEmpty()) {
+                        LOG.trace("Adding delta New networks {} ", newNetworks);
+                        nvpnManager.associateNetworksToVpn(update.getUuid(), newNetworks);
+                    }
+                }
+            } else {
+                //add new Networks
+                LOG.trace("Adding New networks {} ", newNetworks);
+                nvpnManager.associateNetworksToVpn(update.getUuid(), newNetworks);
+            }
+        }
+        // ### TBD : Handle routers
+    }
+
+}
\ No newline at end of file
diff --git a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronNetworkChangeListener.java b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronNetworkChangeListener.java
new file mode 100644 (file)
index 0000000..e5bc67e
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.neutronvpn;
+
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class NeutronNetworkChangeListener extends AbstractDataChangeListener<Network> implements AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronNetworkChangeListener.class);
+
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+    private final DataBroker broker;
+    private NeutronvpnManager nvpnManager;
+
+
+    public NeutronNetworkChangeListener(final DataBroker db, NeutronvpnManager nVpnMgr) {
+        super(Network.class);
+        broker = db;
+        nvpnManager = nVpnMgr;
+        registerListener(db);
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (final Exception e) {
+                LOG.error("Error when cleaning up DataChangeListener.", e);
+            }
+            listenerRegistration = null;
+        }
+        LOG.info("N_Network listener Closed");
+    }
+
+
+    private void registerListener(final DataBroker db) {
+        try {
+            listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Neutron.class).
+                            child(Networks.class).child(Network.class),
+                    NeutronNetworkChangeListener.this, DataChangeScope.SUBTREE);
+            LOG.info("Neutron Manager Network DataChange listener registration Success!");
+        } catch (final Exception e) {
+            LOG.error("Neutron Manager Network DataChange listener registration fail!", e);
+            throw new IllegalStateException("Neutron Manager Network DataChange listener registration failed.", e);
+        }
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<Network> identifier, Network input) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Adding Network : key: " + identifier + ", value=" + input);
+        }
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<Network> identifier, Network input) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Removing Network : key: " + identifier + ", value=" + input);
+        }
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<Network> identifier, Network original, Network update) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Updating Network : key: " + identifier + ", original value=" + original + ", update value=" +
+                    update);
+        }
+    }
+
+}
diff --git a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronPortChangeListener.java b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronPortChangeListener.java
new file mode 100644 (file)
index 0000000..a615600
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.neutronvpn;
+
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
+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.rev150712.Neutron;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class NeutronPortChangeListener extends AbstractDataChangeListener<Port> implements AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronPortChangeListener.class);
+
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+    private final DataBroker broker;
+    private NeutronvpnManager nvpnManager;
+
+
+    public NeutronPortChangeListener(final DataBroker db, NeutronvpnManager nVpnMgr) {
+        super(Port.class);
+        broker = db;
+        nvpnManager = nVpnMgr;
+        registerListener(db);
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (final Exception e) {
+                LOG.error("Error when cleaning up DataChangeListener.", e);
+            }
+            listenerRegistration = null;
+        }
+        LOG.info("N_Port listener Closed");
+    }
+
+
+    private void registerListener(final DataBroker db) {
+        try {
+            listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class),
+                    NeutronPortChangeListener.this, DataChangeScope.SUBTREE);
+        } catch (final Exception e) {
+            LOG.error("Neutron Manager Port DataChange listener registration fail!", e);
+            throw new IllegalStateException("Neutron Manager Port DataChange listener registration failed.", e);
+        }
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<Port> identifier, Port input) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Adding Port : key: " + identifier + ", value=" + input);
+        }
+        nvpnManager.handleNeutronPortCreated(input);
+
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<Port> identifier, Port input) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Removing Port : key: " + identifier + ", value=" + input);
+        }
+        nvpnManager.handleNeutronPortDeleted(input);
+
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<Port> identifier, Port original, Port update) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Updating Port : key: " + identifier + ", original value=" + original + ", update value=" +
+                    update);
+        }
+        List<FixedIps> oldIPs = (original.getFixedIps() != null) ? original.getFixedIps() : new ArrayList<FixedIps>();
+        List<FixedIps> newIPs = (update.getFixedIps() != null) ? update.getFixedIps() : new ArrayList<FixedIps>();
+
+        if (!oldIPs.equals(newIPs)) {
+            Iterator<FixedIps> iterator = newIPs.iterator();
+            while (iterator.hasNext()) {
+                FixedIps ip = iterator.next();
+                if (oldIPs.remove(ip)) {
+                    iterator.remove();
+                }
+            }
+            nvpnManager.handleNeutronPortUpdated(original, update);
+        }
+    }
+}
diff --git a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronRouterChangeListener.java b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronRouterChangeListener.java
new file mode 100644 (file)
index 0000000..6d64485
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.neutronvpn;
+
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
+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.neutron.l3.rev150712.routers.attributes.Routers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMap;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class NeutronRouterChangeListener extends AbstractDataChangeListener<Router> implements AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronRouterChangeListener.class);
+
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+    private final DataBroker broker;
+    private NeutronvpnManager nvpnManager;
+
+
+    public NeutronRouterChangeListener(final DataBroker db, NeutronvpnManager nVpnMgr) {
+        super(Router.class);
+        broker = db;
+        nvpnManager = nVpnMgr;
+        registerListener(db);
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (final Exception e) {
+                LOG.error("Error when cleaning up DataChangeListener.", e);
+            }
+            listenerRegistration = null;
+        }
+        LOG.info("N_Router listener Closed");
+    }
+
+
+    private void registerListener(final DataBroker db) {
+        try {
+            listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Neutron.class).child(Routers.class).child(Router.class),
+                    NeutronRouterChangeListener.this, DataChangeScope.SUBTREE);
+        } catch (final Exception e) {
+            LOG.error("Neutron Manager Router DataChange listener registration fail!", e);
+            throw new IllegalStateException("Neutron Manager Router DataChange listener registration failed.", e);
+        }
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<Router> identifier, Router input) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Adding Router : key: " + identifier + ", value=" + input);
+        }
+        // Create internal VPN
+        nvpnManager.createL3Vpn(input.getUuid(), null, null, null, null, null, input.getUuid(), null);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<Router> identifier, Router input) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Removing router : key: " + identifier + ", value=" + input);
+        }
+        // check if this router has internal-VPN
+        Uuid routerId = input.getUuid();
+        VpnMap vpnmap = NeutronvpnUtils.getVpnMap(broker, routerId);
+        if (vpnmap != null) {
+            // if yes, remove corresponding internal vpn
+            LOG.trace("removing internal-vpn for router {}", routerId);
+            nvpnManager.removeL3Vpn(routerId);
+        } else {
+            // if not, it is associated with some VPN
+            // remove VPN-router association
+            Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId);
+            LOG.trace("dissociating router {} from vpn {}", routerId, vpnId);
+            nvpnManager.dissociateRouterFromVpn(vpnId, routerId);
+        }
+
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<Router> identifier, Router original, Router update) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Updating Router : key: " + identifier + ", original value=" + original + ", update value=" +
+                    update);
+        }
+        Uuid routerId = update.getUuid();
+        Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId);
+        List<Interfaces> oldInterfaces = (original.getInterfaces() != null) ? original.getInterfaces() : new
+                ArrayList<Interfaces>();
+        List<Interfaces> newInterfaces = (update.getInterfaces() != null) ? update.getInterfaces() : new
+                ArrayList<Interfaces>();
+        List<String> oldRoutes = (original.getRoutes() != null) ? original.getRoutes() : new ArrayList<String>();
+        List<String> newRoutes = (update.getRoutes() != null) ? update.getRoutes() : new ArrayList<String>();
+
+        if (!oldInterfaces.equals(newInterfaces)) {
+            for (Interfaces intrf : newInterfaces) {
+                if (!oldInterfaces.remove(intrf)) {
+                    // add new subnet
+                    nvpnManager.addSubnetToVpn(vpnId, intrf.getSubnetId());
+                }
+            }
+            //clear remaining old subnets
+            for (Interfaces intrf : oldInterfaces) {
+                nvpnManager.removeSubnetFromVpn(vpnId, intrf.getSubnetId());
+            }
+        }
+        if (!oldRoutes.equals(newRoutes)) {
+            Iterator<String> iterator = newRoutes.iterator();
+            while (iterator.hasNext()) {
+                String route = iterator.next();
+                if (oldRoutes.remove(route)) {
+                    iterator.remove();
+                }
+            }
+            nvpnManager.addAdjacencyforExtraRoute(newRoutes, true, null);
+            if (!oldRoutes.isEmpty()) {
+                nvpnManager.removeAdjacencyforExtraRoute(oldRoutes);
+            }
+        }
+    }
+}
diff --git a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronSubnetChangeListener.java b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronSubnetChangeListener.java
new file mode 100644 (file)
index 0000000..5eceab3
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.neutronvpn;
+
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
+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.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.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class NeutronSubnetChangeListener extends AbstractDataChangeListener<Subnet> implements AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronSubnetChangeListener.class);
+
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+    private final DataBroker broker;
+    private NeutronvpnManager nvpnManager;
+
+
+    public NeutronSubnetChangeListener(final DataBroker db, NeutronvpnManager nVpnMgr) {
+        super(Subnet.class);
+        broker = db;
+        nvpnManager = nVpnMgr;
+        registerListener(db);
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (final Exception e) {
+                LOG.error("Error when cleaning up DataChangeListener.", e);
+            }
+            listenerRegistration = null;
+        }
+        LOG.info("N_Subnet listener Closed");
+    }
+
+
+    private void registerListener(final DataBroker db) {
+        try {
+            listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Neutron.class).child(Subnets.class).child(Subnet.class),
+                    NeutronSubnetChangeListener.this, DataChangeScope.SUBTREE);
+        } catch (final Exception e) {
+            LOG.error("Neutron Manager Subnet DataChange listener registration fail!", e);
+            throw new IllegalStateException("Neutron Manager Subnet DataChange listener registration failed.", e);
+        }
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<Subnet> identifier, Subnet input) {
+        LOG.trace("Adding Subnet : key: " + identifier + ", value=" + input);
+        nvpnManager.updateSubnetNode(input.getUuid(), input.getTenantId(), input.getNetworkId(), null, null, null);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<Subnet> identifier, Subnet input) {
+        LOG.trace("Removing subnet : key: " + identifier + ", value=" + input);
+        Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(broker, input.getNetworkId());
+        if (vpnId != null) {
+            nvpnManager.removeSubnetFromVpn(vpnId, input.getUuid());
+        }
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<Subnet> identifier, Subnet original, Subnet update) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Updating Subnet : key: " + identifier + ", original value=" + original + ", update value=" +
+                    update);
+        }
+        nvpnManager.updateSubnetNode(update.getUuid(), update.getTenantId(), update.getNetworkId(), null, null, null);
+    }
+}
diff --git a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnManager.java b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnManager.java
new file mode 100644 (file)
index 0000000..3a59137
--- /dev/null
@@ -0,0 +1,1430 @@
+/*
+ * 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.neutronvpn;
+
+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.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.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.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.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.iana._if.type.rev140508.L2vlan;
+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.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
+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.l3vpn.rev130911.adjacency.list.AdjacencyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
+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.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.SubnetmapsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.VpnMaps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.VpnMapsBuilder;
+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
+        .L3vpnInstancesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data
+        .PortFixedipToPortNameBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data
+        .PortNameToPortUuidBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.subnetmaps.Subnetmap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.subnetmaps.SubnetmapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMap;
+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.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
+
+    private static final Logger logger = LoggerFactory.getLogger(NeutronvpnManager.class);
+    private final DataBroker broker;
+    private LockManagerService lockManager;
+    IMdsalApiManager mdsalUtil;
+
+    /**
+     * @param db           - dataBroker reference
+     * @param mdsalManager - MDSAL Util API access
+     */
+    public NeutronvpnManager(final DataBroker db, IMdsalApiManager mdsalManager) {
+        broker = db;
+        mdsalUtil = mdsalManager;
+    }
+
+    public void setLockManager(LockManagerService lockManager) {
+        this.lockManager = lockManager;
+    }
+
+    @Override
+    public void close() throws Exception {
+        logger.info("Neutron VPN Manager Closed");
+    }
+
+    protected Subnetmap updateSubnetNode(Uuid subnetId, Uuid tenantId, Uuid networkId, Uuid routerId, Uuid vpnId,
+                                         Uuid portId) {
+
+        try {
+            SubnetmapBuilder builder = null;
+
+            InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).
+                    child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
+            Optional<Subnetmap> sn = read(LogicalDatastoreType.CONFIGURATION, id);
+            logger.debug("updating Subnet :read: ");
+            if (sn.isPresent()) {
+                builder = new SubnetmapBuilder(sn.get());
+                logger.debug("updating Subnet :existing: ");
+            } else {
+                builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
+                logger.debug("updating Subnet :new: ");
+            }
+
+            if (routerId != null) {
+                builder.setRouterId(routerId);
+            }
+            if (networkId != null) {
+                builder.setNetworkId(networkId);
+            }
+            if (vpnId != null) {
+                builder.setVpnId(vpnId);
+            }
+            if (tenantId != null) {
+                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 subnetmap = builder.build();
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
+            logger.debug("Created/Updated subnetmap node: {} ", subnetId.getValue());
+
+            return subnetmap;
+        } catch (Exception e) {
+            logger.error("Update local subnetmap failed for node: {} {} {} {} {} {} ",
+                    subnetId.getValue(), tenantId.getValue(), networkId.getValue(), routerId.getValue(), vpnId
+                            .getValue(), portId.getValue());
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    protected Subnetmap removeFromSubnetNode(Uuid subnetId, Uuid networkId, Uuid routerId, Uuid vpnId, Uuid portId) {
+        Subnetmap subnetmap = null;
+        try {
+            InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).
+                    child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
+            Optional<Subnetmap> sn = read(LogicalDatastoreType.CONFIGURATION, id);
+
+            if (sn.isPresent()) {
+                SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
+
+                if (routerId != null) {
+                    builder.setRouterId(null);
+                }
+                if (networkId != null) {
+                    builder.setNetworkId(null);
+                }
+                if (vpnId != null) {
+                    builder.setVpnId(null);
+                }
+                if (portId != null && builder.getPortList() != null) {
+                    List<Uuid> portList = builder.getPortList();
+                    portList.remove(portId);
+                    builder.setPortList(portList);
+                }
+
+                subnetmap = builder.build();
+                logger.debug("Removing from existing subnetmap node: {} ", subnetId.getValue());
+                MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
+            } else {
+                logger.warn("remove from non-existing subnetmap node: {} ", subnetId.getValue());
+            }
+        } catch (Exception e) {
+            logger.error("Remove from subnetmap failed for node: {} {} {} {} {} {} ", subnetId.getValue(), networkId
+                    .getValue(), routerId.getValue(), vpnId.getValue(), portId.getValue());
+            throw new RuntimeException(e);
+        }
+
+        return subnetmap;
+    }
+
+    private void updateVpnInstanceNode(String name, List<String> rd, List<String> irt, List<String> ert) {
+
+        try {
+            VpnInstanceBuilder builder = null;
+            List<VpnTarget> vpnTargetList = new ArrayList<VpnTarget>();
+            InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class).
+                    child(VpnInstance.class, new VpnInstanceKey(name)).build();
+            Optional<VpnInstance> optionalVpn = read(LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
+            logger.debug("Creating/Updating a new vpn-instance node: {} ", name);
+            if (optionalVpn.isPresent()) {
+                builder = new VpnInstanceBuilder(optionalVpn.get());
+                logger.debug("updating existing vpninstance node");
+            } else {
+                builder = new VpnInstanceBuilder().setKey(new VpnInstanceKey(name)).setVpnInstanceName(name);
+            }
+
+            if (irt != null && !irt.isEmpty()) {
+                if (ert != null && !ert.isEmpty()) {
+                    List<String> commonRT = new ArrayList<String>(irt);
+                    commonRT.retainAll(ert);
+
+                    for (String common : commonRT) {
+                        irt.remove(common);
+                        ert.remove(common);
+                        VpnTarget vpnTarget = new VpnTargetBuilder().setKey(new VpnTargetKey(common)).setVrfRTValue
+                                (common).setVrfRTType(VpnTarget.VrfRTType.Both).build();
+                        vpnTargetList.add(vpnTarget);
+                    }
+                }
+                for (String importRT : irt) {
+                    VpnTarget vpnTarget = new VpnTargetBuilder().setKey(new VpnTargetKey(importRT)).setVrfRTValue
+                            (importRT).setVrfRTType(VpnTarget.VrfRTType.ImportExtcommunity).build();
+                    vpnTargetList.add(vpnTarget);
+                }
+            }
+
+            if (ert != null && !ert.isEmpty()) {
+                for (String exportRT : ert) {
+                    VpnTarget vpnTarget = new VpnTargetBuilder().setKey(new VpnTargetKey(exportRT)).setVrfRTValue
+                            (exportRT).setVrfRTType(VpnTarget.VrfRTType.ExportExtcommunity).build();
+                    vpnTargetList.add(vpnTarget);
+                }
+            }
+
+            VpnTargets vpnTargets = new VpnTargetsBuilder().setVpnTarget(vpnTargetList).build();
+
+            Ipv4FamilyBuilder ipv4vpnBuilder = new Ipv4FamilyBuilder().setVpnTargets(vpnTargets);
+
+            if (rd != null && !rd.isEmpty()) {
+                ipv4vpnBuilder.setRouteDistinguisher(rd.get(0));
+            }
+
+            VpnInstance newVpn = builder.setIpv4Family(ipv4vpnBuilder.build()).build();
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier, newVpn);
+            logger.debug("Created/Updated vpn-instance for {} ", name);
+        } catch (Exception e) {
+            logger.error("Update VPN Instance node failed for node: {} {} {} {}", name, rd, irt, ert);
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void createVpnMapsNode() {
+        InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
+        VpnMapsBuilder vpnMaps = new VpnMapsBuilder();
+        MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier, vpnMaps.build());
+        InstanceIdentifier<Subnetmaps> subnetmapsId = InstanceIdentifier.builder(Subnetmaps.class).build();
+        SubnetmapsBuilder subnetmaps = new SubnetmapsBuilder();
+        MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, subnetmapsId, subnetmaps.build());
+    }
+
+    private void deleteVpnMapsNode(Uuid vpnid) {
+        InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
+                .child(VpnMap.class, new VpnMapKey(vpnid)).build();
+        logger.debug("removing vpnMaps node: {} ", vpnid.getValue());
+        MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
+    }
+
+    private void updateVpnMaps(Uuid vpnId, String name, Uuid router, Uuid tenantId, List<Uuid> networks) {
+        VpnMapBuilder builder;
+        InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
+                .child(VpnMap.class, new VpnMapKey(vpnId)).build();
+        Optional<VpnMap> optionalVpnMap = read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
+        if (optionalVpnMap.isPresent()) {
+            builder = new VpnMapBuilder(optionalVpnMap.get());
+        } else {
+            builder = new VpnMapBuilder().setKey(new VpnMapKey(vpnId)).setVpnId(vpnId);
+        }
+
+        if (name != null) {
+            builder.setName(name);
+        }
+        if (tenantId != null) {
+            builder.setTenantId(tenantId);
+        }
+        if (router != null) {
+            builder.setRouterId(router);
+        }
+        if (networks != null) {
+            List<Uuid> nwList = builder.getNetworkIds();
+            if (nwList == null) {
+                nwList = new ArrayList<Uuid>();
+            }
+            nwList.addAll(networks);
+            builder.setNetworkIds(nwList);
+        }
+
+        logger.debug("Creating/Updating vpnMaps node: {} ", vpnId.getValue());
+        MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier, builder.build());
+        logger.debug("VPNMaps DS updated for VPN {} ", vpnId.getValue());
+    }
+
+    private void clearFromVpnMaps(Uuid id, Uuid router, List<Uuid> networks) {
+        InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
+                .child(VpnMap.class, new VpnMapKey(id)).build();
+        Optional<VpnMap> optionalVpnMap = read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
+        if (optionalVpnMap.isPresent()) {
+            VpnMap vpnMap = optionalVpnMap.get();
+            VpnMapBuilder vpnMapBuilder = new VpnMapBuilder(vpnMap);
+            if (router != null) {
+                if (vpnMap.getNetworkIds() == null && router.equals(vpnMap.getVpnId())) {
+                    // remove entire node in case of internal VPN
+                    logger.debug("removing vpnMaps node: {} ", id);
+                    MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
+                    return;
+                }
+                vpnMapBuilder.setRouterId(null);
+            }
+            if (networks != null) {
+                List<Uuid> vpnNw = vpnMap.getNetworkIds();
+                for (Uuid nw : networks) {
+                    vpnNw.remove(nw);
+                }
+                if (vpnNw.isEmpty()) {
+                    logger.debug("setting networks null in vpnMaps node: {} ", id.getValue());
+                    vpnMapBuilder.setNetworkIds(null);
+                } else {
+                    vpnMapBuilder.setNetworkIds(vpnNw);
+                }
+            }
+
+            logger.debug("clearing from vpnMaps node: {} ", id.getValue());
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier, vpnMapBuilder.build());
+        } else {
+            logger.error("VPN : {} not found", id.getValue());
+        }
+        logger.debug("VPNMaps DS clear success for VPN {} ", id.getValue());
+    }
+
+    private void createOfPortInterface(Port port, int portVlanId) {
+        String name = NeutronvpnUtils.uuidToTapPortName(port.getUuid());
+        //String ifname = new StringBuilder(name).append(":").append(Integer.toString(portVlanId)).toString();
+        //Network network = NeutronvpnUtils.getNeutronNetwork(broker, port.getNetworkId());
+        //Boolean isVlanTransparent = network.isVlanTransparent();
+
+        logger.debug("Creating OFPort Interface {}", name);
+        InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(name);
+        try {
+            Optional<Interface> optionalInf = read(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier);
+            if (!optionalInf.isPresent()) {
+                // handle these for trunkport extensions : portVlanId, isVlanTransparent
+                Interface inf = new InterfaceBuilder().setEnabled(true).setName(name).setType(L2vlan.class).build();
+                MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, interfaceIdentifier, inf);
+            } else {
+                logger.error("Interface {} is already present", name);
+            }
+        } catch (Exception e) {
+            logger.error("failed to create interface {} due to the exception {} ", name, e.getMessage());
+        }
+
+        InstanceIdentifier portIdentifier = NeutronvpnUtils.buildPortNameToPortUuidIdentifier(name);
+        PortNameToPortUuidBuilder builder = new PortNameToPortUuidBuilder().setPortName(name).setPortId(port.getUuid());
+        MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, portIdentifier, builder.build());
+        logger.debug("name-uuid map for port with name: {}, uuid: {} added to NeutronPortData DS", name, port.getUuid
+                ());
+    }
+
+    private void deleteOfPortInterface(Port port, int portVlanId) {
+        String name = NeutronvpnUtils.uuidToTapPortName(port.getUuid());
+        //String ifname = new StringBuilder(name).append(":").append(Integer.toString(portVlanId)).toString();
+        logger.debug("Removing OFPort Interface {}", name);
+        InstanceIdentifier interfaceIdentifier = NeutronvpnUtils.buildVlanInterfaceIdentifier(name);
+        try {
+            Optional<Interface> optionalInf = read(LogicalDatastoreType.CONFIGURATION, interfaceIdentifier);
+            if (optionalInf.isPresent()) {
+                MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, interfaceIdentifier);
+            } else {
+                logger.error("Interface {} is not present", name);
+            }
+        } catch (Exception e) {
+            logger.error("Failed to delete interface {} due to the exception {}", name, e.getMessage());
+        }
+
+        InstanceIdentifier id = NeutronvpnUtils.buildPortNameToPortUuidIdentifier(name);
+        MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, id);
+        logger.debug("name-uuid map for port with name: {}, uuid: {} deleted from NeutronPortData DS", name, port
+                .getUuid());
+    }
+
+    private void deleteVpnInstance(Uuid vpnId) {
+
+        InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class).
+                child(VpnInstance.class, new VpnInstanceKey(vpnId.getValue())).build();
+        logger.debug("removing vpn Instance {}", vpnId.getValue());
+        MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
+    }
+
+
+    private void createVpnInterface(Uuid vpnId, Port port) {
+
+        if (vpnId == null || port == null) {
+            return;
+        }
+        String portname = NeutronvpnUtils.uuidToTapPortName(port.getUuid());
+        String name = new StringBuilder(portname).append(":0").toString();
+        List<Adjacency> adjList = new ArrayList<Adjacency>();
+        InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
+                child(VpnInterface.class, new VpnInterfaceKey(name)).build();
+        // find router associated to vpn
+        Uuid routerId = NeutronvpnUtils.getRouterforVpn(broker, vpnId);
+        Router rtr = null;
+        if (routerId != null) {
+            rtr = NeutronvpnUtils.getNeutronRouter(broker, routerId);
+        }
+        // find all Subnets to which this port is associated
+        List<FixedIps> ips = port.getFixedIps();
+        // create adjacency list
+        for (FixedIps ip : ips) {
+            // create vm adjacency
+            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();
+            adjList.add(vmAdj);
+            // create extra route adjacency
+            if (rtr != null && rtr.getRoutes() != null) {
+                List<String> routeList = rtr.getRoutes();
+                List<Adjacency> erAdjList = addAdjacencyforExtraRoute(routeList, false, name);
+                if (erAdjList != null) {
+                    adjList.addAll(erAdjList);
+                }
+            }
+        }
+        // create vpn-interface on this neutron port
+        Adjacencies adjs = new AdjacenciesBuilder().setAdjacency(adjList).build();
+        VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(name)).
+                setName(name).setVpnInstanceName(vpnId.getValue()).addAugmentation(Adjacencies.class, adjs);
+        VpnInterface vpnIf = vpnb.build();
+
+        NeutronvpnUtils.lockVpnInterface(lockManager, name);
+        try {
+            logger.debug("Creating vpn interface {}", vpnIf);
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
+        } catch (Exception ex) {
+            logger.error("Creation of vpninterface {} failed due to {}", name, ex);
+        } finally {
+            NeutronvpnUtils.unlockVpnInterface(lockManager, name);
+        }
+    }
+
+    private void deleteVpnInterface(Port port) {
+
+        if (port != null) {
+            String pname = NeutronvpnUtils.uuidToTapPortName(port.getUuid());
+            String name = new StringBuilder(pname).append(":0").toString();
+            InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
+                    child(VpnInterface.class, new VpnInterfaceKey(name)).build();
+
+            NeutronvpnUtils.lockVpnInterface(lockManager, name);
+            try {
+                logger.debug("Deleting vpn interface {}", name);
+                MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
+            } catch (Exception ex) {
+                logger.error("Deletion of vpninterface {} failed due to {}", name, ex);
+            } finally {
+                NeutronvpnUtils.unlockVpnInterface(lockManager, name);
+            }
+        }
+    }
+
+    // adds port to subnet list and creates vpnInterface
+    private Uuid addPortToSubnets(Port port) {
+        Uuid subnetId = null;
+        Uuid vpnId = null;
+        String name = NeutronvpnUtils.uuidToTapPortName(port.getUuid());
+
+        // find all Subnets to which this port is associated,
+        List<FixedIps> ips = port.getFixedIps();
+        for (FixedIps ip : ips) {
+            String ipValue = ip.getIpAddress().getIpv4Address().getValue();
+
+            InstanceIdentifier id = NeutronvpnUtils.buildFixedIpToPortNameIdentifier(ipValue);
+            PortFixedipToPortNameBuilder builder = new PortFixedipToPortNameBuilder().setPortFixedip(ipValue)
+                    .setPortName(name);
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, id, builder.build());
+            logger.debug("fixedIp-name map for neutron port with fixedIp: {}, name: {} added to NeutronPortData DS",
+                    ipValue, name);
+
+            subnetId = ip.getSubnetId();
+            Subnetmap subnetmap = updateSubnetNode(subnetId, null, null, null, null, port.getUuid());
+            if (vpnId == null && subnetmap != null) {
+                vpnId = subnetmap.getVpnId();
+            }
+        }
+        return vpnId;
+    }
+
+    private Uuid removePortFromSubnets(Port port) {
+        Uuid subnetId = null;
+        Uuid vpnId = null;
+
+        // find all Subnets to which this port is associated,
+        List<FixedIps> ips = port.getFixedIps();
+        for (FixedIps ip : ips) {
+            String ipValue = ip.getIpAddress().getIpv4Address().getValue();
+
+            InstanceIdentifier id = NeutronvpnUtils.buildFixedIpToPortNameIdentifier(ipValue);
+            MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, id);
+            logger.debug("fixedIp-name map for neutron port with fixedIp: {} deleted from NeutronPortData DS",
+                    ipValue);
+
+            subnetId = ip.getSubnetId();
+            Subnetmap subnetmap = removeFromSubnetNode(subnetId, null, null, null, port.getUuid());
+            if (vpnId == null && subnetmap != null) {
+                vpnId = subnetmap.getVpnId();
+            }
+        }
+        return vpnId;
+    }
+
+    protected void handleNeutronPortCreated(Port port) {
+        logger.info("Of-port-interface creation");
+        int portVlanId = NeutronvpnUtils.getVlanFromNeutronPort(port);
+        // Create of-port interface for this neutron port
+        createOfPortInterface(port, portVlanId);
+        logger.debug("Add port to subnet");
+        // add port to local Subnets DS
+        Uuid vpnId = addPortToSubnets(port);
+
+        if (vpnId != null) {
+            // create vpn-interface on this neutron port
+            logger.debug("Adding VPN Interface");
+            createVpnInterface(vpnId, port);
+        }
+    }
+
+    protected void handleNeutronPortDeleted(Port port) {
+        logger.debug("Of-port-interface removal");
+        logger.debug("Remove port from subnet");
+        // remove port from local Subnets DS
+        Uuid vpnId = removePortFromSubnets(port);
+
+        if (vpnId != null) {
+            // remove vpn-interface for this neutron port
+            logger.debug("removing VPN Interface");
+            deleteVpnInterface(port);
+        }
+        int portVlanId = NeutronvpnUtils.getVlanFromNeutronPort(port);
+        // Remove of-port interface for this neutron port
+        deleteOfPortInterface(port, portVlanId);
+
+    }
+
+    protected void handleNeutronPortUpdated(Port portoriginal, Port portupdate) {
+        logger.debug("Add port to subnet");
+        // add port FixedIPs to local Subnets DS
+        Uuid vpnIdup = addPortToSubnets(portupdate);
+
+        if (vpnIdup != null) {
+            createVpnInterface(vpnIdup, portupdate);
+        }
+
+        // remove port FixedIPs from local Subnets DS
+        Uuid vpnIdor = removePortFromSubnets(portoriginal);
+
+        if (vpnIdor != null) {
+            deleteVpnInterface(portoriginal);
+        }
+    }
+
+    public void createL3Vpn(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) {
+            associateRouterToVpn(vpn, router);
+        }
+        if (networks != null) {
+            associateNetworksToVpn(vpn, networks);
+        }
+    }
+
+    @Override
+    public Future<RpcResult<CreateL3VPNOutput>> createL3VPN(CreateL3VPNInput input) {
+
+        CreateL3VPNOutputBuilder opBuilder = new CreateL3VPNOutputBuilder();
+        SettableFuture<RpcResult<CreateL3VPNOutput>> result = SettableFuture.create();
+        List<RpcError> errorList = new ArrayList<RpcError>();
+        int failurecount = 0;
+        int warningcount = 0;
+
+        List<L3vpn> vpns = input.getL3vpn();
+        for (L3vpn vpn : vpns) {
+            RpcError error;
+            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",
+                        vpn.getId().getValue());
+                logger.warn(msg);
+                error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
+                errorList.add(error);
+                warningcount++;
+                continue;
+            }
+            if (vpn.getRouteDistinguisher().size() > 1) {
+                msg = String.format("Creation of L3VPN failed for VPN %s due to multiple RD input %s",
+                        vpn.getId().getValue(), vpn.getRouteDistinguisher());
+                logger.warn(msg);
+                error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
+                errorList.add(error);
+                warningcount++;
+                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());
+                error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
+                errorList.add(error);
+                failurecount++;
+            }
+        }
+        // if at least one succeeds; result is success
+        // if none succeeds; result is failure
+        if (failurecount + warningcount == vpns.size()) {
+            result.set(RpcResultBuilder.<CreateL3VPNOutput>failed().withRpcErrors(errorList).build());
+        } else {
+            List<String> errorResponseList = new ArrayList<>();
+            if (!errorList.isEmpty()) {
+                for (RpcError rpcError : errorList) {
+                    String errorResponse = String.format("ErrorType: " + rpcError.getErrorType() + ", " + "ErrorTag: " +
+                            rpcError.getTag() + ", " + "ErrorMessage: " + rpcError.getMessage());
+                    errorResponseList.add(errorResponse);
+                }
+            } else {
+                errorResponseList.add("Operation successful with no errors");
+            }
+            opBuilder.setResponse(errorResponseList);
+            result.set(RpcResultBuilder.<CreateL3VPNOutput>success().withResult(opBuilder.build()).build());
+        }
+        return result;
+    }
+
+    @Override
+    public Future<RpcResult<GetL3VPNOutput>> getL3VPN(GetL3VPNInput input) {
+
+        GetL3VPNOutputBuilder opBuilder = new GetL3VPNOutputBuilder();
+        SettableFuture<RpcResult<GetL3VPNOutput>> result = SettableFuture.create();
+        Uuid inputVpnId = input.getId();
+        List<VpnInstance> vpns = new ArrayList<VpnInstance>();
+
+        try {
+            if (inputVpnId == null) {
+                // get all vpns
+                InstanceIdentifier<VpnInstances> vpnsIdentifier =
+                        InstanceIdentifier.builder(VpnInstances.class).build();
+                Optional<VpnInstances> optionalVpns = read(LogicalDatastoreType.CONFIGURATION, vpnsIdentifier);
+                if (optionalVpns.isPresent()) {
+                    for (VpnInstance vpn : optionalVpns.get().getVpnInstance()) {
+                        vpns.add(vpn);
+                    }
+                } else {
+                    // No VPN present
+                    result.set(RpcResultBuilder.<GetL3VPNOutput>failed()
+                            .withWarning(ErrorType.PROTOCOL, "", "No VPN is present").build());
+                    return result;
+                }
+            } else {
+                String name = inputVpnId.getValue();
+                InstanceIdentifier<VpnInstance> vpnIdentifier =
+                        InstanceIdentifier.builder(VpnInstances.class)
+                                .child(VpnInstance.class, new VpnInstanceKey(name)).build();
+                // read VpnInstance Info
+                Optional<VpnInstance> optionalVpn = read(LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
+                if (optionalVpn.isPresent()) {
+                    vpns.add(optionalVpn.get());
+                } else {
+                    String message = String.format("GetL3VPN failed because VPN %s is not present", name);
+                    logger.error(message);
+                    result.set(RpcResultBuilder.<GetL3VPNOutput>failed()
+                            .withWarning(ErrorType.PROTOCOL, "invalid-value", message).build());
+                }
+            }
+            List<L3vpnInstances> l3vpnList = new ArrayList<L3vpnInstances>();
+            for (VpnInstance vpnInstance : vpns) {
+                Uuid vpnId = new Uuid(vpnInstance.getVpnInstanceName());
+                // create VpnMaps id
+                InstanceIdentifier<VpnMap> vpnMapIdentifier =
+                        InstanceIdentifier.builder(VpnMaps.class)
+                                .child(VpnMap.class, new VpnMapKey(vpnId)).build();
+                L3vpnInstancesBuilder l3vpn = new L3vpnInstancesBuilder();
+
+                List<String> rd = Arrays.asList(vpnInstance.getIpv4Family().getRouteDistinguisher().split(","));
+                List<VpnTarget> vpnTargetList = vpnInstance.getIpv4Family().getVpnTargets().getVpnTarget();
+
+                List<String> ertList = new ArrayList<String>();
+                List<String> irtList = new ArrayList<String>();
+
+                for (VpnTarget vpnTarget : vpnTargetList) {
+                    if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ExportExtcommunity) {
+                        ertList.add(vpnTarget.getVrfRTValue());
+                    }
+                    if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ImportExtcommunity) {
+                        irtList.add(vpnTarget.getVrfRTValue());
+                    }
+                    if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.Both) {
+                        ertList.add(vpnTarget.getVrfRTValue());
+                        irtList.add(vpnTarget.getVrfRTValue());
+                    }
+                }
+
+                l3vpn.setId(vpnId).setRouteDistinguisher(rd).setImportRT(irtList).setExportRT(ertList);
+                Optional<VpnMap> optionalVpnMap =
+                        read(LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
+                if (optionalVpnMap.isPresent()) {
+                    VpnMap vpnMap = optionalVpnMap.get();
+                    l3vpn.setRouterId(vpnMap.getRouterId()).setNetworkIds(vpnMap.getNetworkIds())
+                            .setTenantId(vpnMap.getTenantId()).setName(vpnMap.getName());
+                }
+                l3vpnList.add(l3vpn.build());
+            }
+
+            opBuilder.setL3vpnInstances(l3vpnList);
+            result.set(RpcResultBuilder.<GetL3VPNOutput>success().withResult(opBuilder.build()).build());
+
+        } catch (Exception ex) {
+            String message = String.format("GetL3VPN failed due to %s", ex.getMessage());
+            logger.error(message);
+            result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withError(ErrorType.APPLICATION, message).build());
+        }
+
+        return result;
+    }
+
+    @Override
+    public Future<RpcResult<DeleteL3VPNOutput>> deleteL3VPN(DeleteL3VPNInput input) {
+
+        DeleteL3VPNOutputBuilder opBuilder = new DeleteL3VPNOutputBuilder();
+        SettableFuture<RpcResult<DeleteL3VPNOutput>> result = SettableFuture.create();
+        List<RpcError> errorList = new ArrayList<RpcError>();
+
+        int failurecount = 0;
+        int warningcount = 0;
+        List<Uuid> vpns = input.getId();
+        for (Uuid vpn : vpns) {
+            RpcError error;
+            String msg;
+            try {
+                InstanceIdentifier<VpnInstance> vpnIdentifier =
+                        InstanceIdentifier.builder(VpnInstances.class)
+                                .child(VpnInstance.class, new VpnInstanceKey(vpn.getValue())).build();
+                Optional<VpnInstance> optionalVpn = read(LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
+                if (optionalVpn.isPresent()) {
+                    removeL3Vpn(vpn);
+                } else {
+                    msg = String.format("VPN with vpnid: %s does not exist", vpn.getValue());
+                    logger.warn(msg);
+                    error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-value", msg);
+                    errorList.add(error);
+                    warningcount++;
+                }
+            } catch (Exception ex) {
+                msg = String.format("Deletion of L3VPN failed when deleting for uuid %s", vpn.getValue());
+                logger.error(msg, ex.getMessage());
+                error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
+                errorList.add(error);
+                failurecount++;
+            }
+        }
+        // if at least one succeeds; result is success
+        // if none succeeds; result is failure
+        if (failurecount + warningcount == vpns.size()) {
+            result.set(RpcResultBuilder.<DeleteL3VPNOutput>failed().withRpcErrors(errorList).build());
+        } else {
+            List<String> errorResponseList = new ArrayList<>();
+            if (!errorList.isEmpty()) {
+                for (RpcError rpcError : errorList) {
+                    String errorResponse = String.format("ErrorType: " + rpcError.getErrorType() + ", " + "ErrorTag: " +
+                            rpcError.getTag() + ", " + "ErrorMessage: " + rpcError.getMessage());
+                    errorResponseList.add(errorResponse);
+                }
+            } else {
+                errorResponseList.add("Operation successful with no errors");
+            }
+            opBuilder.setResponse(errorResponseList);
+            result.set(RpcResultBuilder.<DeleteL3VPNOutput>success().withResult(opBuilder.build()).build());
+        }
+        return result;
+    }
+
+    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);
+        // 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));
+            }
+        }
+    }
+
+    protected List<Adjacency> addAdjacencyforExtraRoute(List<String> routeList, boolean rtrUp, String vpnifname) {
+        try {
+            List<Adjacency> adjList = new ArrayList<Adjacency>();
+            for (String route : routeList) {
+                // assuming extra route is strictly in the format "nexthop destination" > "10.1.1.10 40.0.1.0/24"
+                String[] parts = route.split(" ");
+                if (parts.length == 2) {
+                    String nextHop = parts[0];
+                    String destination = parts[1];
+
+                    String tapPortName = NeutronvpnUtils.getNeutronPortNamefromPortFixedIp(broker, nextHop);
+                    String ifname = new StringBuilder(tapPortName).append(":0").toString();
+                    logger.trace("Adding extra route with nexthop {}, destination {}, ifName {}", nextHop,
+                            destination, ifname);
+                    Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination).setNextHopIp(nextHop).setKey
+                            (new AdjacencyKey(destination)).build();
+                    if (rtrUp == false) {
+                        if (ifname.equals(vpnifname)) {
+                            adjList.add(erAdj);
+                        }
+                        continue;
+                    }
+                    InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
+                            child(VpnInterface.class, new VpnInterfaceKey(ifname)).build();
+                    Optional<VpnInterface> optionalVpnInterface = read(LogicalDatastoreType.CONFIGURATION,
+                            vpnIfIdentifier);
+                    if (optionalVpnInterface.isPresent()) {
+                        Adjacencies erAdjs = new AdjacenciesBuilder().setAdjacency(Arrays.asList(erAdj)).build();
+                        VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(ifname))
+                                .addAugmentation(Adjacencies.class, erAdjs).build();
+                        MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
+                        logger.trace("extra route {} added successfully", route);
+                    } else {
+                        logger.error("VM adjacency for interface {} not present ; cannot add extra route adjacency",
+                                ifname);
+                    }
+                } else {
+                    logger.error("Incorrect input received for extra route. {}", parts);
+                }
+            }
+            return adjList;
+        } catch (Exception e) {
+            logger.error("exception in adding extra route: {}" + e);
+        }
+        return null;
+    }
+
+    protected void removeAdjacencyforExtraRoute(List<String> routeList) {
+        try {
+            for (String route : routeList) {
+                // assuming extra route is strictly in the format "nexthop destination" > "10.1.1.10 40.0.1.0/24"
+                String[] parts = route.split(" ");
+                if (parts.length == 2) {
+                    String nextHop = parts[0];
+                    String destination = parts[1];
+
+                    String tapPortName = NeutronvpnUtils.getNeutronPortNamefromPortFixedIp(broker, nextHop);
+                    String ifname = new StringBuilder(tapPortName).append(":0").toString();
+                    logger.trace("Removing extra route with nexthop {}, destination {}, ifName {}", nextHop,
+                            destination, ifname);
+                    InstanceIdentifier<Adjacency> adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class).
+                            child(VpnInterface.class, new VpnInterfaceKey(ifname)).augmentation(Adjacencies.class)
+                            .child(Adjacency.class, new AdjacencyKey(destination)).build();
+                    MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
+                    logger.trace("extra route {} deleted successfully", route);
+                } else {
+                    logger.error("Incorrect input received for extra route. {}", parts);
+                }
+            }
+        } catch (Exception e) {
+            logger.error("exception in deleting extra route: {}" + e);
+        }
+    }
+
+    protected void addPortToVpn(Uuid vpnId, Uuid port) {
+        logger.debug("Adding Port to vpn node...");
+        createVpnInterface(vpnId, getNeutronPort(port));
+    }
+
+    protected void removeL3Vpn(Uuid id) {
+        // read VPN networks
+        VpnMap vpnMap = NeutronvpnUtils.getVpnMap(broker, id);
+        Uuid router = vpnMap.getRouterId();
+        // dissociate router
+        if (router != null) {
+            dissociateRouterFromVpn(id, router);
+        }
+        // dissociate networks
+        if (!id.equals(router)) {
+            dissociateNetworksFromVpn(id, vpnMap.getNetworkIds());
+        }
+        // remove entire vpnMaps node
+        deleteVpnMapsNode(id);
+
+        // remove vpn-instance
+        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);
+        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));
+                }
+            }
+            // update subnet-vpn association
+            removeFromSubnetNode(subnet, null, null, vpnId, null);
+        } else {
+            logger.warn("Subnetmap for subnet {} not found", subnet.getValue());
+        }
+    }
+
+    protected void associateRouterToVpn(Uuid vpn, Uuid router) {
+
+        // remove existing Router-VPN
+        if (!vpn.equals(router)) {
+            removeL3Vpn(router);
+        }
+        updateVpnMaps(vpn, null, router, null, null);
+
+        List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, router);
+        logger.debug("Adding subnets...");
+        for (Uuid subnet : routerSubnets) {
+            addSubnetToVpn(vpn, subnet);
+        }
+    }
+
+    protected void dissociateRouterFromVpn(Uuid vpn, Uuid router) {
+        clearFromVpnMaps(vpn, router, null);
+
+        // fetching sn from SubnetmapDS for internal VPN because sn already deleted from RouterIf DS on router deletion
+        List<Uuid> routerSubnets = (vpn.equals(router)) ? getSubnetsforVpn(vpn) :
+                NeutronvpnUtils.getNeutronRouterSubnetIds(broker, router);
+
+        logger.debug("dissociateRouter vpn {} router {} Removing subnets...", vpn.getValue(), router.getValue());
+        if (routerSubnets != null) {
+            for (Uuid subnet : routerSubnets) {
+                removeSubnetFromVpn(vpn, subnet);
+            }
+        }
+        // create Router-VPN for this router
+        if (!vpn.equals(router)) {
+            logger.debug("Re-creating vpn-router...");
+            createL3Vpn(router, null, null, null, null, null, router, null);
+        }
+    }
+
+    protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
+        List<String> failed = new ArrayList<String>();
+        if (!networks.isEmpty()) {
+            // store in Data Base
+            updateVpnMaps(vpn, null, null, null, networks);
+            // process corresponding subnets for VPN
+            for (Uuid nw : networks) {
+                if (NeutronvpnUtils.getNeutronNetwork(broker, nw) == null) {
+                    failed.add(nw.getValue());
+                } else {
+                    List<Uuid> networkSubnets = NeutronvpnUtils.getNeutronNetworkSubnetIds(broker, nw);
+                    logger.debug("Adding network subnets...");
+                    if (networkSubnets != null) {
+                        for (Uuid subnet : networkSubnets) {
+                            addSubnetToVpn(vpn, subnet);
+                        }
+                    }
+                }
+            }
+        }
+        return failed;
+    }
+
+    protected List<String> dissociateNetworksFromVpn(Uuid vpn, List<Uuid> networks) {
+        List<String> failed = new ArrayList<String>();
+        if (networks != null && !networks.isEmpty()) {
+            // store in Data Base
+            clearFromVpnMaps(vpn, null, networks);
+            // process corresponding subnets for VPN
+            for (Uuid nw : networks) {
+                if (NeutronvpnUtils.getNeutronNetwork(broker, nw) == null) {
+                    failed.add(nw.getValue());
+                } else {
+                    List<Uuid> networkSubnets = NeutronvpnUtils.getNeutronNetworkSubnetIds(broker, nw);
+                    logger.debug("Removing network subnets...");
+                    for (Uuid subnet : networkSubnets) {
+                        removeSubnetFromVpn(vpn, subnet);
+                    }
+                }
+            }
+        }
+        return failed;
+    }
+
+    @Override
+    public Future<RpcResult<AssociateNetworksOutput>> associateNetworks(AssociateNetworksInput input) {
+
+        AssociateNetworksOutputBuilder opBuilder = new AssociateNetworksOutputBuilder();
+        SettableFuture<RpcResult<AssociateNetworksOutput>> result = SettableFuture.create();
+        logger.debug("associateNetworks {}", input);
+        StringBuilder returnMsg = new StringBuilder();
+        Uuid vpnId = input.getVpnId();
+
+        try {
+            if (NeutronvpnUtils.getVpnMap(broker, vpnId) != null) {
+                List<Uuid> netIds = input.getNetworkId();
+                if (netIds != null && !netIds.isEmpty()) {
+                    List<String> failed = associateNetworksToVpn(vpnId, netIds);
+                    if (!failed.isEmpty()) {
+                        returnMsg.append("network(s) not found : ").append(failed);
+                    }
+                }
+            } else {
+                returnMsg.append("VPN not found : ").append(vpnId.getValue());
+            }
+            if (returnMsg.length() != 0) {
+                String message = String.format("associate Networks to vpn %s failed due to %s", vpnId.getValue(),
+                        returnMsg);
+                logger.error(message);
+                String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: " +
+                        message);
+                opBuilder.setResponse(errorResponse);
+                result.set(RpcResultBuilder.<AssociateNetworksOutput>success().withResult(opBuilder.build()).build());
+            } else {
+                result.set(RpcResultBuilder.<AssociateNetworksOutput>success().build());
+            }
+        } catch (Exception ex) {
+            String message = String.format("associate Networks to vpn %s failed due to %s", input.getVpnId().getValue(),
+                    ex.getMessage());
+            logger.error(message);
+            result.set(RpcResultBuilder.<AssociateNetworksOutput>failed().withError(ErrorType.APPLICATION, message)
+                    .build());
+        }
+        logger.debug("associateNetworks returns..");
+        return result;
+    }
+
+    @Override
+    public Future<RpcResult<Void>> associateRouter(AssociateRouterInput input) {
+
+        SettableFuture<RpcResult<Void>> result = SettableFuture.create();
+        logger.debug("associateRouter {}", input);
+        StringBuilder returnMsg = new StringBuilder();
+        Uuid vpnId = input.getVpnId();
+        Uuid routerId = input.getRouterId();
+        try {
+            if (routerId != null && vpnId != null) {
+                Router rtr = NeutronvpnUtils.getNeutronRouter(broker, routerId);
+                VpnMap vpnMap = NeutronvpnUtils.getVpnMap(broker, vpnId);
+                if (rtr != null && vpnMap != null) {
+                    if (vpnMap.getRouterId() != null) {
+                        returnMsg.append("vpn ").append(vpnId.getValue()).append(" already associated to router ")
+                                .append(vpnMap.getRouterId().getValue());
+                    } else {
+                        associateRouterToVpn(vpnId, routerId);
+                    }
+                } else {
+                    returnMsg.append("router not found : ").append(routerId.getValue());
+                }
+            } else {
+                returnMsg.append("VPN not found : ").append(vpnId.getValue());
+            }
+            if (returnMsg.length() != 0) {
+                String message = String.format("associate router to vpn %s failed due to %s", routerId.getValue(),
+                        returnMsg);
+                logger.error(message);
+                result.set(RpcResultBuilder.<Void>failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
+                        .build());
+            } else {
+                result.set(RpcResultBuilder.<Void>success().build());
+            }
+        } 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);
+            result.set(RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION, message).build());
+        }
+        logger.debug("associateRouter returns..");
+        return result;
+    }
+
+    @Override
+    public Future<RpcResult<DissociateNetworksOutput>> dissociateNetworks(DissociateNetworksInput input) {
+
+        DissociateNetworksOutputBuilder opBuilder = new DissociateNetworksOutputBuilder();
+        SettableFuture<RpcResult<DissociateNetworksOutput>> result = SettableFuture.create();
+
+        logger.debug("dissociateNetworks {}", input);
+        StringBuilder returnMsg = new StringBuilder();
+        Uuid vpnId = input.getVpnId();
+
+        try {
+            if (NeutronvpnUtils.getVpnMap(broker, vpnId) != null) {
+                List<Uuid> netIds = input.getNetworkId();
+                if (netIds != null && !netIds.isEmpty()) {
+                    List<String> failed = dissociateNetworksFromVpn(vpnId, netIds);
+                    if (!failed.isEmpty()) {
+                        returnMsg.append("netowrk(s) not found : ").append(failed);
+                    }
+                }
+            } else {
+                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(),
+                        returnMsg);
+                logger.error(message);
+                String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: " +
+                        message);
+                opBuilder.setResponse(errorResponse);
+                result.set(RpcResultBuilder.<DissociateNetworksOutput>success().withResult(opBuilder.build()).build());
+            } else {
+                result.set(RpcResultBuilder.<DissociateNetworksOutput>success().build());
+            }
+        } catch (Exception ex) {
+            String message = String.format("dissociate Networks to vpn %s failed due to %s", input.getVpnId().
+                    getValue(), ex.getMessage());
+            logger.error(message);
+            result.set(RpcResultBuilder.<DissociateNetworksOutput>failed().withError(ErrorType.APPLICATION, message)
+                    .build());
+        }
+        logger.debug("dissociateNetworks returns..");
+        return result;
+    }
+
+    @Override
+    public Future<RpcResult<Void>> dissociateRouter(DissociateRouterInput input) {
+
+        SettableFuture<RpcResult<Void>> result = SettableFuture.create();
+
+        logger.debug("dissociateRouter {}", input);
+        StringBuilder returnMsg = new StringBuilder();
+        Uuid vpnId = input.getVpnId();
+        Uuid routerId = input.getRouterId();
+        try {
+            if (NeutronvpnUtils.getVpnMap(broker, vpnId) != null) {
+                if (routerId != null) {
+                    Router rtr = NeutronvpnUtils.getNeutronRouter(broker, routerId);
+                    if (rtr != null) {
+                        dissociateRouterFromVpn(vpnId, routerId);
+                    } else {
+                        returnMsg.append("router not found : ").append(routerId.getValue());
+                    }
+                }
+            } else {
+                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(),
+                        vpnId.getValue(), returnMsg);
+                logger.error(message);
+                String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: " +
+                        message);
+                result.set(RpcResultBuilder.<Void>failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
+                        .build());
+            } else {
+                result.set(RpcResultBuilder.<Void>success().build());
+            }
+        } 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);
+            result.set(RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION, message).build());
+        }
+        logger.debug("dissociateRouter returns..");
+
+        return result;
+    }
+
+    private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
+
+        ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
+
+        Optional<T> result = Optional.absent();
+        try {
+            result = tx.read(datastoreType, path).get();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        return result;
+    }
+
+    protected Subnet getNeutronSubnet(Uuid subnetId) {
+        InstanceIdentifier<Subnet> inst = InstanceIdentifier.create(Neutron.class).
+                child(Subnets.class).child(Subnet.class, new SubnetKey(subnetId));
+        Optional<Subnet> sn = read(LogicalDatastoreType.CONFIGURATION, inst);
+
+        if (sn.isPresent()) {
+            return sn.get();
+        }
+        return null;
+    }
+
+    protected IpAddress getNeutronSubnetGateway(Uuid subnetId) {
+        Subnet sn = getNeutronSubnet(subnetId);
+        if (null != sn) {
+            return sn.getGatewayIp();
+        }
+        return null;
+    }
+
+    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 = read(LogicalDatastoreType.CONFIGURATION, pid);
+            if (optPort.isPresent()) {
+                return optPort.get();
+            }
+        } else {
+            logger.error("Port {} not Found!!", name);
+        }
+        return null;
+    }
+
+    protected Port getNeutronPort(Uuid portId) {
+        InstanceIdentifier<Port> pid = InstanceIdentifier.create(Neutron.class).
+                child(Ports.class).child(Port.class, new PortKey(portId));
+        Optional<Port> optPort = read(LogicalDatastoreType.CONFIGURATION, pid);
+        if (optPort.isPresent()) {
+            return optPort.get();
+        }
+        return null;
+    }
+
+    protected List<Uuid> getSubnetsforVpn(Uuid vpnid) {
+        List<Uuid> subnets = new ArrayList<Uuid>();
+        //read subnetmaps
+        InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
+        Optional<Subnetmaps> subnetmaps = read(LogicalDatastoreType.CONFIGURATION, subnetmapsid);
+        if (subnetmaps.isPresent()) {
+            Subnetmaps smaps = subnetmaps.get();
+            List<Subnetmap> subnetMapList = smaps.getSubnetmap();
+            for (Subnetmap subnetMap : subnetMapList) {
+                if (subnetMap.getVpnId() != null && subnetMap.getVpnId().equals(vpnid)) {
+                    subnets.add(subnetMap.getId());
+                }
+            }
+        }
+        return subnets;
+    }
+
+    public List<String> showNeutronPortsCLI() {
+        List<String> result = new ArrayList<String>();
+        result.add(String.format(" %-22s  %-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 = read(LogicalDatastoreType.CONFIGURATION, portidentifier);
+            if (ports.isPresent()) {
+                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(), getIPPrefixFromPort(port)));
+                }
+            }
+        } catch (Exception e) {
+            logger.trace("Failed to retrieve neutronPorts info : ", e);
+            System.out.println("Failed to retrieve neutronPorts info : " + e.getMessage());
+        }
+        return result;
+    }
+
+    private Short getIPPrefixFromPort(Port port) {
+        Short prefix = new Short((short) 0);
+        String cidr = "";
+        try {
+            Uuid subnetUUID = port.getFixedIps().get(0).getSubnetId();
+
+            org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets
+                    .SubnetKey subnetkey = new org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets
+                    .rev150712.subnets.attributes.subnets.SubnetKey(subnetUUID);
+            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets
+                    .attributes.subnets.Subnet> subnetidentifier = InstanceIdentifier.create(Neutron.class).child(org
+                    .opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets
+                    .class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets
+                    .attributes.subnets.Subnet.class, subnetkey);
+            Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes
+                    .subnets.Subnet> subnet = read(LogicalDatastoreType.CONFIGURATION, subnetidentifier);
+
+            if (subnet.isPresent()) {
+                cidr = subnet.get().getCidr();
+                // Extract the prefix length from cidr
+                String[] parts = cidr.split("/");
+                if ((parts.length == 2)) {
+                    prefix = Short.valueOf(parts[1]);
+                    return prefix;
+                } else {
+                    logger.trace("Could not retrieve prefix from subnet CIDR");
+                    System.out.println("Could not retrieve prefix from subnet CIDR");
+                }
+            } else {
+                logger.trace("Unable to read on subnet datastore");
+            }
+        } catch (Exception e) {
+            logger.trace("Failed to retrieve IP prefix from port : ", e);
+            System.out.println("Failed to retrieve IP prefix from port : " + e.getMessage());
+        }
+        return null;
+    }
+
+    public List<String> showVpnConfigCLI(Uuid vpnuuid) {
+        List<String> result = new ArrayList<String>();
+        if (vpnuuid == null) {
+            System.out.println("");
+            System.out.println("Displaying VPN config for all VPNs");
+            System.out.println("To display VPN config for a particular VPN, use the following syntax");
+            System.out.println(getshowVpnConfigCLIHelp());
+        }
+        try {
+            RpcResult<GetL3VPNOutput> rpcResult = getL3VPN(new GetL3VPNInputBuilder().setId(vpnuuid).build()).get();
+            if (rpcResult.isSuccessful()) {
+                result.add("");
+                result.add(String.format(" %-37s %-37s %-7s ", "VPN ID", "Tenant ID", "RD"));
+                result.add("");
+                result.add(String.format(" %-80s ", "Import-RTs"));
+                result.add("");
+                result.add(String.format(" %-80s ", "Export-RTs"));
+                result.add("");
+                result.add(String.format(" %-76s ", "Subnet IDs"));
+                result.add("");
+                result.add("------------------------------------------------------------------------------------");
+                result.add("");
+                List<L3vpnInstances> VpnList = rpcResult.getResult().getL3vpnInstances();
+                for (L3vpnInstance Vpn : VpnList) {
+                    String tenantId = Vpn.getTenantId() != null ? Vpn.getTenantId().getValue() : "\"                 " +
+                            "                  \"";
+                    result.add(String.format(" %-37s %-37s %-7s ", Vpn.getId().getValue(), tenantId, Vpn
+                            .getRouteDistinguisher()));
+                    result.add("");
+                    result.add(String.format(" %-80s ", Vpn.getImportRT()));
+                    result.add("");
+                    result.add(String.format(" %-80s ", Vpn.getExportRT()));
+                    result.add("");
+
+                    Uuid vpnid = Vpn.getId();
+                    List<Uuid> subnetList = getSubnetsforVpn(vpnid);
+                    if (!subnetList.isEmpty()) {
+                        for (Uuid subnetuuid : subnetList) {
+                            result.add(String.format(" %-76s ", subnetuuid.getValue()));
+                        }
+                    } else {
+                        result.add(String.format(" %-76s ", "\"                                    \""));
+                    }
+                    result.add("");
+                    result.add("----------------------------------------");
+                    result.add("");
+                }
+            } else {
+                String errortag = rpcResult.getErrors().iterator().next().getTag();
+                if (errortag == "") {
+                    System.out.println("");
+                    System.out.println("No VPN has been configured yet");
+                } else if (errortag == "invalid-value") {
+                    System.out.println("");
+                    System.out.println("VPN " + vpnuuid.getValue() + " is not present");
+                } else {
+                    System.out.println("error getting VPN info : " + rpcResult.getErrors());
+                    System.out.println(getshowVpnConfigCLIHelp());
+                }
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            logger.trace("error getting VPN info : ", e);
+            System.out.println("error getting VPN info : " + e.getMessage());
+        }
+        return result;
+    }
+
+    private String getshowVpnConfigCLIHelp() {
+        StringBuilder help = new StringBuilder("Usage:");
+        help.append("display vpn-config [-vid/--vpnid <id>]");
+        return help.toString();
+    }
+
+}
diff --git a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnProvider.java b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnProvider.java
new file mode 100644 (file)
index 0000000..ccfc14e
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.neutronvpn;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.vpnservice.neutronvpn.interfaces.INeutronVpnManager;
+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.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.LockManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NeutronvpnService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+public class NeutronvpnProvider implements BindingAwareProvider, INeutronVpnManager, AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronvpnProvider.class);
+    private NeutronvpnManager nvManager;
+    private IMdsalApiManager mdsalManager;
+    private LockManagerService lockManager;
+    private NeutronBgpvpnChangeListener bgpvpnListener;
+    private NeutronNetworkChangeListener networkListener;
+    private NeutronSubnetChangeListener subnetListener;
+    private NeutronRouterChangeListener routerListener;
+    private NeutronPortChangeListener portListener;
+    private RpcProviderRegistry rpcProviderRegistry;
+
+    public NeutronvpnProvider(RpcProviderRegistry rpcRegistry) {
+        this.rpcProviderRegistry = rpcRegistry;
+    }
+
+    public RpcProviderRegistry getRpcProviderRegistry() {
+        return rpcProviderRegistry;
+    }
+
+    public void setRpcProviderRegistry(RpcProviderRegistry rpcProviderRegistry) {
+        this.rpcProviderRegistry = rpcProviderRegistry;
+    }
+
+    public void setMdsalManager(IMdsalApiManager mdsalManager) {
+        this.mdsalManager = mdsalManager;
+    }
+
+    public void setLockManager(LockManagerService lockManager) {
+        this.lockManager = lockManager;
+    }
+
+    @Override
+    public void onSessionInitiated(ProviderContext session) {
+        try {
+            final DataBroker dbx = session.getSALService(DataBroker.class);
+            nvManager = new NeutronvpnManager(dbx, mdsalManager);
+            final BindingAwareBroker.RpcRegistration<NeutronvpnService> rpcRegistration =
+                    getRpcProviderRegistry().addRpcImplementation(NeutronvpnService.class, nvManager);
+            bgpvpnListener = new NeutronBgpvpnChangeListener(dbx, nvManager);
+            networkListener = new NeutronNetworkChangeListener(dbx, nvManager);
+            subnetListener = new NeutronSubnetChangeListener(dbx, nvManager);
+            routerListener = new NeutronRouterChangeListener(dbx, nvManager);
+            portListener = new NeutronPortChangeListener(dbx, nvManager);
+            nvManager.setLockManager(lockManager);
+
+            LOG.info("NeutronvpnProvider Session Initiated");
+        } catch (Exception e) {
+            LOG.error("Error initializing services", e);
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+        portListener.close();
+        subnetListener.close();
+        routerListener.close();
+        networkListener.close();
+        bgpvpnListener.close();
+        nvManager.close();
+        LOG.info("NeutronvpnProvider Closed");
+    }
+
+    @Override
+    public List<String> showNeutronPortsCLI() {
+        return nvManager.showNeutronPortsCLI();
+    }
+
+    @Override
+    public List<String> showVpnConfigCLI(Uuid vuuid) {
+        return nvManager.showVpnConfigCLI(vuuid);
+    }
+
+    @Override
+    public void addSubnetToVpn(Uuid vpnId, Uuid subnet) {
+        nvManager.addSubnetToVpn(vpnId, subnet);
+    }
+
+    @Override
+    public List<Uuid> getSubnetsforVpn(Uuid vpnid) {
+        return nvManager.getSubnetsforVpn(vpnid);
+    }
+
+    @Override
+    public void removeSubnetFromVpn(Uuid vpnId, Uuid subnet) {
+        nvManager.removeSubnetFromVpn(vpnId, subnet);
+    }
+
+    @Override
+    public Port getNeutronPort(String name) {
+        return nvManager.getNeutronPort(name);
+    }
+
+    @Override
+    public Subnet getNeutronSubnet(Uuid subnetId) {
+        return nvManager.getNeutronSubnet(subnetId);
+    }
+
+    @Override
+    public String uuidToTapPortName(Uuid id) {
+        return NeutronvpnUtils.uuidToTapPortName(id);
+    }
+
+    @Override
+    public Port getNeutronPort(Uuid portId) {
+        return nvManager.getNeutronPort(portId);
+    }
+
+    @Override
+    public IpAddress getNeutronSubnetGateway(Uuid subnetId) {
+        return nvManager.getNeutronSubnetGateway(subnetId);
+    }
+
+}
diff --git a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnUtils.java b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnUtils.java
new file mode 100644 (file)
index 0000000..12bd658
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.neutronvpn;
+
+import com.google.common.base.Optional;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+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.neutron.l3.rev150712.routers.attributes.Routers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkKey;
+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.vpnservice.lockmanager.rev150819.LockManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TimeUnits;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TryLockInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TryLockInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.UnlockInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.UnlockInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NeutronPortData;
+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.neutron.port.data
+        .PortFixedipToPortName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data
+        .PortFixedipToPortNameKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data
+        .PortNameToPortUuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data
+        .PortNameToPortUuidKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.subnetmaps.Subnetmap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMapKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.port.ext.rev151125.TrunkportExt;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.port.ext.rev151125.TrunkportTypeBase;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.port.ext.rev151125.TrunkportTypeSubport;
+
+public class NeutronvpnUtils {
+
+    private static final Logger logger = LoggerFactory.getLogger(NeutronvpnUtils.class);
+
+    protected static Subnetmap getSubnetmap(DataBroker broker, Uuid subnetId) {
+        InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).
+                child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
+        Optional<Subnetmap> sn = read(broker, LogicalDatastoreType.CONFIGURATION, id);
+
+        if (sn.isPresent()) {
+            return sn.get();
+        }
+        return null;
+    }
+
+    protected static VpnMap getVpnMap(DataBroker broker, Uuid id) {
+        InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
+                .child(VpnMap.class, new VpnMapKey(id)).build();
+        Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION,
+                vpnMapIdentifier);
+        if (optionalVpnMap.isPresent()) {
+            return optionalVpnMap.get();
+        }
+        logger.error("getVpnMap failed, VPN {} not present", id.getValue());
+        return null;
+    }
+
+    protected static Uuid getVpnForNetwork(DataBroker broker, Uuid network) {
+        InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
+        Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
+                vpnMapsIdentifier);
+        if (optionalVpnMaps.isPresent()) {
+            VpnMaps vpnMaps = optionalVpnMaps.get();
+            List<VpnMap> allMaps = vpnMaps.getVpnMap();
+            for (VpnMap vpnMap : allMaps) {
+                if (vpnMap.getNetworkIds().contains(network)) {
+                    return vpnMap.getVpnId();
+                }
+            }
+        }
+        return null;
+    }
+
+    protected static Uuid getVpnForRouter(DataBroker broker, Uuid router) {
+        InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
+        Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
+                vpnMapsIdentifier);
+        if (optionalVpnMaps.isPresent()) {
+            VpnMaps vpnNets = optionalVpnMaps.get();
+            List<VpnMap> allMaps = vpnNets.getVpnMap();
+            if (router != null) {
+                for (VpnMap vpnMap : allMaps) {
+                    if (router.equals(vpnMap.getRouterId())) {
+                        return vpnMap.getVpnId();
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    protected static Uuid getRouterforVpn(DataBroker broker, Uuid vpnId) {
+        InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
+                .child(VpnMap.class, new VpnMapKey(vpnId)).build();
+        Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION,
+                vpnMapIdentifier);
+        if (optionalVpnMap.isPresent()) {
+            VpnMap vpnMap = optionalVpnMap.get();
+            return vpnMap.getRouterId();
+        }
+        return null;
+    }
+
+    protected static Uuid getNeutronPortIdfromPortName(DataBroker broker, String portname) {
+        InstanceIdentifier id = buildPortNameToPortUuidIdentifier(portname);
+        Optional<PortNameToPortUuid> portNameToPortUuidData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
+        if (portNameToPortUuidData.isPresent()) {
+            return portNameToPortUuidData.get().getPortId();
+        }
+        return null;
+    }
+
+    protected static String getNeutronPortNamefromPortFixedIp(DataBroker broker, String fixedIp) {
+        InstanceIdentifier id = buildFixedIpToPortNameIdentifier(fixedIp);
+        Optional<PortFixedipToPortName> portFixedipToPortNameData = read(broker, LogicalDatastoreType.CONFIGURATION,
+                id);
+        if (portFixedipToPortNameData.isPresent()) {
+            return portFixedipToPortNameData.get().getPortName();
+        }
+        return null;
+    }
+
+    //TODO
+    //Will be done once integrated with TrunkPort Extensions
+    protected static int getVlanFromNeutronPort(Port port) {
+        int vlanId = 0;
+        /*
+        TrunkportExt trunkportExt = port.getAugmentation(TrunkportExt.class);
+        if (trunkportExt != null) {
+            Class<? extends TrunkportTypeBase> trunkportType = trunkportExt.getType();
+            if (trunkportType != null && trunkportType.isAssignableFrom(TrunkportTypeSubport.class)) {
+                vlanId = trunkportExt.getVid();
+            }
+        }
+        */
+        return vlanId;
+    }
+
+    protected static Router getNeutronRouter(DataBroker broker, Uuid routerId) {
+
+        InstanceIdentifier<Router> inst = InstanceIdentifier.create(Neutron.class).
+                child(Routers.class).child(Router.class, new RouterKey(routerId));
+
+        Optional<Router> rtr = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
+        if (rtr.isPresent()) {
+            return rtr.get();
+        }
+        return null;
+    }
+
+    protected static Network getNeutronNetwork(DataBroker broker, Uuid networkId) {
+        logger.debug("getNeutronNetwork for {}", networkId.getValue());
+        InstanceIdentifier<Network> inst = InstanceIdentifier.create(Neutron.class).
+                child(Networks.class).child(Network.class, new NetworkKey(networkId));
+
+        Optional<Network> net = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
+        if (net.isPresent()) {
+            return net.get();
+        }
+        return null;
+    }
+
+    protected static List<Uuid> getNeutronNetworkSubnetIds(DataBroker broker, Uuid networkId) {
+
+        logger.debug("getNeutronNetworkSubnetIds for {}", networkId.getValue());
+        Network network = getNeutronNetwork(broker, networkId);
+        if (network != null) {
+            //TODO
+            //return network.getSubnets();
+        }
+        logger.debug("returning from getNeutronNetworkSubnetIds for {}", networkId.getValue());
+
+        return null;
+    }
+
+    protected static List<Uuid> getNeutronRouterSubnetIds(DataBroker broker, Uuid routerId) {
+        logger.info("getNeutronRouterSubnetIds for {}", routerId.getValue());
+
+        List<Uuid> subnetNames = new ArrayList<Uuid>();
+        Router router = getNeutronRouter(broker, routerId);
+        if (router != null) {
+            List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router
+                    .Interfaces> ifs = router.getInterfaces();
+            if (!ifs.isEmpty()) {
+                for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers
+                        .router.Interfaces iff : ifs) {
+                    subnetNames.add(iff.getSubnetId());
+                }
+            }
+        }
+        logger.info("returning from getNeutronRouterSubnetIds for {}", routerId.getValue());
+        return subnetNames;
+    }
+
+    protected static String uuidToTapPortName(Uuid id) {
+        String tapId = id.getValue().substring(0, 11);
+        return new StringBuilder().append("tap").append(tapId).toString();
+    }
+
+    protected static void lockVpnInterface(LockManagerService lockManager, String vpnInterfaceName) {
+        TryLockInput input = new TryLockInputBuilder().setLockName(vpnInterfaceName).setTime(5L).setTimeUnit
+                (TimeUnits.Milliseconds).build();
+        Future<RpcResult<Void>> result = lockManager.tryLock(input);
+        try {
+            if ((result != null) && (result.get().isSuccessful())) {
+                logger.debug("Acquired lock for vpninterface {}", vpnInterfaceName);
+            } else {
+                throw new RuntimeException(String.format("Unable to getLock for vpninterface %s", vpnInterfaceName));
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            logger.error("Unable to getLock for vpninterface {}", vpnInterfaceName);
+            throw new RuntimeException(String.format("Unable to getLock for vpninterface %s", vpnInterfaceName), e
+                    .getCause());
+        }
+    }
+
+    protected static void unlockVpnInterface(LockManagerService lockManager, String vpnInterfaceName) {
+        UnlockInput input = new UnlockInputBuilder().setLockName(vpnInterfaceName).build();
+        Future<RpcResult<Void>> result = lockManager.unlock(input);
+        try {
+            if ((result != null) && (result.get().isSuccessful())) {
+                logger.debug("Unlocked vpninterface{}", vpnInterfaceName);
+            } else {
+                logger.debug("Unable to unlock vpninterface {}", vpnInterfaceName);
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            logger.error("Unable to unlock vpninterface {}", vpnInterfaceName);
+            throw new RuntimeException(String.format("Unable to unlock vpninterface %s", vpnInterfaceName), e
+                    .getCause());
+        }
+    }
+
+    static InstanceIdentifier<PortNameToPortUuid> buildPortNameToPortUuidIdentifier(String portname) {
+        InstanceIdentifier<PortNameToPortUuid> id =
+                InstanceIdentifier.builder(NeutronPortData.class).child(PortNameToPortUuid.class, new
+                        PortNameToPortUuidKey(portname)).build();
+        return id;
+    }
+
+    static InstanceIdentifier<PortFixedipToPortName> buildFixedIpToPortNameIdentifier(String fixedIp) {
+        InstanceIdentifier<PortFixedipToPortName> id =
+                InstanceIdentifier.builder(NeutronPortData.class).child(PortFixedipToPortName.class, new
+                        PortFixedipToPortNameKey(fixedIp)).build();
+        return id;
+    }
+
+    static InstanceIdentifier<Interface> buildVlanInterfaceIdentifier(String interfaceName) {
+        InstanceIdentifier<Interface> id = InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new
+                InterfaceKey(interfaceName)).build();
+        return id;
+    }
+
+    static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
+                                                   InstanceIdentifier<T> path) {
+
+        ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
+
+        Optional<T> result = Optional.absent();
+        try {
+            result = tx.read(datastoreType, path).get();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        return result;
+    }
+
+}
diff --git a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/neutronvpn/impl/rev150325/NeutronvpnImplModule.java b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/neutronvpn/impl/rev150325/NeutronvpnImplModule.java
new file mode 100644 (file)
index 0000000..c6b556d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.neutronvpn.impl.rev150325;
+
+import org.opendaylight.vpnservice.neutronvpn.NeutronvpnProvider;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.LockManagerService;
+
+public class NeutronvpnImplModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.neutronvpn
+        .impl.rev150325.AbstractNeutronvpnImplModule {
+    public NeutronvpnImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight
+            .controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public NeutronvpnImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight
+            .controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn
+            .opendaylight.params.xml.ns.yang.neutronvpn.impl.rev150325.NeutronvpnImplModule oldModule, java.lang
+            .AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        // TODO:implement
+        LockManagerService lockManagerService = getRpcRegistryDependency().getRpcService(LockManagerService.class);
+        NeutronvpnProvider provider = new NeutronvpnProvider(getRpcRegistryDependency());
+        provider.setMdsalManager(getMdsalutilDependency());
+        provider.setLockManager(lockManagerService);
+        getBrokerDependency().registerProvider(provider);
+        return provider;
+    }
+
+}
diff --git a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/neutronvpn/impl/rev150325/NeutronvpnImplModuleFactory.java b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/neutronvpn/impl/rev150325/NeutronvpnImplModuleFactory.java
new file mode 100644 (file)
index 0000000..d54bef1
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: neutronvpn-impl yang module local name: neutronvpn-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Thu Jan 06 10:51:12 IST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.neutronvpn.impl.rev150325;
+public class NeutronvpnImplModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.neutronvpn.impl.rev150325.AbstractNeutronvpnImplModuleFactory {
+
+}
diff --git a/neutronvpn/neutronvpn-impl/src/main/yang/neutronvpn-impl.yang b/neutronvpn/neutronvpn-impl/src/main/yang/neutronvpn-impl.yang
new file mode 100644 (file)
index 0000000..dafd23a
--- /dev/null
@@ -0,0 +1,54 @@
+module neutronvpn-impl {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:neutronvpn:impl";
+    prefix "neutronvpn-impl";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import neutronvpn-api { prefix neutronvpn-api; revision-date 2015-08-12;}
+    import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
+    import odl-mdsalutil { prefix odl-mdsal; revision-date 2015-04-10;}
+
+    description
+        "Service definition for neutronvpn project";
+
+    revision "2015-03-25" {
+        description
+            "Initial revision";
+    }
+
+    identity neutronvpn-impl {
+        base config:module-type;
+        config:provided-service neutronvpn-api:neutronvpn-api;
+        config:java-name-prefix NeutronvpnImpl;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case neutronvpn-impl {
+            when "/config:modules/config:module/config:type = 'neutronvpn-impl'";
+            container broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity md-sal-binding:binding-broker-osgi-registry;
+                    }
+                }
+            }
+            container rpc-registry {
+                 uses config:service-ref {
+                      refine type {
+                         mandatory true;
+                         config:required-identity md-sal-binding:binding-rpc-registry;
+                      }
+                 }
+            }
+            container mdsalutil {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity odl-mdsal:odl-mdsalutil;
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/neutronvpn/neutronvpn-shell/pom.xml b/neutronvpn/neutronvpn-shell/pom.xml
new file mode 100644 (file)
index 0000000..4be8655
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: --><!--
+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,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <parent>
+        <groupId>org.opendaylight.vpnservice</groupId>
+        <artifactId>config-parent</artifactId>
+        <version>0.2.0-SNAPSHOT</version>
+        <relativePath>../../commons/config-parent</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opendaylight.vpnservice</groupId>
+    <artifactId>neutronvpn-shell</artifactId>
+    <version>${vpnservices.version}</version>
+    <packaging>bundle</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.vpnservice</groupId>
+            <artifactId>neutronvpn-api</artifactId>
+            <version>${vpnservices.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+            <version>${karaf.shell.console.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/neutronvpn/neutronvpn-shell/src/main/java/org/opendaylight/vpnservice/neutronvpn/shell/ConfigureL3VpnCommand.java b/neutronvpn/neutronvpn-shell/src/main/java/org/opendaylight/vpnservice/neutronvpn/shell/ConfigureL3VpnCommand.java
new file mode 100644 (file)
index 0000000..01bfeb1
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.neutronvpn.shell;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.vpnservice.neutronvpn.interfaces.INeutronVpnManager;
+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.vpnservice.neutronvpn.rev150602.CreateL3VPNInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.CreateL3VPNOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.DeleteL3VPNInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.DeleteL3VPNOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NeutronvpnService;
+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.createl3vpn.input.L3vpnBuilder;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+@Command(scope = "vpnservice", name = "configure-l3vpn", description = "Create/Delete Neutron L3VPN")
+public class ConfigureL3VpnCommand extends OsgiCommandSupport {
+
+    final Logger Logger = LoggerFactory.getLogger(ConfigureL3VpnCommand.class);
+
+    private INeutronVpnManager neutronVpnManager;
+    private RpcProviderRegistry rpcProviderRegistry;
+    private NeutronvpnService neutronvpnService;
+
+    public void setNeutronVpnManager(INeutronVpnManager neutronVpnManager) {
+        this.neutronVpnManager = neutronVpnManager;
+    }
+
+    public void setRpcRegistry(RpcProviderRegistry rpcProviderRegistry) {
+        this.rpcProviderRegistry = rpcProviderRegistry;
+    }
+
+    @Option(name = "-op", aliases = {"--operation"}, description = "create-l3-vpn/delete-l3-vpn",
+            required = false, multiValued = false)
+    String op;
+
+    @Option(name = "-vid", aliases = {"--vpnid"}, description = "VPN ID", required = false, multiValued = false)
+    String vid;
+
+    @Option(name = "-n", aliases = {"--name"}, description = "VPN Name", required = false, multiValued = false)
+    String name;
+
+    @Option(name = "-tid", aliases = {"--tenantid"}, description = "Tenant ID", required = false, multiValued = false)
+    String tid;
+
+    @Option(name = "-rd", aliases = {"--rd"}, description = "Route Distinguisher", required = false, multiValued =
+            false)
+    String rd;
+
+    @Option(name = "-irt", aliases = {"--import-rts"}, description = "List of Import RTs", required = false,
+            multiValued = false)
+    String irt;
+
+    @Option(name = "-ert", aliases = {"--export-rts"}, description = "List of Export RTs", required = false,
+            multiValued = false)
+    String ert;
+
+    @Option(name = "-sid", aliases = {"--subnet-uuid"}, description = "List of Subnet IDs", required = false,
+            multiValued = false)
+    String sid;
+
+    @Override
+    protected Object doExecute() throws Exception {
+
+        if (rpcProviderRegistry != null) {
+            neutronvpnService = rpcProviderRegistry.getRpcService(NeutronvpnService.class);
+            if (neutronvpnService != null) {
+                if (op != null) {
+                    switch (op) {
+                        case "create-l3-vpn":
+                            createL3VpnCLI();
+                            break;
+                        case "delete-l3-vpn":
+                            deleteL3VpnCLI();
+                            break;
+                        default:
+                            System.out.println("Invalid argument.");
+                            System.out.println(getHelp(""));
+                            break;
+                    }
+                } else {
+                    System.out.println("Too few arguments");
+                    System.out.println(getHelp(""));
+                }
+            } else {
+                System.out.println("neutronvpnservice not initialized");
+            }
+        } else {
+            System.out.println("rpcProviderRegistryService not initialized");
+        }
+        return null;
+    }
+
+    public void createL3VpnCLI() {
+
+        if (vid == null) {
+            System.out.println("Please supply a valid VPN ID");
+            System.out.println(getHelp("create"));
+            return;
+        }
+
+        if (rd == null) {
+            System.out.println("Please supply a valid RD");
+            System.out.println(getHelp("create"));
+            return;
+        }
+
+        if (irt == null) {
+            System.out.println("Please supply a valid list of import RTs separated by {,}");
+            System.out.println(getHelp("create"));
+            return;
+        }
+
+        if (ert == null) {
+            System.out.println("Please supply a valid list of export RTs separated by {,}");
+            System.out.println(getHelp("create"));
+            return;
+        }
+
+        Uuid vuuid = new Uuid(vid);
+
+        try {
+            ArrayList<String> rdList = new ArrayList<String>(Arrays.asList(rd.split(",")));
+            ArrayList<String> irtList = new ArrayList<String>(Arrays.asList(irt.split(",")));
+            ArrayList<String> ertList = new ArrayList<String>(Arrays.asList(ert.split(",")));
+            Uuid tuuid = null;
+
+            if (tid != null) {
+                tuuid = new Uuid(tid);
+            }
+
+            List<L3vpn> l3vpns = new ArrayList<L3vpn>();
+            L3vpn l3vpn = new L3vpnBuilder().setId(vuuid).setName(name).setRouteDistinguisher(rdList).setImportRT
+                    (irtList)
+                    .setExportRT(ertList).setTenantId(tuuid).build();
+            l3vpns.add(l3vpn);
+            Future<RpcResult<CreateL3VPNOutput>> result =
+                    neutronvpnService.createL3VPN(new CreateL3VPNInputBuilder().setL3vpn(l3vpns).build());
+            RpcResult<CreateL3VPNOutput> rpcResult = result.get();
+            if (rpcResult.isSuccessful()) {
+                System.out.println("L3VPN created successfully");
+                Logger.trace("createl3vpn: {}", result);
+            } else {
+                System.out.println("error populating createL3VPN : " + result.get().getErrors());
+                System.out.println(getHelp("create"));
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            Logger.trace("error populating createL3VPN", e);
+            System.out.println("error populating createL3VPN : " + e.getMessage());
+            System.out.println(getHelp("create"));
+        }
+
+        try {
+            List<Uuid> sidList = new ArrayList<Uuid>();
+
+            if (sid != null) {
+                for (String sidStr : sid.split(",")) {
+                    Uuid suuid = new Uuid(sidStr);
+                    sidList.add(suuid);
+                }
+            }
+            for (Uuid subnet : sidList) {
+                neutronVpnManager.addSubnetToVpn(vuuid, subnet);
+            }
+
+        } catch (Exception e) {
+            Logger.trace("error in adding subnet to VPN", e);
+            System.out.println("error in adding subnet to VPN : " + e.getMessage());
+        }
+    }
+
+    public void deleteL3VpnCLI() {
+
+        if (vid == null) {
+            System.out.println("Please supply a valid VPN ID");
+            System.out.println(getHelp("delete"));
+            return;
+        }
+        Uuid vpnid = new Uuid(vid);
+        try {
+            List<Uuid> sidList = neutronVpnManager.getSubnetsforVpn(vpnid);
+            if (sidList != null) {
+                for (Uuid subnet : sidList) {
+                    neutronVpnManager.removeSubnetFromVpn(vpnid, subnet);
+                }
+            }
+        } catch (Exception e) {
+            Logger.trace("error in deleting subnet from VPN", e);
+            System.out.println("error in deleting subnet from VPN : " + e.getMessage());
+        }
+
+        try {
+            List<Uuid> vpnIdList = new ArrayList<Uuid>();
+            vpnIdList.add(vpnid);
+
+            Future<RpcResult<DeleteL3VPNOutput>> result =
+                    neutronvpnService.deleteL3VPN(new DeleteL3VPNInputBuilder().setId(vpnIdList).build());
+            RpcResult<DeleteL3VPNOutput> rpcResult = result.get();
+            if (rpcResult.isSuccessful()) {
+                System.out.println("L3VPN deleted successfully");
+                Logger.trace("deletel3vpn: {}", result);
+            } else {
+                System.out.println("error populating deleteL3VPN : " + result.get().getErrors());
+                System.out.println(getHelp("delete"));
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            Logger.trace("error populating deleteL3VPN", e);
+            System.out.println("error populating deleteL3VPN : " + e.getMessage());
+            System.out.println(getHelp("delete"));
+        }
+    }
+
+    private String getHelp(String cmd) {
+        StringBuilder help = new StringBuilder("Usage:");
+        switch (cmd) {
+            case "create":
+                help.append("exec configure-vpn -op/--operation create-l3-vpn -vid/--vpnid <id>\n");
+                help.append("-rd/--rd <rd> -irt/--import-rts <irt1,irt2,..> -ert/--export-rts <ert1,ert2,..>\n");
+                help.append("[-sid/--subnet-uuid <subnet1,subnet2,..>]\n");
+                break;
+            case "delete":
+                help.append("exec configure-vpn -op/--operation delete-l3-vpn -vid/--vpnid <id> \n");
+                break;
+            case "":
+                help.append("exec configure-vpn -op/--operation create-l3-vpn -vid/--vpnid <id>\n");
+                help.append("-rd/--rd <rd> -irt/--import-rts <irt1,irt2,..> -ert/--export-rts <ert1,ert2,..>\n");
+                help.append("[-sid/--subnet-uuid <subnet1,subnet2,..>]\n");
+                help.append("exec configure-vpn -op/--operation delete-l3-vpn -vid/--vpnid <id> \n");
+        }
+        return help.toString();
+    }
+
+}
diff --git a/neutronvpn/neutronvpn-shell/src/main/java/org/opendaylight/vpnservice/neutronvpn/shell/ShowNeutronPortsCommand.java b/neutronvpn/neutronvpn-shell/src/main/java/org/opendaylight/vpnservice/neutronvpn/shell/ShowNeutronPortsCommand.java
new file mode 100644 (file)
index 0000000..cf4736e
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.neutronvpn.shell;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.vpnservice.neutronvpn.interfaces.INeutronVpnManager;
+
+@Command(scope = "vpnservice", name = "neutron-ports-show", description = "Displays neutron ports")
+public class ShowNeutronPortsCommand extends OsgiCommandSupport {
+    private INeutronVpnManager neutronVpnManager;
+
+    public void setNeutronVpnManager(INeutronVpnManager neutronVpnManager) {
+        this.neutronVpnManager = neutronVpnManager;
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+        for (String p : neutronVpnManager.showNeutronPortsCLI()) {
+            System.out.println(p);
+        }
+        return null;
+    }
+}
diff --git a/neutronvpn/neutronvpn-shell/src/main/java/org/opendaylight/vpnservice/neutronvpn/shell/ShowVpnConfigCommand.java b/neutronvpn/neutronvpn-shell/src/main/java/org/opendaylight/vpnservice/neutronvpn/shell/ShowVpnConfigCommand.java
new file mode 100644 (file)
index 0000000..8801af3
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.neutronvpn.shell;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.vpnservice.neutronvpn.interfaces.INeutronVpnManager;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+
+@Command(scope = "vpnservice", name = "l3vpn-config-show", description = "Displays Neutron L3VPN configuration")
+public class ShowVpnConfigCommand extends OsgiCommandSupport {
+
+    @Option(name = "-vid", aliases = {"--vpnid"}, description = "VPN ID", required = false, multiValued = false)
+    String vid;
+
+    private INeutronVpnManager neutronVpnManager;
+
+    public void setNeutronVpnManager(INeutronVpnManager neutronVpnManager) {
+        this.neutronVpnManager = neutronVpnManager;
+    }
+
+    @Override
+    protected Object doExecute() throws Exception {
+
+        Uuid vuuid = null;
+        if (vid != null) {
+            vuuid = new Uuid(vid);
+        }
+
+        for (String p : neutronVpnManager.showVpnConfigCLI(vuuid)) {
+            System.out.println(p);
+        }
+        return null;
+    }
+}
diff --git a/neutronvpn/neutronvpn-shell/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/neutronvpn/neutronvpn-shell/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644 (file)
index 0000000..80cff04
--- /dev/null
@@ -0,0 +1,38 @@
+<!--    * Copyright (c) 2015 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,
+        * and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+    <reference id="neutronVpnManagerRef"
+               interface="org.opendaylight.vpnservice.neutronvpn.interfaces.INeutronVpnManager"
+               availability="optional"/>
+    <reference id="rpcRegistryRef" interface="org.opendaylight.controller.sal.binding.api.RpcProviderRegistry"
+               availability="optional"/>
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+
+        <command>
+            <action class="org.opendaylight.vpnservice.neutronvpn.shell.ConfigureL3VpnCommand">
+                <property name="neutronVpnManager" ref="neutronVpnManagerRef"/>
+                <property name="rpcRegistry" ref="rpcRegistryRef"/>
+            </action>
+        </command>
+
+        <command>
+            <action class="org.opendaylight.vpnservice.neutronvpn.shell.ShowVpnConfigCommand">
+                <property name="neutronVpnManager" ref="neutronVpnManagerRef"/>
+            </action>
+        </command>
+
+        <command>
+            <action class="org.opendaylight.vpnservice.neutronvpn.shell.ShowNeutronPortsCommand">
+                <property name="neutronVpnManager" ref="neutronVpnManagerRef"/>
+            </action>
+        </command>
+
+    </command-bundle>
+
+</blueprint>
diff --git a/neutronvpn/pom.xml b/neutronvpn/pom.xml
new file mode 100644 (file)
index 0000000..18814e0
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>odlparent</artifactId>
+        <version>1.6.0-SNAPSHOT</version>
+        <relativePath/>
+    </parent>
+
+    <groupId>org.opendaylight.vpnservice</groupId>
+    <artifactId>neutronvpn-aggregator</artifactId>
+    <version>0.2.0-SNAPSHOT</version>
+    <name>neutronvpn</name>
+    <packaging>pom</packaging>
+    <modelVersion>4.0.0</modelVersion>
+    <prerequisites>
+        <maven>3.1.1</maven>
+    </prerequisites>
+    <modules>
+        <module>neutronvpn-api</module>
+        <module>neutronvpn-impl</module>
+        <module>neutronvpn-shell</module>
+    </modules>
+    <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-install-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/pom.xml b/pom.xml
index 19bcaaa344747c009ffb0d60ee1309ef0cce9920..0fdc1a45cb08a2e199452941579035c2e701f770 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -28,6 +28,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <module>alivenessmonitor</module>
     <module>fibmanager</module>
     <module>bgpmanager</module>
+    <module>neutronvpn</module>
     <module>dhcpservice</module>
     <module>itm</module>
     <module>distribution/karaf</module>