Working with OVS 61/29461/3
authorFaseela K <faseela.k@ericsson.com>
Fri, 20 Nov 2015 10:35:08 +0000 (16:05 +0530)
committerFaseela K <faseela.k@ericsson.com>
Fri, 20 Nov 2015 10:35:08 +0000 (16:05 +0530)
    - Config and Topology listeners and helpers
- Yang updations
- Datastore job co-ordinator prototype
- Incorporating previous review comments

Change-Id: I81be9516578172497d3a45fbfcda0c01bffe9613
Signed-off-by: Faseela K <faseela.k@ericsson.com>
56 files changed:
features/src/main/features/features.xml
interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/interfaces/IInterfaceManager.java
interfacemgr/interfacemgr-api/src/main/yang/odl-interface-meta.yang
interfacemgr/interfacemgr-api/src/main/yang/odl-interface-rpc.yang
interfacemgr/interfacemgr-api/src/main/yang/odl-interface-service-bindings.yang
interfacemgr/interfacemgr-api/src/main/yang/odl-interface.yang
interfacemgr/interfacemgr-impl/src/main/config/default-config.xml
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmUtil.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceManagerCommonUtils.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceMetaUtils.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceConfigListener.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceInventoryStateListener.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceTopologyStateListener.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/VlanMemberConfigListener.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigAddHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigRemoveHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigUpdateHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigAddHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigRemoveHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigUpdateHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateAddHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateRemoveHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateUpdateHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceTopologyStateAddHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceTopologyStateRemoveHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/utilities/SouthboundUtils.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/utilities/VlanTrunkSouthboundUtils.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/rpcservice/InterfaceManagerRpcService.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/confighelpers/FlowBasedServicesConfigBindHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/confighelpers/FlowBasedServicesConfigUnbindHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/listeners/FlowBasedServicesConfigListener.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/listeners/FlowBasedServicesInterfaceStateListener.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/statehelpers/FlowBasedServicesStateBindHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/statehelpers/FlowBasedServicesStateUnbindHelper.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/utilities/FlowBasedServicesUtils.java [new file with mode: 0644]
interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/interfacemgr/impl/rev150325/InterfacemgrImplModule.java
interfacemgr/interfacemgr-impl/src/main/yang/interfacemgr-impl.yang
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/AsyncDataChangeListenerBase.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/AsyncDataTreeChangeListenerBase.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/DataStoreJobCoordinator.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/JobEntry.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/JobQueue.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/RollbackCallable.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/TaskRetryLooper.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MDSALUtil.java
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/MetaDataUtil.java
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/interfaces/IMdsalApiManager.java
mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALManager.java
mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/MDSALUtilProvider.java
nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/NexthopManager.java
nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/OdlInterfaceChangeListener.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/InterfaceChangeListener.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java

index 4a4b1cac2c4247fc31d900c42623824e032d1e4e..e03ef333f3063ccf61c1ce58e24bd6f406f6afa6 100644 (file)
@@ -20,7 +20,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
     <feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
     <feature version='${openflowplugin.version}'>odl-openflowplugin-nsf-model</feature>
-    <feature version="${ovsdb.version}">odl-ovsdb-southbound-api</feature>
     <bundle>mvn:org.opendaylight.vpnservice/model-bgp/{{VERSION}}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/idmanager-api/${idmanager.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/vpnmanager-api/${vpnmanager.version}</bundle>
@@ -30,7 +29,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   </feature>
   <feature name='odl-vpnservice-impl' version='${project.version}' description='OpenDaylight :: vpnservice :: impl '>
     <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
-    <feature version="${ovsdb.version}">odl-ovsdb-southbound-api</feature>
+    <feature version="${ovsdb.version}">odl-ovsdb-southbound-impl-rest</feature>
     <feature version='${project.version}'>odl-vpnservice-api</feature>
     <feature version="${openflowplugin.version}">odl-openflowplugin-southbound</feature>
     <feature version="${openflowplugin.version}">odl-openflowplugin-flow-services</feature>
index 8ef4efdb474a82d5f24e019faf2466201d0d0ae8..64c98b9f2e189f65cdf83019fbb0aaf1014d5106 100644 (file)
@@ -15,14 +15,27 @@ import java.util.List;
 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
 
+@Deprecated
 public interface IInterfaceManager {
-
+    @Deprecated
     public Long getPortForInterface(String ifName);
+
+    @Deprecated
     public BigInteger getDpnForInterface(String ifName);
+
+    @Deprecated
     public BigInteger getDpnForInterface(Interface intrf);
+
+    @Deprecated
     public String getEndpointIpForDpn(BigInteger dpnId);
+
+    @Deprecated
     public List<MatchInfo> getInterfaceIngressRule(String ifName);
+
+    @Deprecated
     public List<ActionInfo> getInterfaceEgressActions(String ifName);
+
+    @Deprecated
     public Long getPortForInterface(Interface intf);
 
 }
\ No newline at end of file
index c2a99dac575f419e91b15b49786cce2214066260..66b4a850b2baad239d92e96f7c11eb603bd26853 100644 (file)
@@ -24,9 +24,6 @@ module odl-interface-meta {
                 leaf interface-name {
                     type string;
                 }
-                leaf tp-id-ref {
-                    type southbound:ovsdb-termination-point-ref;
-                }
             }
         }
     }
@@ -47,4 +44,21 @@ module odl-interface-meta {
             }
         }
     }
+
+    container interface-child-info {
+        description "The container of all Child-Interfaces for a given interface.";
+        list interface-parent-entry {
+            key parent-interface;
+            leaf parent-interface {
+                type string;
+            }
+
+            list interface-child-entry {
+                key child-interface;
+                leaf child-interface {
+                    type string;
+                }
+            }
+        }
+    }
 }
\ No newline at end of file
index f95d52c27c77d93c7cfcb8f41b165a248cc1a6a6..0e4efca05eeca046b9e43ad7ea1d8ed462abc2c5 100644 (file)
@@ -17,62 +17,7 @@ module odl-interface-rpc {
         description "ODL Specific Interface Manager Rpcs Module";
     }
 
-/* RPCs */
-    rpc get-interface-from-lporttag {
-        description "Used to retrieve the interface-name using lporttag";
-        input {
-            leaf lportag {
-                type uint32;
-            }
-        }
-        output {
-            leaf intf-name {
-                type string;
-            }
-        }
-    }
-
-    rpc get-lporttag-from-interface {
-        description "Used to retrieve the lporttag from interface-name";
-        input {
-            leaf intf-name {
-                type string;
-            }
-        }
-        output {
-            leaf lportag {
-                type uint32;
-            }
-        }
-    }
-
-    rpc get-interface-from-groupid {
-        description "Used to retrieve the interface-name using groupid";
-        input {
-            leaf groupid {
-                type uint32;
-            }
-        }
-        output {
-            leaf intf-name {
-                type string;
-            }
-        }
-    }
-
-    rpc get-groupid-from-interface {
-        description "Used to retrieve the interface-name using groupid";
-        input {
-            leaf intf-name {
-                type string;
-            }
-        }
-        output {
-            leaf groupid {
-                type uint32;
-            }
-        }
-    }
+    /* RPCs */
 
     rpc get-dpid-from-interface {
         description "used to retrieve dpid from interface name";
index cebf3bdd9dbfcce75eecabd3d3f2a0a65dc32b02..14af19ff15ab08a609b6a907c5fa887514b2e1d2 100644 (file)
@@ -42,10 +42,6 @@ module interface-service-bindings {
                     }
                 }
 
-                leaf interface-name {
-                    type string;
-                }
-
                 leaf service-name {
                     type string;
                 }
index 609c11472d5941bcd744b5cf91bf91c00dba1045..38405be01414d4a3b8b05e61692105f32f2f438a 100644 (file)
@@ -23,6 +23,8 @@ module odl-interface {
         prefix inv; revision-date 2013-08-19;
     }
 
+    import opendaylight-l2-types { prefix ethertype; revision-date "2013-08-27";}
+
     import config {
         prefix config; revision-date 2013-04-05;
     }
@@ -47,14 +49,13 @@ module odl-interface {
         reference "MPLS interface";
     }
 
+    /* Tunnel (GRE, VxLAN) logical port */
     identity l3tunnel {
         status deprecated;
         base if:interface-type;
-        reference
-        "l3 tunnel interface";
+        reference "l3 tunnel interface";
     }
 
-    /* Tunnel (GRE, VxLAN) logical port */
     identity tunnel-type-base {
         description "Base identity for all tunnel-types";
     }
@@ -99,8 +100,42 @@ module odl-interface {
         ext:augment-identifier "if-l2vlan";
         when "if:type = 'ianaift:l2vlan'";
         leaf vlan-id {
-            type uint16 {
-                range "1..4094";
+            type ethertype:vlan-id;
+        }
+
+        leaf l2vlan-mode {
+            description "The VLAN mode of the L2Vlan Interface.";
+            type enumeration {
+                enum "access" {
+                    value 1;
+                    description
+                        "The VLAN mode access.";
+                }
+                enum "native-tagged" {
+                    value 2;
+                    description
+                        "The VLAN mode native-tagged.";
+                }
+                enum "native-untagged" {
+                    value 3;
+                    description
+                        "The VLAN mode native-untagged.";
+                }
+                enum "trunk" {
+                    value 4;
+                    description
+                        "The VLAN mode trunk.";
+                }
+                enum "trunk-member" {
+                    value 5;
+                    description
+                        "The VLAN mode trunk-member.";
+                }
+                enum "transparent" {
+                    value 6;
+                    description
+                        "The VLAN mode transparent.";
+                }
             }
         }
     }
@@ -152,6 +187,7 @@ module odl-interface {
                 base tunnel-type-base;
             }
         }
+
         leaf local-ip {
             type inet:ip-address;
             description "Local Endpoint IP address";
index e4fb6f45324266183813cb7061764fa700462a8b..a0e92ffb9ca5bfbfbf40a44bc67f6e64bd886431 100644 (file)
@@ -24,6 +24,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
             <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>
         </module>
       </modules>
       <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
index da85fe55b3a8e3f49c1cab77cbdb047e62613dc5..bcaf8ef2f12d4b62c9664bdea9e9396034bcc12e 100644 (file)
@@ -15,5 +15,7 @@ public class IfmConstants {
     public static final String OF_URI_PREFIX = "openflow:";
     public static final String OF_URI_SEPARATOR = ":";
     public static final int DEFAULT_IFINDEX = 65536;
+    public static final String IFM_LPORT_TAG_IDPOOL_NAME = "vlaninterfaces.lporttag";
+    public static final short VLAN_INTERFACE_INGRESS_TABLE = 0;
 
 }
index 2b298475e5435d156154f4a68b8c8d26d3453544..400ebd2433e0c04e218919a5ff9889596df93eac 100644 (file)
@@ -8,16 +8,29 @@
 package org.opendaylight.vpnservice.interfacemgr;
 
 import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 
+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.InterfacesState;
 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.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadata;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.Pools;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPoolKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
 
@@ -55,7 +68,7 @@ public class IfmUtil {
         InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder =
                 InstanceIdentifier.builder(InterfacesState.class)
                 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class,
-                                new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
+                        new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id = idBuilder.build();
         return id;
     }
@@ -71,4 +84,71 @@ public class IfmUtil {
         InstanceIdentifier<IdPool> id = idBuilder.build();
         return id;
     }
+
+    public static List<String> getPortNameAndSuffixFromInterfaceName(String intfName) {
+        List<String> strList = new ArrayList<>(2);
+        int index = intfName.indexOf(":");
+        if (index != -1) {
+            strList.add(0, intfName.substring(0, index));
+            strList.add(1, intfName.substring(index));
+        }
+        return strList;
+    }
+
+    public static List<String> getDpIdPortNameAndSuffixFromInterfaceName(String intfName) {
+        List<String> strList = new ArrayList<>(3);
+        int index1 = intfName.indexOf(":");
+        if (index1 != -1) {
+            int index2 = intfName.indexOf(":", index1 + 1 );
+            strList.add(0, intfName.substring(0, index1));
+            if (index2 != -1) {
+                strList.add(1, intfName.substring(index1, index2));
+                strList.add(2, intfName.substring(index2));
+            } else {
+                strList.add(1, intfName.substring(index1));
+                strList.add(2, "");
+            }
+        }
+        return strList;
+    }
+
+    public static <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
+                                                          InstanceIdentifier<T> path, DataBroker broker) {
+
+        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;
+    }
+
+    public static NodeId getNodeIdFromNodeConnectorId(NodeConnectorId ncId) {
+        return new NodeId(ncId.getValue().substring(0,ncId.getValue().lastIndexOf(":")));
+    }
+
+    public static BigInteger[] mergeOpenflowMetadataWriteInstructions(List<Instruction> instructions) {
+        BigInteger metadata = new BigInteger("0", 16);
+        BigInteger metadataMask = new BigInteger("0", 16);
+        if (instructions != null && !instructions.isEmpty()) {
+            // check if metadata write instruction is present
+            for (Instruction instruction : instructions) {
+                org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction actualInstruction = instruction.getInstruction();
+                if (actualInstruction instanceof WriteMetadataCase) {
+                    WriteMetadataCase writeMetaDataInstruction = (WriteMetadataCase) actualInstruction ;
+                    WriteMetadata availableMetaData = writeMetaDataInstruction.getWriteMetadata();
+                    metadata = metadata.or(availableMetaData.getMetadata());
+                    metadataMask = metadataMask.or(availableMetaData.getMetadataMask());
+                }
+            }
+        }
+        return new BigInteger[] { metadata, metadataMask };
+    }
+
+
+
 }
index d03fd5f6d313260f53d802a53be9289c96d85425..bd643ba22527340bfd8ecb49a80ceb9abeb728eb 100644 (file)
@@ -7,17 +7,9 @@
  */
 package org.opendaylight.vpnservice.interfacemgr;
 
-import java.math.BigInteger;
-
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
@@ -31,6 +23,7 @@ import org.opendaylight.vpnservice.mdsalutil.ActionType;
 import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
 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.iana._if.type.rev140508.Tunnel;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
 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;
@@ -49,15 +42,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.id.pool.GeneratedIds;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfMpls;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfStackedVlan;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.Mpls;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.StackedVlan;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.*;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -66,6 +51,14 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
 public class InterfaceManager extends AbstractDataChangeListener<Interface> implements AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(InterfaceManager.class);
     private ListenerRegistration<DataChangeListener> listenerRegistration;
@@ -148,10 +141,10 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
             ncId = nodeConn.getId();
         }
         mapNcToInterfaceName.put(ncId, interf.getName());
-        if(interf.getType().isAssignableFrom(L3tunnel.class)) {
+        if(interf.getType().isAssignableFrom(Tunnel.class)) {
             NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
-            IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class);
-            dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue());
+            IfTunnel tunnel = interf.getAugmentation(IfTunnel.class);
+            dbDpnEndpoints.put(nodeId, tunnel.getTunnelSource().getIpv4Address().getValue());
             LOG.trace("dbDpnEndpoints: {}",dbDpnEndpoints);
         }
     }
@@ -280,7 +273,7 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
             NodeConnectorId ncId = getNodeConnectorIdFromInterface(delInterface);
             if(ncId != null) {
                 mapNcToInterfaceName.remove(ncId);
-                if(delInterface.getType().isAssignableFrom(L3tunnel.class)) {
+                if(delInterface.getType().isAssignableFrom(Tunnel.class)) {
                     NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
                     dbDpnEndpoints.remove(nodeId);
                     LOG.trace("dbDpnEndpoints: {}",dbDpnEndpoints);
@@ -319,10 +312,10 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
             if(nc != null) {
                 // Name doesn't change. Is it present in update?
                 mapNcToInterfaceName.put(nc.getId(), original.getName());
-                if(interf.getType().isAssignableFrom(L3tunnel.class)) {
+                if(interf.getType().isAssignableFrom(Tunnel.class)) {
                     NodeId nodeId = getNodeIdFromNodeConnectorId(nc.getId());
-                    IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class);
-                    dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue());
+                    IfTunnel tunnel = interf.getAugmentation(IfTunnel.class);
+                    dbDpnEndpoints.put(nodeId, tunnel.getTunnelSource().getIpv4Address().getValue());
                     LOG.trace("dbEndpoints: {}",dbDpnEndpoints);
                 }
             }
@@ -491,17 +484,17 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
 
         if (ifType.isInstance(L2vlan.class)) {
             IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class);
-            long vlanVid = vlanIface.getVlanId().longValue();
+            long vlanVid = vlanIface.getVlanId().getValue().longValue();
             if (vlanVid != 0) {
                 matches.add(new MatchInfo(MatchFieldType.vlan_vid,
                             new long[] {vlanVid}));
                 LOG.trace("L2Vlan: {}",vlanIface);
             }
-        } else if (ifType.isInstance(L3tunnel.class)) {
+        } else if (ifType.isInstance(Tunnel.class)) {
             //TODO: Handle different tunnel types
-            IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class);
-            Class<? extends TunnelTypeBase> tunnType = ifL3Tunnel.getTunnelType();
-            LOG.trace("L3Tunnel: {}",ifL3Tunnel);
+            IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
+            Class<? extends TunnelTypeBase> tunnType = ifTunnel.getTunnelInterfaceType();
+            LOG.trace("L3Tunnel: {}",ifTunnel);
         } else if (ifType.isAssignableFrom(StackedVlan.class)) {
             IfStackedVlan ifStackedVlan = iface.getAugmentation(IfStackedVlan.class);
             LOG.trace("StackedVlan: {}",ifStackedVlan);
@@ -524,7 +517,7 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
             if(ifType.isAssignableFrom(L2vlan.class)) {
                 IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class);
                 LOG.trace("L2Vlan: {}",vlanIface);
-                long vlanVid = (vlanIface == null) ? 0 : vlanIface.getVlanId();
+                long vlanVid = (vlanIface == null) ? 0 : vlanIface.getVlanId().getValue().longValue();
                 if (vlanVid != 0) {
                     listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
                     listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
@@ -532,11 +525,11 @@ public class InterfaceManager extends AbstractDataChangeListener<Interface> impl
                 }
                 listActionInfo.add(new ActionInfo(ActionType.output, new String[] { Long.toString(portNo)}));
 
-            } else if (ifType.isAssignableFrom(L3tunnel.class)) {
+            } else if (ifType.isAssignableFrom(Tunnel.class)) {
                 //TODO: Handle different tunnel types
-                IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class);
-                Class<? extends TunnelTypeBase> tunnType = ifL3Tunnel.getTunnelType();
-                LOG.trace("L3Tunnel: {}",ifL3Tunnel);
+                IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
+                Class<? extends TunnelTypeBase> tunnType = ifTunnel.getTunnelInterfaceType();
+                LOG.trace("L3Tunnel: {}",ifTunnel);
                 //TODO: check switch_type and configure accordingly
                 listActionInfo.add(new ActionInfo(ActionType.output, new String[] { Long.toString(portNo)}));
 
index 74074883aad0f659bd67d11d0cda1552861ae1f5..ace54f553cffe0d9be4d894bd4a25495bee22475 100644 (file)
@@ -7,42 +7,96 @@
  */
 package org.opendaylight.vpnservice.interfacemgr;
 
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-
-import java.math.BigInteger;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+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.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.listeners.InterfaceConfigListener;
+import org.opendaylight.vpnservice.interfacemgr.listeners.InterfaceInventoryStateListener;
+import org.opendaylight.vpnservice.interfacemgr.listeners.InterfaceTopologyStateListener;
 import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.interfacemgr.rpcservice.InterfaceManagerRpcService;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.listeners.FlowBasedServicesConfigListener;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.listeners.FlowBasedServicesInterfaceStateListener;
+import org.opendaylight.vpnservice.interfacemgr.listeners.VlanMemberConfigListener;
 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+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.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.*;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.math.BigInteger;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
 public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable, IInterfaceManager {
 
     private static final Logger LOG = LoggerFactory.getLogger(InterfacemgrProvider.class);
 
+    private RpcProviderRegistry rpcProviderRegistry;
+
     private InterfaceManager interfaceManager;
     private IfmNodeConnectorListener ifmNcListener;
     private IdManager idManager;
 
+    private InterfaceConfigListener interfaceConfigListener;
+    private InterfaceTopologyStateListener topologyStateListener;
+    private InterfaceInventoryStateListener interfaceInventoryStateListener;
+    private FlowBasedServicesInterfaceStateListener flowBasedServicesInterfaceStateListener;
+    private FlowBasedServicesConfigListener flowBasedServicesConfigListener;
+    private VlanMemberConfigListener vlanMemberConfigListener;
+
+    private InterfaceManagerRpcService interfaceManagerRpcService;
+    private BindingAwareBroker.RpcRegistration<OdlInterfaceRpcService> rpcRegistration;
+
+    public void setRpcProviderRegistry(RpcProviderRegistry rpcProviderRegistry) {
+        this.rpcProviderRegistry = rpcProviderRegistry;
+    }
+
     @Override
     public void onSessionInitiated(ProviderContext session) {
         LOG.info("InterfacemgrProvider Session Initiated");
         try {
             final  DataBroker dataBroker = session.getSALService(DataBroker.class);
             idManager = new IdManager(dataBroker);
-            interfaceManager = new InterfaceManager(dataBroker, idManager);
-            ifmNcListener = new IfmNodeConnectorListener(dataBroker, interfaceManager);
             createIdPool();
+
+            interfaceManagerRpcService = new InterfaceManagerRpcService(dataBroker);
+            rpcRegistration = getRpcProviderRegistry().addRpcImplementation(
+                    OdlInterfaceRpcService.class, interfaceManagerRpcService);
+
+            interfaceConfigListener = new InterfaceConfigListener(dataBroker, idManager);
+            interfaceConfigListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
+
+            interfaceInventoryStateListener = new InterfaceInventoryStateListener(dataBroker);
+            interfaceInventoryStateListener.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
+
+            topologyStateListener = new InterfaceTopologyStateListener(dataBroker);
+            topologyStateListener.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
+
+            flowBasedServicesConfigListener = new FlowBasedServicesConfigListener(dataBroker);
+            flowBasedServicesConfigListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
+
+            flowBasedServicesInterfaceStateListener =
+                    new FlowBasedServicesInterfaceStateListener(dataBroker);
+            flowBasedServicesInterfaceStateListener.registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
+
+            vlanMemberConfigListener =
+                               new VlanMemberConfigListener(dataBroker, idManager);
+            vlanMemberConfigListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
+
+
+            /*interfaceManager = new InterfaceManager(dataBroker, idManager);
+            ifmNcListener = new IfmNodeConnectorListener(dataBroker, interfaceManager);*/
         } catch (Exception e) {
             LOG.error("Error initializing services", e);
         }
@@ -70,27 +124,75 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
         LOG.info("InterfacemgrProvider Closed");
         interfaceManager.close();
         ifmNcListener.close();
+        interfaceConfigListener.close();
+        rpcRegistration.close();
+    }
+
+    public RpcProviderRegistry getRpcProviderRegistry() {
+        return rpcProviderRegistry;
     }
 
     @Override
     public Long getPortForInterface(String ifName) {
-        return interfaceManager.getPortForInterface(ifName);
+        GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(ifName).build();
+        Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
+        try {
+            RpcResult<GetPortFromInterfaceOutput> port = output.get();
+            if(port.isSuccessful()){
+                return port.getResult().getPortno();
+            }
+        }catch(NullPointerException | InterruptedException | ExecutionException e){
+            LOG.warn("Exception when getting port for interface",e);
+        }
+        return null;
     }
 
     @Override
     public Long getPortForInterface(Interface intf) {
-        return interfaceManager.getPortForInterface(intf);
+        GetPortFromInterfaceInput input = new GetPortFromInterfaceInputBuilder().setIntfName(intf.getName()).build();
+        Future<RpcResult<GetPortFromInterfaceOutput>> output = interfaceManagerRpcService.getPortFromInterface(input);
+        try {
+            RpcResult<GetPortFromInterfaceOutput> port = output.get();
+            if(port.isSuccessful()){
+                return port.getResult().getPortno();
+            }
+        }catch(NullPointerException | InterruptedException | ExecutionException e){
+            LOG.warn("Exception when getting port for interface",e);
+        }
+        return null;
     }
 
-
     @Override
     public BigInteger getDpnForInterface(String ifName) {
-        return interfaceManager.getDpnForInterface(ifName);
+        GetDpidFromInterfaceInput input = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
+        Future<RpcResult<GetDpidFromInterfaceOutput>> output = interfaceManagerRpcService.getDpidFromInterface(input);
+        try {
+            RpcResult<GetDpidFromInterfaceOutput> dpn = output.get();
+            if(dpn.isSuccessful()){
+                return dpn.getResult().getDpid();
+            }
+        }catch(NullPointerException | InterruptedException | ExecutionException e){
+            LOG.warn("Exception when getting port for interface",e);
+        }
+        return null;
     }
 
     @Override
     public String getEndpointIpForDpn(BigInteger dpnId) {
-        return interfaceManager.getEndpointIpForDpn(dpnId);
+        GetEndpointIpForDpnInput input = new GetEndpointIpForDpnInputBuilder().setDpid(dpnId).build();
+        Future<RpcResult<GetEndpointIpForDpnOutput>> output = interfaceManagerRpcService.getEndpointIpForDpn(input);
+        try {
+            RpcResult<GetEndpointIpForDpnOutput> ipForDpnOutputRpcResult = output.get();
+            if(ipForDpnOutputRpcResult.isSuccessful()){
+                List<IpAddress> localIps = ipForDpnOutputRpcResult.getResult().getLocalIps();
+                if(!localIps.isEmpty()) {
+                    return localIps.get(0).getIpv4Address().getValue();
+                }
+            }
+        }catch(NullPointerException | InterruptedException | ExecutionException e){
+            LOG.warn("Exception when getting port for interface",e);
+        }
+        return null;
     }
 
     @Override
@@ -100,12 +202,11 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
 
     @Override
     public List<ActionInfo> getInterfaceEgressActions(String ifName) {
-        return interfaceManager.getInterfaceEgressActions(ifName);
+        return interfaceManagerRpcService.getEgressActionInfosForInterface(ifName);
     }
 
     @Override
     public BigInteger getDpnForInterface(Interface intrf) {
-        // TODO Auto-generated method stub
-        return interfaceManager.getDpnForInterface(intrf);
+        return getDpnForInterface(intrf.getName());
     }
-}
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceManagerCommonUtils.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceManagerCommonUtils.java
new file mode 100644 (file)
index 0000000..6b10cb0
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * 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
+ */
+
+package org.opendaylight.vpnservice.interfacemgr.commons;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+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.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdOutput;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+public class InterfaceManagerCommonUtils {
+    private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerCommonUtils.class);
+    public static NodeConnector getNodeConnectorFromInventoryOperDS(NodeConnectorId nodeConnectorId,
+                                                                    DataBroker dataBroker) {
+        NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
+        InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
+                .child(Node.class, new NodeKey(nodeId))
+                .child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId)).build();
+
+        Optional<NodeConnector> nodeConnectorOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL,
+                ncIdentifier, dataBroker);
+        if (!nodeConnectorOptional.isPresent()) {
+            return null;
+        }
+        return nodeConnectorOptional.get();
+    }
+
+    /*public static void addInterfaceEntryToInventoryOperDS(NodeConnectorId nodeConnectorId, long lporttag, String interfaceName,
+                                                          DataBroker dataBroker, WriteTransaction t) {
+        NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
+        TunnelInterfaceInventoryInfoKey tunnelInterfaceInventoryInfoKey = new TunnelInterfaceInventoryInfoKey(lporttag);
+        InstanceIdentifier<TunnelInterfaceInventoryInfo> inventoryIdentifier = InstanceIdentifier.builder(Nodes.class)
+                .child(Node.class, new NodeKey(nodeId))
+                .augmentation(TunnelInterfaceNames.class)
+                .child(TunnelInterfaceInventoryInfo.class, tunnelInterfaceInventoryInfoKey).build();
+        TunnelInterfaceInventoryInfoBuilder builder = new TunnelInterfaceInventoryInfoBuilder().setKey(tunnelInterfaceInventoryInfoKey)
+                .setTunIntfName(interfaceName);
+        t.put(LogicalDatastoreType.OPERATIONAL, inventoryIdentifier, builder.build(), true);
+    }
+
+    public static void removeInterfaceEntryFromInventoryOperDS(NodeConnectorId nodeConnectorId, long lporttag,
+                                                               String interfaceName, DataBroker dataBroker,
+                                                               WriteTransaction t) {
+        NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
+        TunnelInterfaceInventoryInfoKey tunnelInterfaceInventoryInfoKey = new TunnelInterfaceInventoryInfoKey(lporttag);
+        InstanceIdentifier<TunnelInterfaceInventoryInfo> inventoryIdentifier = InstanceIdentifier.builder(Nodes.class)
+                .child(Node.class, new NodeKey(nodeId))
+                .augmentation(TunnelInterfaceNames.class)
+                .child(TunnelInterfaceInventoryInfo.class, tunnelInterfaceInventoryInfoKey).build();
+        t.delete(LogicalDatastoreType.OPERATIONAL, inventoryIdentifier);
+    }
+
+    public static void removeInterfaceEntryFromInventoryOperDS(NodeConnectorId nodeConnectorId, long lporttag,
+                                                               DataBroker dataBroker) {
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+        NodeId nodeId = IfmUtil.getNodeIdFromNodeConnectorId(nodeConnectorId);
+        TunnelInterfaceInventoryInfoKey tunnelInterfaceInventoryInfoKey = new TunnelInterfaceInventoryInfoKey(lporttag);
+        InstanceIdentifier<TunnelInterfaceInventoryInfo> inventoryIdentifier = InstanceIdentifier.builder(Nodes.class)
+                .child(Node.class, new NodeKey(nodeId))
+                .augmentation(TunnelInterfaceNames.class)
+                .child(TunnelInterfaceInventoryInfo.class, tunnelInterfaceInventoryInfoKey).build();
+        t.delete(LogicalDatastoreType.OPERATIONAL, inventoryIdentifier);
+        t.submit(); // This is a Best-Effort Deletion. If Node is already removed, this may fail.
+    } */
+
+    public static InstanceIdentifier<Interface> getInterfaceIdentifier(InterfaceKey interfaceKey) {
+        InstanceIdentifier.InstanceIdentifierBuilder<Interface> interfaceInstanceIdentifierBuilder =
+                InstanceIdentifier.builder(Interfaces.class).child(Interface.class, interfaceKey);
+        return interfaceInstanceIdentifierBuilder.build();
+    }
+
+    public static Interface getInterfaceFromConfigDS(InterfaceKey interfaceKey, DataBroker dataBroker) {
+        InstanceIdentifier<Interface> interfaceId = getInterfaceIdentifier(interfaceKey);
+        Optional<Interface> interfaceOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceId, dataBroker);
+        if (!interfaceOptional.isPresent()) {
+            return null;
+        }
+
+        return interfaceOptional.get();
+    }
+
+    public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(String interfaceName, DataBroker dataBroker) {
+        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
+                IfmUtil.buildStateInterfaceId(interfaceName);
+        Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateOptional =
+                IfmUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker);
+        if (!ifStateOptional.isPresent()) {
+            return null;
+        }
+
+        return ifStateOptional.get();
+    }
+
+    public static Integer getUniqueId(IdManager idManager, String idKey) {
+        GetUniqueIdInput getIdInput = new GetUniqueIdInputBuilder()
+                .setPoolName(IfmConstants.IFM_LPORT_TAG_IDPOOL_NAME)
+                .setIdKey(idKey).build();
+
+        try {
+            Future<RpcResult<GetUniqueIdOutput>> result = idManager.
+                    getUniqueId(getIdInput);
+            RpcResult<GetUniqueIdOutput> rpcResult = result.get();
+            if(rpcResult.isSuccessful()) {
+                return rpcResult.getResult().getIdValue().intValue();
+            } else {
+                LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
+            }
+        } catch (NullPointerException | InterruptedException | ExecutionException e) {
+            LOG.warn("Exception when getting Unique Id",e);
+        }
+        return 0;
+    }
+
+    public static String getJobKey(String dpId, String portName) {
+        String jobKey = "";
+        if (dpId != null && !"".equals(dpId)) {
+            jobKey = dpId.toString() + ":";
+        }
+        jobKey = jobKey + portName;
+        return jobKey;
+    }
+
+    public static String getJobKey(BigInteger dpId, String portName) {
+        String jobKey = "";
+        if (dpId != null && dpId.longValue() != 0) {
+            jobKey = dpId.toString() + ":";
+        }
+        jobKey = jobKey + portName;
+        return jobKey;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceMetaUtils.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/commons/InterfaceMetaUtils.java
new file mode 100644 (file)
index 0000000..8367b8a
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.commons;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.BridgeInterfaceInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.BridgeRefInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.InterfaceChildInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class InterfaceMetaUtils {
+    public static InstanceIdentifier<BridgeRefEntry> getBridgeRefEntryIdentifier(BridgeRefEntryKey bridgeRefEntryKey) {
+        InstanceIdentifier.InstanceIdentifierBuilder<BridgeRefEntry> bridgeRefEntryInstanceIdentifierBuilder =
+                InstanceIdentifier.builder(BridgeRefInfo.class)
+                        .child(BridgeRefEntry.class, bridgeRefEntryKey);
+        return bridgeRefEntryInstanceIdentifierBuilder.build();
+    }
+
+    public static BridgeRefEntry getBridgeRefEntryFromOperDS(InstanceIdentifier<BridgeRefEntry> dpnBridgeEntryIid,
+                                                             DataBroker dataBroker) {
+        Optional<BridgeRefEntry> bridgeRefEntryOptional =
+                IfmUtil.read(LogicalDatastoreType.OPERATIONAL, dpnBridgeEntryIid, dataBroker);
+        if (!bridgeRefEntryOptional.isPresent()) {
+            return null;
+        }
+        return bridgeRefEntryOptional.get();
+    }
+
+    public static InstanceIdentifier<BridgeEntry> getBridgeEntryIdentifier(BridgeEntryKey bridgeEntryKey) {
+        InstanceIdentifier.InstanceIdentifierBuilder<BridgeEntry> bridgeEntryIdBuilder =
+                InstanceIdentifier.builder(BridgeInterfaceInfo.class).child(BridgeEntry.class, bridgeEntryKey);
+        return bridgeEntryIdBuilder.build();
+    }
+
+    public static BridgeEntry getBridgeEntryFromConfigDS(InstanceIdentifier<BridgeEntry> bridgeEntryInstanceIdentifier,
+                                                         DataBroker dataBroker) {
+        Optional<BridgeEntry> bridgeEntryOptional =
+                IfmUtil.read(LogicalDatastoreType.CONFIGURATION, bridgeEntryInstanceIdentifier, dataBroker);
+        if (!bridgeEntryOptional.isPresent()) {
+            return null;
+        }
+        return bridgeEntryOptional.get();
+    }
+
+    public static InstanceIdentifier<BridgeInterfaceEntry> getBridgeInterfaceEntryIdentifier(BridgeEntryKey bridgeEntryKey,
+                                                                                    BridgeInterfaceEntryKey bridgeInterfaceEntryKey) {
+        return InstanceIdentifier.builder(BridgeInterfaceInfo.class)
+                        .child(BridgeEntry.class, bridgeEntryKey)
+                        .child(BridgeInterfaceEntry.class, bridgeInterfaceEntryKey).build();
+
+    }
+
+    public static BridgeInterfaceEntry getBridgeInterfaceEntryFromConfigDS(
+            InstanceIdentifier<BridgeInterfaceEntry> bridgeInterfaceEntryInstanceIdentifier, DataBroker dataBroker) {
+        Optional<BridgeInterfaceEntry> bridgeInterfaceEntryOptional =
+                IfmUtil.read(LogicalDatastoreType.CONFIGURATION, bridgeInterfaceEntryInstanceIdentifier, dataBroker);
+        if (!bridgeInterfaceEntryOptional.isPresent()) {
+            return null;
+        }
+        return bridgeInterfaceEntryOptional.get();
+    }
+
+
+    public static void createBridgeInterfaceEntryInConfigDS(BridgeEntryKey bridgeEntryKey,
+                                                             BridgeInterfaceEntryKey bridgeInterfaceEntryKey,
+                                                             String childInterface,
+                                                             WriteTransaction t) {
+        InstanceIdentifier<BridgeInterfaceEntry> bridgeInterfaceEntryIid =
+                InterfaceMetaUtils.getBridgeInterfaceEntryIdentifier(bridgeEntryKey, bridgeInterfaceEntryKey);
+        BridgeInterfaceEntryBuilder entryBuilder = new BridgeInterfaceEntryBuilder().setKey(bridgeInterfaceEntryKey)
+                .setInterfaceName(childInterface);
+        t.put(LogicalDatastoreType.CONFIGURATION, bridgeInterfaceEntryIid, entryBuilder.build(), true);
+    }
+
+    public static void createBridgeInterfaceEntryInConfigDS(BridgeEntryKey bridgeEntryKey,
+                                                             BridgeInterfaceEntryKey bridgeInterfaceEntryKey,
+                                                             String childInterface,
+                                                             InstanceIdentifier<TerminationPoint> tpIid,
+                                                             WriteTransaction t) {
+        if (tpIid == null) {
+            createBridgeInterfaceEntryInConfigDS(bridgeEntryKey, bridgeInterfaceEntryKey, childInterface, t);
+            return;
+        }
+
+        InstanceIdentifier<BridgeInterfaceEntry> bridgeInterfaceEntryIid =
+                InterfaceMetaUtils.getBridgeInterfaceEntryIdentifier(bridgeEntryKey, bridgeInterfaceEntryKey);
+        BridgeInterfaceEntryBuilder entryBuilder = new BridgeInterfaceEntryBuilder().setKey(bridgeInterfaceEntryKey)
+                .setInterfaceName(childInterface);
+        t.put(LogicalDatastoreType.CONFIGURATION, bridgeInterfaceEntryIid, entryBuilder.build(), true);
+    }
+
+    public static InstanceIdentifier<InterfaceParentEntry> getInterfaceParentEntryIdentifier(
+            InterfaceParentEntryKey interfaceParentEntryKey) {
+        InstanceIdentifier.InstanceIdentifierBuilder<InterfaceParentEntry> intfIdBuilder =
+                InstanceIdentifier.builder(InterfaceChildInfo.class)
+                        .child(InterfaceParentEntry.class, interfaceParentEntryKey);
+        return intfIdBuilder.build();
+    }
+
+    public static InstanceIdentifier<InterfaceChildEntry> getInterfaceChildEntryIdentifier(
+            InterfaceParentEntryKey interfaceParentEntryKey, InterfaceChildEntryKey interfaceChildEntryKey) {
+        InstanceIdentifier.InstanceIdentifierBuilder<InterfaceChildEntry> intfIdBuilder =
+                InstanceIdentifier.builder(InterfaceChildInfo.class)
+                        .child(InterfaceParentEntry.class, interfaceParentEntryKey)
+                        .child(InterfaceChildEntry.class, interfaceChildEntryKey);
+        return intfIdBuilder.build();
+    }
+
+    public static InterfaceParentEntry getInterfaceParentEntryFromConfigDS(
+            InterfaceParentEntryKey interfaceParentEntryKey, DataBroker dataBroker) {
+        InstanceIdentifier<InterfaceParentEntry> intfParentIid =
+                getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
+
+        return getInterfaceParentEntryFromConfigDS(intfParentIid, dataBroker);
+    }
+
+    public static InterfaceParentEntry getInterfaceParentEntryFromConfigDS(
+            InstanceIdentifier<InterfaceParentEntry> intfId, DataBroker dataBroker) {
+        Optional<InterfaceParentEntry> interfaceParentEntryOptional =
+                IfmUtil.read(LogicalDatastoreType.CONFIGURATION, intfId, dataBroker);
+        if (!interfaceParentEntryOptional.isPresent()) {
+            return null;
+        }
+        return interfaceParentEntryOptional.get();
+    }
+
+    public static InterfaceChildEntry getInterfaceChildEntryFromConfigDS(InterfaceParentEntryKey interfaceParentEntryKey,
+                                                                         InterfaceChildEntryKey interfaceChildEntryKey,
+                                                                         DataBroker dataBroker) {
+        InstanceIdentifier<InterfaceChildEntry> intfChildIid =
+                getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
+
+        return getInterfaceChildEntryFromConfigDS(intfChildIid, dataBroker);
+    }
+
+    public static InterfaceChildEntry getInterfaceChildEntryFromConfigDS(
+            InstanceIdentifier<InterfaceChildEntry> intfChildIid, DataBroker dataBroker) {
+        Optional<InterfaceChildEntry> interfaceChildEntryOptional =
+                IfmUtil.read(LogicalDatastoreType.CONFIGURATION, intfChildIid, dataBroker);
+        if (!interfaceChildEntryOptional.isPresent()) {
+            return null;
+        }
+        return interfaceChildEntryOptional.get();
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceConfigListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceConfigListener.java
new file mode 100644 (file)
index 0000000..a8457c5
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * 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
+ */
+
+package org.opendaylight.vpnservice.interfacemgr.listeners;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsInterfaceConfigAddHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsInterfaceConfigRemoveHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsInterfaceConfigUpdateHelper;
+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.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+/**
+ * This class listens for interface creation/removal/update in Configuration DS.
+ * This is used to handle interfaces for base of-ports.
+ */
+public class InterfaceConfigListener extends AsyncDataTreeChangeListenerBase<Interface, InterfaceConfigListener> {
+    private static final Logger LOG = LoggerFactory.getLogger(InterfaceConfigListener.class);
+    private DataBroker dataBroker;
+    private IdManager idManager;
+
+    public InterfaceConfigListener(final DataBroker dataBroker, final IdManager idManager) {
+        super(Interface.class, InterfaceConfigListener.class);
+        this.dataBroker = dataBroker;
+        this.idManager = idManager;
+    }
+
+    @Override
+    protected InstanceIdentifier<Interface> getWildCardPath() {
+        return InstanceIdentifier.create(Interfaces.class).child(Interface.class);
+    }
+
+    @Override
+    protected InterfaceConfigListener getDataTreeChangeListener() {
+        return InterfaceConfigListener.this;
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<Interface> key, Interface interfaceOld) {
+        LOG.debug("Received Interface Remove Event: {}, {}", key, interfaceOld);
+        String ifName = interfaceOld.getName();
+        String parentInterface = null;
+
+        ParentRefs parentRefs = interfaceOld.getAugmentation(ParentRefs.class);
+        if (parentRefs != null) {
+            parentInterface = parentRefs.getParentInterface();
+            if (parentInterface != null && !parentInterface.equals(ifName)) {
+                return;
+            }
+            if (parentRefs.getDatapathNodeIdentifier() == null) {
+                return;
+            }
+        }
+
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+        RendererConfigRemoveWorker configWorker = new RendererConfigRemoveWorker(key, interfaceOld, ifName, parentRefs);
+        coordinator.enqueueJob(ifName, configWorker);
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<Interface> key, Interface interfaceOld, Interface interfaceNew) {
+        LOG.debug("Received Interface Update Event: {}, {}, {}", key, interfaceOld, interfaceNew);
+        String ifNameNew = interfaceNew.getName();
+        String parentInterface = null;
+
+        ParentRefs parentRefs = interfaceNew.getAugmentation(ParentRefs.class);
+        if (parentRefs != null) {
+            parentInterface = parentRefs.getParentInterface();
+        }
+
+        if (parentInterface != null && !parentInterface.equals(ifNameNew)) {
+            return;
+        }
+
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+        RendererConfigUpdateWorker worker = new RendererConfigUpdateWorker(key, interfaceOld, interfaceNew, ifNameNew);
+        coordinator.enqueueJob(ifNameNew, worker);
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<Interface> key, Interface interfaceNew) {
+        LOG.debug("Received Interface Add Event: {}, {}", key, interfaceNew);
+        String ifName = interfaceNew.getName();
+        String parentInterface = null;
+
+        ParentRefs parentRefs = interfaceNew.getAugmentation(ParentRefs.class);
+        if (parentRefs != null) {
+            parentInterface = parentRefs.getParentInterface();
+        }
+
+        if (parentInterface != null && !parentInterface.equals(ifName)) {
+            return;
+        }
+
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+        RendererConfigAddWorker configWorker = new RendererConfigAddWorker(key, interfaceNew, parentRefs, ifName);
+        coordinator.enqueueJob(ifName, configWorker);
+    }
+
+    private class RendererConfigAddWorker implements Callable<List<ListenableFuture<Void>>> {
+        InstanceIdentifier<Interface> key;
+        Interface interfaceNew;
+        String portName;
+        ParentRefs parentRefs;
+
+        public RendererConfigAddWorker(InstanceIdentifier<Interface> key, Interface interfaceNew,
+                                       ParentRefs parentRefs, String portName) {
+            this.key = key;
+            this.interfaceNew = interfaceNew;
+            this.portName = portName;
+            this.parentRefs = parentRefs;
+        }
+
+        @Override
+        public List<ListenableFuture<Void>> call() throws Exception {
+            // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+            // to call the respective helpers.
+            return OvsInterfaceConfigAddHelper.addConfiguration(dataBroker, parentRefs, interfaceNew, idManager);
+        }
+
+        @Override
+        public String toString() {
+            return "RendererConfigAddWorker{" +
+                    "key=" + key +
+                    ", interfaceNew=" + interfaceNew +
+                    ", portName='" + portName + '\'' +
+                    '}';
+        }
+    }
+
+    /**
+     *
+     */
+    private class RendererConfigUpdateWorker implements Callable {
+        InstanceIdentifier<Interface> key;
+        Interface interfaceOld;
+        Interface interfaceNew;
+        String portNameNew;
+
+        public RendererConfigUpdateWorker(InstanceIdentifier<Interface> key, Interface interfaceOld,
+                                          Interface interfaceNew, String portNameNew) {
+            this.key = key;
+            this.interfaceOld = interfaceOld;
+            this.interfaceNew = interfaceNew;
+            this.portNameNew = portNameNew;
+        }
+
+        @Override
+        public List<ListenableFuture<Void>> call() throws Exception {
+            // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+            // to call the respective helpers.
+            return OvsInterfaceConfigUpdateHelper.updateConfiguration(dataBroker, idManager, interfaceNew, interfaceOld);
+        }
+
+        @Override
+        public String toString() {
+            return "RendererConfigUpdateWorker{" +
+                    "key=" + key +
+                    ", interfaceOld=" + interfaceOld +
+                    ", interfaceNew=" + interfaceNew +
+                    ", portNameNew='" + portNameNew + '\'' +
+                    '}';
+        }
+    }
+
+    /**
+     *
+     */
+    private class RendererConfigRemoveWorker implements Callable {
+        InstanceIdentifier<Interface> key;
+        Interface interfaceOld;
+        String portName;
+        ParentRefs parentRefs;
+
+        public RendererConfigRemoveWorker(InstanceIdentifier<Interface> key, Interface interfaceOld, String portName,
+                                          ParentRefs parentRefs) {
+            this.key = key;
+            this.interfaceOld = interfaceOld;
+            this.portName = portName;
+            this.parentRefs = parentRefs;
+        }
+
+        @Override
+        public List<ListenableFuture<Void>> call() throws Exception {
+            // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+            // to call the respective helpers.
+            return OvsInterfaceConfigRemoveHelper.removeConfiguration(dataBroker, interfaceOld, idManager, parentRefs);
+        }
+
+        @Override
+        public String toString() {
+            return "RendererConfigRemoveWorker{" +
+                    "key=" + key +
+                    ", interfaceOld=" + interfaceOld +
+                    ", portName='" + portName + '\'' +
+                    '}';
+        }
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceInventoryStateListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceInventoryStateListener.java
new file mode 100644 (file)
index 0000000..8629a75
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.listeners;
+
+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;
+import org.opendaylight.vpnservice.datastoreutils.AsyncDataChangeListenerBase;
+import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceStateAddHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceStateRemoveHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceStateUpdateHelper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.Callable;
+
+/**
+ *
+ * This Class is a Data Change Listener for FlowCapableNodeConnector updates.
+ * This creates an entry in the interface-state OperDS for every node-connector used.
+ *
+ * NOTE: This class just creates an ifstate entry whose interface-name will be the same as the node-connector portname.
+ * If PortName is not unique across DPNs, this implementation can have problems.
+ */
+
+public class InterfaceInventoryStateListener extends AsyncDataChangeListenerBase<FlowCapableNodeConnector, InterfaceInventoryStateListener> implements AutoCloseable{
+    private static final Logger LOG = LoggerFactory.getLogger(InterfaceInventoryStateListener.class);
+    private DataBroker dataBroker;
+
+    public InterfaceInventoryStateListener(final DataBroker dataBroker) {
+        super(FlowCapableNodeConnector.class, InterfaceInventoryStateListener.class);
+        this.dataBroker = dataBroker;
+    }
+
+    @Override
+    protected InstanceIdentifier<FlowCapableNodeConnector> getWildCardPath() {
+        return InstanceIdentifier.create(Nodes.class).child(Node.class).child(NodeConnector.class)
+                .augmentation(FlowCapableNodeConnector.class);
+    }
+
+    @Override
+    protected DataChangeListener getDataChangeListener() {
+        return InterfaceInventoryStateListener.this;
+    }
+
+    @Override
+    protected AsyncDataBroker.DataChangeScope getDataChangeScope() {
+        return AsyncDataBroker.DataChangeScope.BASE;
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<FlowCapableNodeConnector> key,
+                          FlowCapableNodeConnector flowCapableNodeConnectorOld) {
+        LOG.debug("Received NodeConnector Remove Event: {}, {}", key, flowCapableNodeConnectorOld);
+        String portName = flowCapableNodeConnectorOld.getName();
+        NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+
+        InterfaceStateRemoveWorker interfaceStateRemoveWorker = new InterfaceStateRemoveWorker(key,
+                flowCapableNodeConnectorOld, portName);
+        coordinator.enqueueJob(portName, interfaceStateRemoveWorker);
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<FlowCapableNodeConnector> key, FlowCapableNodeConnector fcNodeConnectorOld,
+                          FlowCapableNodeConnector fcNodeConnectorNew) {
+        LOG.debug("Received NodeConnector Update Event: {}, {}, {}", key, fcNodeConnectorOld, fcNodeConnectorNew);
+        String portName = fcNodeConnectorNew.getName();
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+
+        InterfaceStateUpdateWorker interfaceStateUpdateWorker = new InterfaceStateUpdateWorker(key, fcNodeConnectorOld,
+                fcNodeConnectorNew, portName);
+        coordinator.enqueueJob(portName, interfaceStateUpdateWorker);
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<FlowCapableNodeConnector> key, FlowCapableNodeConnector fcNodeConnectorNew) {
+        LOG.debug("Received NodeConnector Add Event: {}, {}", key, fcNodeConnectorNew);
+        String portName = fcNodeConnectorNew.getName();
+        NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
+
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+        InterfaceStateAddWorker ifStateAddWorker = new InterfaceStateAddWorker(nodeConnectorId,
+                fcNodeConnectorNew, portName);
+        coordinator.enqueueJob(portName, ifStateAddWorker);
+    }
+
+    private class InterfaceStateAddWorker implements Callable {
+        private final NodeConnectorId nodeConnectorId;
+        private final FlowCapableNodeConnector fcNodeConnectorNew;
+        private final String portName;
+
+        public InterfaceStateAddWorker(NodeConnectorId nodeConnectorId,
+                                       FlowCapableNodeConnector fcNodeConnectorNew,
+                                       String portName) {
+            this.nodeConnectorId = nodeConnectorId;
+            this.fcNodeConnectorNew = fcNodeConnectorNew;
+            this.portName = portName;
+        }
+
+        @Override
+        public Object call() throws Exception {
+            // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+            // to call the respective helpers.
+             return OvsInterfaceStateAddHelper.addState(dataBroker, nodeConnectorId,
+                     portName, fcNodeConnectorNew);
+        }
+
+        @Override
+        public String toString() {
+            return "InterfaceStateAddWorker{" +
+                    "nodeConnectorId=" + nodeConnectorId +
+                    ", fcNodeConnectorNew=" + fcNodeConnectorNew +
+                    ", portName='" + portName + '\'' +
+                    '}';
+        }
+    }
+
+    private class InterfaceStateUpdateWorker implements Callable {
+        private InstanceIdentifier<FlowCapableNodeConnector> key;
+        private final FlowCapableNodeConnector fcNodeConnectorOld;
+        private final FlowCapableNodeConnector fcNodeConnectorNew;
+        private String portName;
+
+
+        public InterfaceStateUpdateWorker(InstanceIdentifier<FlowCapableNodeConnector> key,
+                                          FlowCapableNodeConnector fcNodeConnectorOld,
+                                          FlowCapableNodeConnector fcNodeConnectorNew,
+                                          String portName) {
+            this.key = key;
+            this.fcNodeConnectorOld = fcNodeConnectorOld;
+            this.fcNodeConnectorNew = fcNodeConnectorNew;
+            this.portName = portName;
+        }
+
+        @Override
+        public Object call() throws Exception {
+            // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+            // to call the respective helpers.
+            return OvsInterfaceStateUpdateHelper.updateState(key, dataBroker, portName,
+                    fcNodeConnectorNew, fcNodeConnectorOld);
+        }
+
+        @Override
+        public String toString() {
+            return "InterfaceStateUpdateWorker{" +
+                    "key=" + key +
+                    ", fcNodeConnectorOld=" + fcNodeConnectorOld +
+                    ", fcNodeConnectorNew=" + fcNodeConnectorNew +
+                    ", portName='" + portName + '\'' +
+                    '}';
+        }
+    }
+
+    private class InterfaceStateRemoveWorker implements Callable {
+        InstanceIdentifier<FlowCapableNodeConnector> key;
+        FlowCapableNodeConnector fcNodeConnectorOld;
+        private final String portName;
+
+        public InterfaceStateRemoveWorker(InstanceIdentifier<FlowCapableNodeConnector> key,
+                                          FlowCapableNodeConnector fcNodeConnectorOld,
+                                          String portName) {
+            this.key = key;
+            this.fcNodeConnectorOld = fcNodeConnectorOld;
+            this.portName = portName;
+        }
+
+        @Override
+        public Object call() throws Exception {
+            // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+            // to call the respective helpers.
+            return OvsInterfaceStateRemoveHelper.removeState(key, dataBroker, portName, fcNodeConnectorOld);
+        }
+
+        @Override
+        public String toString() {
+            return "InterfaceStateRemoveWorker{" +
+                    "key=" + key +
+                    ", fcNodeConnectorOld=" + fcNodeConnectorOld +
+                    ", portName='" + portName + '\'' +
+                    '}';
+        }
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceTopologyStateListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/InterfaceTopologyStateListener.java
new file mode 100644 (file)
index 0000000..db2ebcd
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.listeners;
+
+import com.google.common.util.concurrent.ListenableFuture;
+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;
+import org.opendaylight.vpnservice.datastoreutils.AsyncDataChangeListenerBase;
+import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceTopologyStateAddHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers.OvsInterfaceTopologyStateRemoveHelper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+public class InterfaceTopologyStateListener extends AsyncDataChangeListenerBase<OvsdbBridgeAugmentation, InterfaceTopologyStateListener> {
+    private static final Logger LOG = LoggerFactory.getLogger(InterfaceTopologyStateListener.class);
+    private DataBroker dataBroker;
+
+    public InterfaceTopologyStateListener(DataBroker dataBroker) {
+        super(OvsdbBridgeAugmentation.class, InterfaceTopologyStateListener.class);
+        this.dataBroker = dataBroker;
+    }
+
+    @Override
+    protected InstanceIdentifier<OvsdbBridgeAugmentation> getWildCardPath() {
+        return InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class)
+                .child(Node.class).augmentation(OvsdbBridgeAugmentation.class).build();
+    }
+
+    @Override
+    protected DataChangeListener getDataChangeListener() {
+        return InterfaceTopologyStateListener.this;
+    }
+
+    @Override
+    protected AsyncDataBroker.DataChangeScope getDataChangeScope() {
+        return AsyncDataBroker.DataChangeScope.BASE;
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<OvsdbBridgeAugmentation> identifier, OvsdbBridgeAugmentation bridgeOld) {
+        LOG.debug("Received Remove DataChange Notification for identifier: {}, ovsdbBridgeAugmentation: {}",
+                identifier, bridgeOld);
+        DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
+        RendererStateRemoveWorker rendererStateRemoveWorker = new RendererStateRemoveWorker(identifier, bridgeOld);
+        jobCoordinator.enqueueJob(bridgeOld.getBridgeName().getValue() + bridgeOld.getDatapathId(), rendererStateRemoveWorker);
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<OvsdbBridgeAugmentation> identifier, OvsdbBridgeAugmentation bridgeOld,
+                          OvsdbBridgeAugmentation bridgeNew) {
+        LOG.info("Received Update DataChange Notification for identifier: {}, ovsdbBridgeAugmentation old: {}, new: {}." +
+                "No Action Performed.", identifier, bridgeOld, bridgeNew);
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<OvsdbBridgeAugmentation> identifier, OvsdbBridgeAugmentation bridgeNew) {
+        LOG.debug("Received Add DataChange Notification for identifier: {}, ovsdbBridgeAugmentation: {}",
+                identifier, bridgeNew);
+        DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
+        RendererStateAddWorker rendererStateAddWorker = new RendererStateAddWorker(identifier, bridgeNew);
+        jobCoordinator.enqueueJob(bridgeNew.getBridgeName().getValue() + bridgeNew.getDatapathId(), rendererStateAddWorker);
+    }
+
+    private class RendererStateAddWorker implements Callable<List<ListenableFuture<Void>>> {
+        InstanceIdentifier<OvsdbBridgeAugmentation> instanceIdentifier;
+        OvsdbBridgeAugmentation bridgeNew;
+
+
+        public RendererStateAddWorker(InstanceIdentifier<OvsdbBridgeAugmentation> instanceIdentifier,
+                                      OvsdbBridgeAugmentation bridgeNew) {
+            this.instanceIdentifier = instanceIdentifier;
+            this.bridgeNew = bridgeNew;
+        }
+
+        @Override
+        public List<ListenableFuture<Void>> call() throws Exception {
+            // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+            // to call the respective helpers.
+            return OvsInterfaceTopologyStateAddHelper.addPortToBridge(instanceIdentifier,
+                    bridgeNew, dataBroker);
+        }
+    }
+
+    private class RendererStateRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
+        InstanceIdentifier<OvsdbBridgeAugmentation> instanceIdentifier;
+        OvsdbBridgeAugmentation bridgeNew;
+
+
+        public RendererStateRemoveWorker(InstanceIdentifier<OvsdbBridgeAugmentation> instanceIdentifier,
+                                         OvsdbBridgeAugmentation bridgeNew) {
+            this.instanceIdentifier = instanceIdentifier;
+            this.bridgeNew = bridgeNew;
+        }
+
+        @Override
+        public List<ListenableFuture<Void>> call() throws Exception {
+            // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+            // to call the respective helpers.
+            return OvsInterfaceTopologyStateRemoveHelper.removePortFromBridge(instanceIdentifier,
+                    bridgeNew, dataBroker);
+        }
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/VlanMemberConfigListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/listeners/VlanMemberConfigListener.java
new file mode 100644 (file)
index 0000000..2d94716
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.listeners;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsVlanMemberConfigAddHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsVlanMemberConfigRemoveHelper;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers.OvsVlanMemberConfigUpdateHelper;
+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.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+public class VlanMemberConfigListener extends AsyncDataTreeChangeListenerBase<Interface, VlanMemberConfigListener> {
+    private static final Logger LOG = LoggerFactory.getLogger(VlanMemberConfigListener.class);
+    private DataBroker dataBroker;
+    private IdManager idManager;
+
+    public VlanMemberConfigListener(final DataBroker dataBroker, final IdManager idManager) {
+        super(Interface.class, VlanMemberConfigListener.class);
+        this.dataBroker = dataBroker;
+        this.idManager = idManager;
+    }
+
+    @Override
+    protected InstanceIdentifier<Interface> getWildCardPath() {
+        return InstanceIdentifier.create(Interfaces.class).child(Interface.class);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<Interface> key, Interface interfaceOld) {
+        IfL2vlan ifL2vlan = interfaceOld.getAugmentation(IfL2vlan.class);
+        if (ifL2vlan == null) {
+            return;
+        }
+
+        if (ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.TrunkMember) {
+            return;
+        }
+
+        ParentRefs parentRefs = interfaceOld.getAugmentation(ParentRefs.class);
+        if (parentRefs == null) {
+            LOG.error("Attempt to remove Vlan Trunk-Member {} without a parent interface", interfaceOld);
+            return;
+        }
+
+        String lowerLayerIf = parentRefs.getParentInterface();
+        if (lowerLayerIf.equals(interfaceOld.getName())) {
+            LOG.error("Attempt to remove Vlan Trunk-Member {} with same parent interface name.", interfaceOld);
+            return;
+        }
+
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+        RendererConfigRemoveWorker removeWorker = new RendererConfigRemoveWorker(key, interfaceOld, parentRefs, ifL2vlan);
+        coordinator.enqueueJob(lowerLayerIf, removeWorker);
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<Interface> key, Interface interfaceOld, Interface interfaceNew) {
+        IfL2vlan ifL2vlanNew = interfaceNew.getAugmentation(IfL2vlan.class);
+        if (ifL2vlanNew == null) {
+            return;
+        }
+        if (ifL2vlanNew.getL2vlanMode() != IfL2vlan.L2vlanMode.TrunkMember) {
+            LOG.error("Configuration Error. Attempt to modify Vlan Mode of interface: {} " +
+                    "to interface: {}", interfaceOld, interfaceNew);
+            return;
+        }
+
+        ParentRefs parentRefsNew = interfaceNew.getAugmentation(ParentRefs.class);
+        if (parentRefsNew == null) {
+            LOG.error("Configuration Error. Attempt to update Vlan Trunk-Member {} without a " +
+                    "parent interface", interfaceNew);
+            return;
+        }
+
+        String lowerLayerIf = parentRefsNew.getParentInterface();
+        if (lowerLayerIf.equals(interfaceNew.getName())) {
+            LOG.error("Configuration Error. Attempt to update Vlan Trunk-Member {} with same parent " +
+                    "interface name.", interfaceNew);
+            return;
+        }
+
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+        RendererConfigUpdateWorker updateWorker = new RendererConfigUpdateWorker(key, interfaceNew, interfaceOld,
+                parentRefsNew, ifL2vlanNew);
+        coordinator.enqueueJob(lowerLayerIf, updateWorker);
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<Interface> key, Interface interfaceNew) {
+        IfL2vlan ifL2vlan = interfaceNew.getAugmentation(IfL2vlan.class);
+        if (ifL2vlan == null) {
+            return;
+        }
+
+        if (ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.TrunkMember) {
+            return;
+        }
+
+        ParentRefs parentRefs = interfaceNew.getAugmentation(ParentRefs.class);
+        if (parentRefs == null) {
+            LOG.error("Attempt to add Vlan Trunk-Member {} without a parent interface", interfaceNew);
+            return;
+        }
+
+        String lowerLayerIf = parentRefs.getParentInterface();
+        if (lowerLayerIf.equals(interfaceNew.getName())) {
+            LOG.error("Attempt to add Vlan Trunk-Member {} with same parent interface name.", interfaceNew);
+            return;
+        }
+
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+        RendererConfigAddWorker configWorker = new RendererConfigAddWorker(key, interfaceNew, parentRefs, ifL2vlan);
+        coordinator.enqueueJob(lowerLayerIf, configWorker);
+    }
+
+    @Override
+    protected VlanMemberConfigListener getDataTreeChangeListener() {
+        return VlanMemberConfigListener.this;
+    }
+
+    private class RendererConfigAddWorker implements Callable<List<ListenableFuture<Void>>> {
+        InstanceIdentifier<Interface> key;
+        Interface interfaceNew;
+        IfL2vlan ifL2vlan;
+        ParentRefs parentRefs;
+
+        public RendererConfigAddWorker(InstanceIdentifier<Interface> key, Interface interfaceNew,
+                                       ParentRefs parentRefs, IfL2vlan ifL2vlan) {
+            this.key = key;
+            this.interfaceNew = interfaceNew;
+            this.ifL2vlan = ifL2vlan;
+            this.parentRefs = parentRefs;
+        }
+
+        @Override
+        public List<ListenableFuture<Void>> call() throws Exception {
+            // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+            // to call the respective helpers.
+            return OvsVlanMemberConfigAddHelper.addConfiguration(dataBroker, parentRefs, interfaceNew,
+                    ifL2vlan, idManager);
+        }
+    }
+
+    private class RendererConfigUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
+        InstanceIdentifier<Interface> key;
+        Interface interfaceNew;
+        Interface interfaceOld;
+        IfL2vlan ifL2vlanNew;
+        ParentRefs parentRefsNew;
+
+        public RendererConfigUpdateWorker(InstanceIdentifier<Interface> key, Interface interfaceNew,
+                                       Interface interfaceOld, ParentRefs parentRefsNew, IfL2vlan ifL2vlanNew) {
+            this.key = key;
+            this.interfaceNew = interfaceNew;
+            this.interfaceOld = interfaceOld;
+            this.ifL2vlanNew = ifL2vlanNew;
+            this.parentRefsNew = parentRefsNew;
+        }
+
+        @Override
+        public List<ListenableFuture<Void>> call() throws Exception {
+            // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+            // to call the respective helpers.
+            return OvsVlanMemberConfigUpdateHelper.updateConfiguration(dataBroker, parentRefsNew, interfaceOld,
+                    ifL2vlanNew, interfaceNew, idManager);
+        }
+    }
+
+    private class RendererConfigRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
+        InstanceIdentifier<Interface> key;
+        Interface interfaceOld;
+        IfL2vlan ifL2vlan;
+        ParentRefs parentRefs;
+
+        public RendererConfigRemoveWorker(InstanceIdentifier<Interface> key, Interface interfaceOld,
+                                          ParentRefs parentRefs, IfL2vlan ifL2vlan) {
+            this.key = key;
+            this.interfaceOld = interfaceOld;
+            this.ifL2vlan = ifL2vlan;
+            this.parentRefs = parentRefs;
+        }
+
+        @Override
+        public List<ListenableFuture<Void>> call() throws Exception {
+            // If another renderer(for eg : CSS) needs to be supported, check can be performed here
+            // to call the respective helpers.
+            return OvsVlanMemberConfigRemoveHelper.removeConfiguration(dataBroker, parentRefs, interfaceOld,
+                    ifL2vlan, idManager);
+        }
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigAddHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigAddHelper.java
new file mode 100644 (file)
index 0000000..cc26192
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities.SouthboundUtils;
+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.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsInterfaceConfigAddHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceConfigAddHelper.class);
+
+    public static List<ListenableFuture<Void>> addConfiguration(DataBroker dataBroker, ParentRefs parentRefs,
+                                                                Interface interfaceNew, IdManager idManager) {
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+        IfTunnel ifTunnel = interfaceNew.getAugmentation(IfTunnel.class);
+        if (ifTunnel != null) {
+            addTunnelConfiguration(dataBroker, parentRefs, interfaceNew, idManager, t);
+            futures.add(t.submit());
+            return futures;
+        }
+
+        addVlanConfiguration(interfaceNew, t, dataBroker);
+        futures.add(t.submit());
+        return futures;
+    }
+
+    private static void addVlanConfiguration(Interface interfaceNew, WriteTransaction t, DataBroker dataBroker) {
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+                InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceNew.getName(), dataBroker);
+        if (ifState == null) {
+            return;
+        }
+        updateStateEntry(interfaceNew, t, ifState);
+
+        IfL2vlan ifL2vlan = interfaceNew.getAugmentation(IfL2vlan.class);
+        if (ifL2vlan == null || ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) {
+            return;
+        }
+
+        InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(interfaceNew.getName());
+        InterfaceParentEntry interfaceParentEntry =
+                InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
+        if (interfaceParentEntry == null) {
+            return;
+        }
+
+        List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
+        if (interfaceChildEntries == null) {
+            return;
+        }
+
+        OperStatus operStatus = ifState.getOperStatus();
+        PhysAddress physAddress = ifState.getPhysAddress();
+        AdminStatus adminStatus = ifState.getAdminStatus();
+        NodeConnectorId nodeConnectorId = new NodeConnectorId(ifState.getLowerLayerIf().get(0));
+
+        //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100.
+        for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
+            InterfaceKey childIfKey = new InterfaceKey(interfaceChildEntry.getChildInterface());
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface ifaceChild =
+                    InterfaceManagerCommonUtils.getInterfaceFromConfigDS(childIfKey, dataBroker);
+
+            if (!ifaceChild.isEnabled()) {
+                operStatus = OperStatus.Down;
+            }
+
+            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId =
+                    IfmUtil.buildStateInterfaceId(ifaceChild.getName());
+            List<String> childLowerLayerIfList = new ArrayList<>();
+            childLowerLayerIfList.add(0, nodeConnectorId.getValue());
+            childLowerLayerIfList.add(1, interfaceNew.getName());
+            InterfaceBuilder childIfaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus)
+                    .setOperStatus(operStatus).setPhysAddress(physAddress).setLowerLayerIf(childLowerLayerIfList);
+            childIfaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifaceChild.getName()));
+            t.put(LogicalDatastoreType.OPERATIONAL, ifChildStateId, childIfaceBuilder.build(), true);
+        }
+    }
+
+    private static void addTunnelConfiguration(DataBroker dataBroker, ParentRefs parentRefs,
+                                              Interface interfaceNew, IdManager idManager,
+                                              WriteTransaction t) {
+        if (parentRefs == null) {
+            LOG.warn("ParentRefs for interface: {} Not Found. " +
+                    "Creation of Tunnel OF-Port not supported when dpid not provided.", interfaceNew.getName());
+            return;
+        }
+
+        BigInteger dpId = parentRefs.getDatapathNodeIdentifier();
+        if (dpId == null) {
+            LOG.warn("dpid for interface: {} Not Found. No DPID provided. " +
+                    "Creation of OF-Port not supported.", interfaceNew.getName());
+            return;
+        }
+
+        createBridgeEntryIfNotPresent(dpId, dataBroker, t);
+
+        BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId);
+        InstanceIdentifier<BridgeRefEntry> dpnBridgeEntryIid =
+                InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey);
+        BridgeRefEntry bridgeRefEntry =
+                InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker);
+        BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(dpId);
+        BridgeInterfaceEntryKey bridgeInterfaceEntryKey = new BridgeInterfaceEntryKey(interfaceNew.getName());
+        if (bridgeRefEntry == null) {
+            InterfaceMetaUtils.createBridgeInterfaceEntryInConfigDS(bridgeEntryKey, bridgeInterfaceEntryKey,
+                    interfaceNew.getName(), t);
+            return;
+        }
+
+        InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
+                (InstanceIdentifier<OvsdbBridgeAugmentation>)bridgeRefEntry.getBridgeReference().getValue();
+        Optional<OvsdbBridgeAugmentation> bridgeNodeOptional =
+                IfmUtil.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
+        if (bridgeNodeOptional.isPresent()) {
+            OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNodeOptional.get();
+            String bridgeName = ovsdbBridgeAugmentation.getBridgeName().getValue();
+            SouthboundUtils.addPortToBridge(bridgeIid, interfaceNew,
+                    ovsdbBridgeAugmentation, bridgeName, interfaceNew.getName(), dataBroker, t);
+        }
+
+        InstanceIdentifier<TerminationPoint> tpIid = SouthboundUtils.createTerminationPointInstanceIdentifier(
+            InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), interfaceNew.getName());
+        InterfaceMetaUtils.createBridgeInterfaceEntryInConfigDS(bridgeEntryKey, bridgeInterfaceEntryKey,
+                interfaceNew.getName(), tpIid, t);
+    }
+
+    private static void updateStateEntry(Interface interfaceNew, WriteTransaction t,
+                                         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
+        OperStatus operStatus;
+        if (!interfaceNew.isEnabled() && ifState.getOperStatus() != OperStatus.Down) {
+            operStatus = OperStatus.Down;
+            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
+                    IfmUtil.buildStateInterfaceId(interfaceNew.getName());
+            InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
+            ifaceBuilder.setOperStatus(operStatus);
+            ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceNew.getName()));
+            t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
+        }
+    }
+
+    private static void createBridgeEntryIfNotPresent(BigInteger dpId,
+                                                      DataBroker dataBroker, WriteTransaction t) {
+        BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(dpId);
+        InstanceIdentifier<BridgeEntry> bridgeEntryInstanceIdentifier =
+                InterfaceMetaUtils.getBridgeEntryIdentifier(bridgeEntryKey);
+        BridgeEntry bridgeEntry =
+                InterfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryInstanceIdentifier,
+                        dataBroker);
+        if (bridgeEntry == null) {
+            BridgeEntryBuilder bridgeEntryBuilder = new BridgeEntryBuilder().setKey(bridgeEntryKey)
+                    .setDpid(dpId);
+            t.put(LogicalDatastoreType.CONFIGURATION, bridgeEntryInstanceIdentifier, bridgeEntryBuilder.build(), true);
+        }
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigRemoveHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigRemoveHelper.java
new file mode 100644 (file)
index 0000000..edb6d27
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities.SouthboundUtils;
+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.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsInterfaceConfigRemoveHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceConfigRemoveHelper.class);
+
+    public static List<ListenableFuture<Void>> removeConfiguration(DataBroker dataBroker, Interface interfaceOld,
+                                                                   IdManager idManager, ParentRefs parentRefs) {
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+        IfTunnel ifTunnel = interfaceOld.getAugmentation(IfTunnel.class);
+        if (ifTunnel != null) {
+            removeTunnelConfiguration(parentRefs, dataBroker, interfaceOld, idManager, t);
+            futures.add(t.submit());
+            return futures;
+        }
+
+        removeVlanConfiguration(dataBroker, interfaceOld, t);
+
+        /* FIXME: Deallocate ID from Idmanager. */
+
+        futures.add(t.submit());
+        return futures;
+    }
+
+    private static void removeVlanConfiguration(DataBroker dataBroker, Interface interfaceOld, WriteTransaction t) {
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+                InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceOld.getName(), dataBroker);
+        if (ifState == null) {
+            return;
+        }
+
+        String ncStr = ifState.getLowerLayerIf().get(0);
+        NodeConnectorId nodeConnectorId = new NodeConnectorId(ncStr);
+        NodeConnector nodeConnector =
+                InterfaceManagerCommonUtils.getNodeConnectorFromInventoryOperDS(nodeConnectorId, dataBroker);
+        FlowCapableNodeConnector flowCapableNodeConnector =
+                nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
+        //State state = flowCapableNodeConnector.getState();
+        OperStatus operStatus = flowCapableNodeConnector == null ? OperStatus.Down : OperStatus.Up;
+
+        if (ifState.getOperStatus() != operStatus) {
+            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
+                    IfmUtil.buildStateInterfaceId(interfaceOld.getName());
+            InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
+            ifaceBuilder.setOperStatus(operStatus);
+            ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceOld.getName()));
+            t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
+        }
+
+        IfL2vlan ifL2vlan = interfaceOld.getAugmentation(IfL2vlan.class);
+        if (ifL2vlan == null || ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) {
+            return;
+        }
+
+        // For Vlan-Trunk Interface, remove the trunk-member operstates as well...
+        InterfaceKey interfaceKey = new InterfaceKey(interfaceOld.getName());
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+                InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+        if (iface == null) {
+            return;
+        }
+
+        InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(iface.getName());
+        InterfaceParentEntry interfaceParentEntry =
+                InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
+        if (interfaceParentEntry == null) {
+            return;
+        }
+
+        List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
+        if (interfaceChildEntries == null) {
+            return;
+        }
+
+        //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100.
+        for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
+            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId =
+                    IfmUtil.buildStateInterfaceId(interfaceChildEntry.getChildInterface());
+            t.delete(LogicalDatastoreType.OPERATIONAL, ifChildStateId);
+        }
+    }
+
+    private static void removeTunnelConfiguration(ParentRefs parentRefs, DataBroker dataBroker, Interface interfaceOld,
+                                                  IdManager idManager, WriteTransaction t) {
+
+        BigInteger dpId = null;
+        if (parentRefs != null) {
+            dpId = parentRefs.getDatapathNodeIdentifier();
+        }
+
+        if (dpId == null) {
+            return;
+        }
+
+        BridgeRefEntryKey bridgeRefEntryKey = new BridgeRefEntryKey(dpId);
+        InstanceIdentifier<BridgeRefEntry> bridgeRefEntryIid =
+                InterfaceMetaUtils.getBridgeRefEntryIdentifier(bridgeRefEntryKey);
+        BridgeRefEntry bridgeRefEntry =
+                InterfaceMetaUtils.getBridgeRefEntryFromOperDS(bridgeRefEntryIid, dataBroker);
+
+        if (bridgeRefEntry != null) {
+            InstanceIdentifier<?> bridgeIid = bridgeRefEntry.getBridgeReference().getValue();
+            InstanceIdentifier<TerminationPoint> tpIid = SouthboundUtils.createTerminationPointInstanceIdentifier(
+                    InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), interfaceOld.getName());
+            t.delete(LogicalDatastoreType.CONFIGURATION, tpIid);
+        }
+
+        BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(dpId);
+        InstanceIdentifier<BridgeEntry> bridgeEntryIid = InterfaceMetaUtils.getBridgeEntryIdentifier(bridgeEntryKey);
+        BridgeEntry bridgeEntry = InterfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryIid, dataBroker);
+        if (bridgeEntry == null) {
+            return;
+        }
+
+        List<BridgeInterfaceEntry> bridgeInterfaceEntries = bridgeEntry.getBridgeInterfaceEntry();
+        if (bridgeInterfaceEntries == null) {
+            return;
+        }
+
+        if (bridgeInterfaceEntries.size() <= 1) {
+            t.delete(LogicalDatastoreType.CONFIGURATION, bridgeEntryIid);
+        } else {
+            BridgeInterfaceEntryKey bridgeInterfaceEntryKey =
+                    new BridgeInterfaceEntryKey(interfaceOld.getName());
+            InstanceIdentifier<BridgeInterfaceEntry> bridgeInterfaceEntryIid =
+                    InterfaceMetaUtils.getBridgeInterfaceEntryIdentifier(bridgeEntryKey,
+                            bridgeInterfaceEntryKey);
+            t.delete(LogicalDatastoreType.CONFIGURATION, bridgeInterfaceEntryIid);
+        }
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigUpdateHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsInterfaceConfigUpdateHelper.java
new file mode 100644 (file)
index 0000000..b7c2bb0
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+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.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsInterfaceConfigUpdateHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceConfigUpdateHelper.class);
+
+    public static List<ListenableFuture<Void>> updateConfiguration(DataBroker dataBroker,  IdManager idManager,
+                                                                   Interface interfaceNew, Interface interfaceOld) {
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+
+        if(portAttributesModified(interfaceOld, interfaceNew)) {
+            futures.addAll(OvsInterfaceConfigRemoveHelper.removeConfiguration(dataBroker, interfaceOld, idManager,
+                    interfaceOld.getAugmentation(ParentRefs.class)));
+            futures.addAll(OvsInterfaceConfigAddHelper.addConfiguration(dataBroker,
+                    interfaceNew.getAugmentation(ParentRefs.class), interfaceNew, idManager));
+            return futures;
+        }
+
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+                InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceNew.getName(), dataBroker);
+        if (ifState == null) {
+            futures.addAll(OvsInterfaceConfigAddHelper.addConfiguration(dataBroker,
+                    interfaceNew.getAugmentation(ParentRefs.class), interfaceNew, idManager));
+            return futures;
+        }
+
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+        if (interfaceNew.isEnabled() != interfaceOld.isEnabled()) {
+            OperStatus operStatus;
+            if (!interfaceNew.isEnabled()) {
+                operStatus = OperStatus.Down;
+            } else {
+                String ncStr = ifState.getLowerLayerIf().get(0);
+                NodeConnectorId nodeConnectorId = new NodeConnectorId(ncStr);
+                NodeConnector nodeConnector =
+                        InterfaceManagerCommonUtils.getNodeConnectorFromInventoryOperDS(nodeConnectorId, dataBroker);
+                FlowCapableNodeConnector flowCapableNodeConnector =
+                        nodeConnector.getAugmentation(FlowCapableNodeConnector.class);
+                //State state = flowCapableNodeConnector.getState();
+                operStatus = flowCapableNodeConnector == null ? OperStatus.Down : OperStatus.Up;
+            }
+
+            String ifName = interfaceNew.getName();
+            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
+                    IfmUtil.buildStateInterfaceId(interfaceNew.getName());
+            InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
+            ifaceBuilder.setOperStatus(operStatus);
+            ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName));
+            t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
+
+            IfL2vlan ifL2vlan = interfaceNew.getAugmentation(IfL2vlan.class);
+            if (ifL2vlan == null || ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) {
+                futures.add(t.submit());
+                return futures;
+            }
+
+            InterfaceKey interfaceKey = new InterfaceKey(ifName);
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+                    InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+            if (iface == null) {
+                futures.add(t.submit());
+                return futures;
+            }
+
+            InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(iface.getName());
+            InterfaceParentEntry interfaceParentEntry =
+                    InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
+            if (interfaceParentEntry == null) {
+                futures.add(t.submit());
+                return futures;
+            }
+
+            List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
+            if (interfaceChildEntries == null) {
+                futures.add(t.submit());
+                return futures;
+            }
+
+            for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
+                InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId =
+                        IfmUtil.buildStateInterfaceId(interfaceChildEntry.getChildInterface());
+                InterfaceBuilder ifaceBuilderChild = new InterfaceBuilder();
+                ifaceBuilderChild.setOperStatus(operStatus);
+                ifaceBuilderChild.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceChildEntry.getChildInterface()));
+                t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilderChild.build());
+            }
+        }
+
+        futures.add(t.submit());
+        return futures;
+    }
+
+    private static boolean portAttributesModified(Interface interfaceOld, Interface interfaceNew) {
+        ParentRefs parentRefsOld = interfaceOld.getAugmentation(ParentRefs.class);
+        ParentRefs parentRefsNew = interfaceNew.getAugmentation(ParentRefs.class);
+        if (checkAugmentations(parentRefsOld, parentRefsNew)) {
+            return true;
+        }
+
+        IfL2vlan ifL2vlanOld = interfaceOld.getAugmentation(IfL2vlan.class);
+        IfL2vlan ifL2vlanNew = interfaceNew.getAugmentation(IfL2vlan.class);
+        if (checkAugmentations(ifL2vlanOld, ifL2vlanNew)) {
+            return true;
+        }
+
+        IfTunnel ifTunnelOld = interfaceOld.getAugmentation(IfTunnel.class);
+        IfTunnel ifTunnelNew = interfaceNew.getAugmentation(IfTunnel.class);
+        if (checkAugmentations(ifTunnelOld, ifTunnelNew)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private static<T> boolean checkAugmentations(T oldAug, T newAug) {
+        if ((oldAug != null && newAug == null) ||
+                (oldAug == null && newAug != null)) {
+            return true;
+        }
+
+        if (newAug != null && oldAug != null && !newAug.equals(oldAug)) {
+            return true;
+        }
+
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigAddHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigAddHelper.java
new file mode 100644 (file)
index 0000000..e90a8f9
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+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.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsVlanMemberConfigAddHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(OvsVlanMemberConfigAddHelper.class);
+    public static List<ListenableFuture<Void>> addConfiguration(DataBroker dataBroker, ParentRefs parentRefs,
+                                                                Interface interfaceNew, IfL2vlan ifL2vlan,
+                                                                IdManager idManager) {
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+        InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentRefs.getParentInterface());
+        createInterfaceParentEntryIfNotPresent(dataBroker, t, interfaceParentEntryKey, parentRefs.getParentInterface());
+        createInterfaceChildEntry(dataBroker, idManager, t, interfaceParentEntryKey, interfaceNew.getName());
+
+        InterfaceKey interfaceKey = new InterfaceKey(parentRefs.getParentInterface());
+        Interface ifaceParent = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+        if (ifaceParent == null) {
+            LOG.info("Parent Interface: {} not found when adding child interface: {}",
+                    parentRefs.getParentInterface(), interfaceNew.getName());
+            futures.add(t.submit());
+            return futures;
+        }
+
+        IfL2vlan parentIfL2Vlan = ifaceParent.getAugmentation(IfL2vlan.class);
+        if (parentIfL2Vlan == null || parentIfL2Vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) {
+            LOG.error("Parent Interface: {} not of trunk Type when adding trunk-member: {}", ifaceParent, interfaceNew);
+            futures.add(t.submit());
+            return futures;
+        }
+
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+                InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(parentRefs.getParentInterface(), dataBroker);
+        if (ifState != null) {
+            OperStatus operStatus = ifState.getOperStatus();
+            AdminStatus adminStatus = ifState.getAdminStatus();
+            PhysAddress physAddress = ifState.getPhysAddress();
+
+            if (!interfaceNew.isEnabled()) {
+                operStatus = OperStatus.Down;
+            }
+
+            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
+                    IfmUtil.buildStateInterfaceId(interfaceNew.getName());
+            List<String> lowerLayerIfList = new ArrayList<>();
+            lowerLayerIfList.add(parentRefs.getParentInterface());
+            InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus).setOperStatus(operStatus)
+                    .setPhysAddress(physAddress).setLowerLayerIf(lowerLayerIfList);
+            ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceNew.getName()));
+            t.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), true);
+
+            // FIXME: Maybe, add the new interface to the higher-layer if of the parent interface-state.
+            // That may not serve any purpose though for interface manager.... Unless some external parties are interested in it.
+
+            /* FIXME -- Below code is needed to add vlan-trunks to the of-port. Is this really needed.
+            String lowerLayerIf = ifState.getLowerLayerIf().get(0);
+
+            NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
+            BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+
+            BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId);
+            InstanceIdentifier<BridgeRefEntry> dpnBridgeEntryIid =
+                    InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey);
+            BridgeRefEntry bridgeRefEntry =
+                    InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker);
+            if (bridgeRefEntry != null) {
+                InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
+                        (InstanceIdentifier<OvsdbBridgeAugmentation>)bridgeRefEntry.getBridgeReference().getValue();
+                Optional<OvsdbBridgeAugmentation> bridgeNodeOptional =
+                        IfmUtil.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
+                if (bridgeNodeOptional.isPresent()) {
+                    OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNodeOptional.get();
+                    String bridgeName = ovsdbBridgeAugmentation.getBridgeName().getValue();
+                    VlanTrunkSouthboundUtils.addVlanPortToBridge(bridgeIid, ifL2vlan,
+                            ovsdbBridgeAugmentation, bridgeName, parentRefs.getParentInterface(), dataBroker, t);
+                }
+            } */
+            // FIXME: Need to add the Group here with actions: Push-Vlan, output_port. May not be needed here...
+        }
+
+        futures.add(t.submit());
+        return futures;
+    }
+
+    private static void createInterfaceParentEntryIfNotPresent(DataBroker dataBroker, WriteTransaction t,
+                                                               InterfaceParentEntryKey interfaceParentEntryKey,
+                                                               String parentInterface){
+        InstanceIdentifier<InterfaceParentEntry> interfaceParentEntryIdentifier =
+                InterfaceMetaUtils.getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
+        InterfaceParentEntry interfaceParentEntry =
+                InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryIdentifier, dataBroker);
+
+        if(interfaceParentEntry != null){
+            LOG.info("Not Found entry for Parent Interface: {} in Vlan Trunk-Member Interface Renderer ConfigDS. " +
+                    "Creating...", parentInterface);
+            InterfaceParentEntryBuilder interfaceParentEntryBuilder = new InterfaceParentEntryBuilder()
+                    .setKey(interfaceParentEntryKey).setParentInterface(parentInterface);
+            t.put(LogicalDatastoreType.CONFIGURATION, interfaceParentEntryIdentifier,
+                    interfaceParentEntryBuilder.build(), true);
+        }
+    }
+
+    private static long createInterfaceChildEntry(DataBroker dataBroker, IdManager idManager, WriteTransaction t,
+                                                InterfaceParentEntryKey interfaceParentEntryKey, String childInterface){
+        long lportTag = InterfaceManagerCommonUtils.getUniqueId(idManager, childInterface);
+        InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(childInterface);
+        InstanceIdentifier<InterfaceChildEntry> intfId =
+                InterfaceMetaUtils.getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
+        InterfaceChildEntryBuilder entryBuilder = new InterfaceChildEntryBuilder().setKey(interfaceChildEntryKey)
+                .setChildInterface(childInterface);
+        t.put(LogicalDatastoreType.CONFIGURATION, intfId, entryBuilder.build(),true);
+        return lportTag;
+    }
+}
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigRemoveHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigRemoveHelper.java
new file mode 100644 (file)
index 0000000..a0b404f
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsVlanMemberConfigRemoveHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(OvsVlanMemberConfigRemoveHelper.class);
+    public static List<ListenableFuture<Void>> removeConfiguration(DataBroker dataBroker, ParentRefs parentRefs,
+                                                                Interface interfaceOld, IfL2vlan ifL2vlan,
+                                                                IdManager idManager) {
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+        InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(parentRefs.getParentInterface());
+        InstanceIdentifier<InterfaceParentEntry> interfaceParentEntryIid =
+                InterfaceMetaUtils.getInterfaceParentEntryIdentifier(interfaceParentEntryKey);
+        InterfaceParentEntry interfaceParentEntry =
+                InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryIid, dataBroker);
+
+        List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
+        if (interfaceChildEntries.size() <= 1) {
+            t.delete(LogicalDatastoreType.CONFIGURATION, interfaceParentEntryIid);
+        } else {
+            InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(interfaceOld.getName());
+            InstanceIdentifier<InterfaceChildEntry> interfaceChildEntryIid =
+                    InterfaceMetaUtils.getInterfaceChildEntryIdentifier(interfaceParentEntryKey, interfaceChildEntryKey);
+            t.delete(LogicalDatastoreType.CONFIGURATION, interfaceChildEntryIid);
+        }
+
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+                InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(parentRefs.getParentInterface(), dataBroker);
+        if (ifState != null) {
+            /* FIXME -- The below code is needed if vlan-trunks should be updated in the of-port
+
+            String lowerLayerIf = ifState.getLowerLayerIf().get(0);
+            NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
+            BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+
+            BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId);
+            InstanceIdentifier<BridgeRefEntry> dpnBridgeEntryIid =
+                    InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey);
+            BridgeRefEntry bridgeRefEntry =
+                    InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker);
+            if (bridgeRefEntry != null) {
+                InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
+                        (InstanceIdentifier<OvsdbBridgeAugmentation>)bridgeRefEntry.getBridgeReference().getValue();
+                Optional<OvsdbBridgeAugmentation> bridgeNodeOptional =
+                        IfmUtil.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
+                if (bridgeNodeOptional.isPresent()) {
+                    OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNodeOptional.get();
+                    String bridgeName = ovsdbBridgeAugmentation.getBridgeName().getValue();
+                    VlanTrunkSouthboundUtils.updateVlanMemberInTrunk(bridgeIid, ifL2vlan,
+                            ovsdbBridgeAugmentation, bridgeName, parentRefs.getParentInterface(), dataBroker, t);
+                }
+            } */
+
+            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
+                    IfmUtil.buildStateInterfaceId(interfaceOld.getName());
+            t.delete(LogicalDatastoreType.OPERATIONAL, ifStateId);
+        }
+
+        futures.add(t.submit());
+        return futures;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigUpdateHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/confighelpers/OvsVlanMemberConfigUpdateHelper.java
new file mode 100644 (file)
index 0000000..73edde0
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.confighelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+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.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsVlanMemberConfigUpdateHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(OvsVlanMemberConfigUpdateHelper.class);
+    public static List<ListenableFuture<Void>> updateConfiguration(DataBroker dataBroker, ParentRefs parentRefsNew,
+                                                                   Interface interfaceOld, IfL2vlan ifL2vlanNew,
+                                                                   Interface interfaceNew, IdManager idManager) {
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        ParentRefs parentRefsOld = interfaceOld.getAugmentation(ParentRefs.class);
+
+        InterfaceParentEntryKey interfaceParentEntryKey =
+                new InterfaceParentEntryKey(parentRefsOld.getParentInterface());
+        InterfaceChildEntryKey interfaceChildEntryKey = new InterfaceChildEntryKey(interfaceOld.getName());
+        InterfaceChildEntry interfaceChildEntry =
+                InterfaceMetaUtils.getInterfaceChildEntryFromConfigDS(interfaceParentEntryKey, interfaceChildEntryKey,
+                        dataBroker);
+
+        if (interfaceChildEntry == null) {
+            futures.addAll(OvsInterfaceConfigAddHelper.addConfiguration(dataBroker,
+                    interfaceNew.getAugmentation(ParentRefs.class), interfaceNew, idManager));
+            return futures;
+        }
+
+        IfL2vlan ifL2vlanOld = interfaceOld.getAugmentation(IfL2vlan.class);
+        if (ifL2vlanOld == null || (ifL2vlanNew.getL2vlanMode() != ifL2vlanOld.getL2vlanMode())) {
+            LOG.error("Configuration Error. Vlan Mode Change of Vlan Trunk Member {} as new trunk member: {} is " +
+                    "not allowed.", interfaceOld, interfaceNew);
+            return futures;
+        }
+
+        if (ifL2vlanOld.getVlanId() != ifL2vlanNew.getVlanId() ||
+                !parentRefsOld.getParentInterface().equals(parentRefsNew.getParentInterface())) {
+            futures.addAll(OvsVlanMemberConfigRemoveHelper.removeConfiguration(dataBroker, parentRefsOld, interfaceOld,
+                    ifL2vlanOld, idManager));
+            futures.addAll(OvsVlanMemberConfigAddHelper.addConfiguration(dataBroker, parentRefsNew, interfaceNew,
+                    ifL2vlanNew, idManager));
+            return futures;
+        }
+
+        if (interfaceNew.isEnabled() == interfaceOld.isEnabled()) {
+            return futures;
+        }
+
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface pifState =
+                InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(parentRefsNew.getParentInterface(), dataBroker);
+        if (pifState != null) {
+            OperStatus operStatus = OperStatus.Down;
+            if (interfaceNew.isEnabled()) {
+                operStatus = pifState.getOperStatus();
+            }
+
+            WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
+                    IfmUtil.buildStateInterfaceId(interfaceNew.getName());
+            InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
+            ifaceBuilder.setOperStatus(operStatus);
+            ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(interfaceNew.getName()));
+
+            t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
+            futures.add(t.submit());
+        }
+
+        return futures;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateAddHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateAddHelper.java
new file mode 100644 (file)
index 0000000..95df198
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+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.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This worker is responsible for adding the openflow-interfaces/of-port-info container
+ * in odl-interface-openflow yang.
+ * Where applicable:
+    * Create the entries in Interface-State OperDS.
+    * Create the entries in Inventory OperDS.
+ */
+
+public class OvsInterfaceStateAddHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateAddHelper.class);
+
+    public static List<ListenableFuture<Void>> addState(DataBroker dataBroker, NodeConnectorId nodeConnectorId,
+                                                        String portName, FlowCapableNodeConnector fcNodeConnectorNew) {
+        LOG.debug("Adding Interface State to Oper DS for port: {}", portName);
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+        //Retrieve PbyAddress & OperState from the DataObject
+        PhysAddress physAddress = new PhysAddress(fcNodeConnectorNew.getHardwareAddress().getValue());
+        /*FIXME
+        State state = fcNodeConnectorNew.getState();
+        Interface.OperStatus operStatus =
+                fcNodeConnectorNew == null ? Interface.OperStatus.Down : Interface.OperStatus.Up;
+        Interface.AdminStatus adminStatus = state.isBlocked() ? Interface.AdminStatus.Down : Interface.AdminStatus.Up;
+        */
+        Interface.OperStatus operStatus = Interface.OperStatus.Up;
+        Interface.AdminStatus adminStatus = Interface.AdminStatus.Up;
+        InterfaceKey interfaceKey = new InterfaceKey(portName);
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+                InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+
+        if (iface != null && !iface.isEnabled()) {
+            operStatus = Interface.OperStatus.Down;
+        }
+
+        List<String> lowerLayerIfList = new ArrayList<>();
+        lowerLayerIfList.add(nodeConnectorId.getValue());
+
+        InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(portName);
+        InterfaceBuilder ifaceBuilder = new InterfaceBuilder().setOperStatus(operStatus)
+                .setAdminStatus(adminStatus).setPhysAddress(physAddress).setLowerLayerIf(lowerLayerIfList)
+                .setKey(IfmUtil.getStateInterfaceKeyFromName(portName));
+        t.put(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build(), true);
+
+        if (iface == null) {
+            futures.add(t.submit());
+            return futures;
+        }
+
+        // If this interface maps to a Vlan trunk entity, operational states of all the vlan-trunk-members
+        // should also be created here.
+        IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class);
+        if (ifL2vlan == null || ifL2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Trunk) {
+            futures.add(t.submit());
+            return futures;
+        }
+
+        InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(iface.getName());
+        InterfaceParentEntry interfaceParentEntry =
+                InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
+        if (interfaceParentEntry == null) {
+            futures.add(t.submit());
+            return futures;
+        }
+
+        List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
+        if (interfaceChildEntries == null) {
+            futures.add(t.submit());
+            return futures;
+        }
+
+        //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100.
+        //List<Trunks> trunks = new ArrayList<>();
+        for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
+            InterfaceKey childIfKey = new InterfaceKey(interfaceChildEntry.getChildInterface());
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface ifaceChild =
+                    InterfaceManagerCommonUtils.getInterfaceFromConfigDS(childIfKey, dataBroker);
+
+            // IfL2vlan ifL2vlanChild = iface.getAugmentation(IfL2vlan.class);
+            // trunks.add(new TrunksBuilder().setTrunk(ifL2vlanChild.getVlanId()).build());
+
+            if (!ifaceChild.isEnabled()) {
+                operStatus = Interface.OperStatus.Down;
+            }
+
+            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId =
+                    IfmUtil.buildStateInterfaceId(ifaceChild.getName());
+            List<String> childLowerLayerIfList = new ArrayList<>();
+            childLowerLayerIfList.add(0, nodeConnectorId.getValue());
+            childLowerLayerIfList.add(1, iface.getName());
+            InterfaceBuilder childIfaceBuilder = new InterfaceBuilder().setAdminStatus(adminStatus).setOperStatus(operStatus)
+                    .setPhysAddress(physAddress).setLowerLayerIf(childLowerLayerIfList);
+            childIfaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifaceChild.getName()));
+            t.put(LogicalDatastoreType.OPERATIONAL, ifChildStateId, childIfaceBuilder.build(), true);
+        }
+
+        /** Below code will be needed if we want to update the vlan-trunks on the of-port
+        if (trunks.isEmpty()) {
+            futures.add(t.submit());
+            return futures;
+        }
+
+        BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+
+        BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId);
+        InstanceIdentifier<BridgeRefEntry> dpnBridgeEntryIid =
+                InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey);
+        BridgeRefEntry bridgeRefEntry =
+                InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker);
+        if (bridgeRefEntry == null) {
+            futures.add(t.submit());
+            return futures;
+        }
+
+        InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid =
+                (InstanceIdentifier<OvsdbBridgeAugmentation>)bridgeRefEntry.getBridgeReference().getValue();
+        VlanTrunkSouthboundUtils.addTerminationPointWithTrunks(bridgeIid, trunks, iface.getName(), t);
+         */
+
+        futures.add(t.submit());
+        return futures;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateRemoveHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateRemoveHelper.java
new file mode 100644 (file)
index 0000000..26734ca
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+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.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsInterfaceStateRemoveHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateRemoveHelper.class);
+
+    public static List<ListenableFuture<Void>> removeState(InstanceIdentifier<FlowCapableNodeConnector> key,
+                                                           DataBroker dataBroker, String portName, FlowCapableNodeConnector fcNodeConnectorOld) {
+        LOG.debug("Removing interface-state for port: {}", portName);
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+        InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(portName);
+        t.delete(LogicalDatastoreType.OPERATIONAL, ifStateId);
+
+        // For Vlan-Trunk Interface, remove the trunk-member operstates as well...
+        InterfaceKey interfaceKey = new InterfaceKey(portName);
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+                InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+        if (iface == null) {
+            futures.add(t.submit());
+            return futures;
+        }
+
+        InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(iface.getName());
+        InterfaceParentEntry interfaceParentEntry =
+                InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
+        if (interfaceParentEntry == null) {
+            futures.add(t.submit());
+            return futures;
+        }
+
+        List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
+        if (interfaceChildEntries == null) {
+            futures.add(t.submit());
+            return futures;
+        }
+
+        //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100.
+        for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
+            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifChildStateId =
+                    IfmUtil.buildStateInterfaceId(interfaceChildEntry.getChildInterface());
+            t.delete(LogicalDatastoreType.OPERATIONAL, ifChildStateId);
+        }
+
+       /* Below code will be needed if we want to update the vlan-trunk in the of-port.
+       NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(key.firstIdentifierOf(NodeConnector.class)).getId();
+        BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+
+        BridgeRefEntryKey BridgeRefEntryKey = new BridgeRefEntryKey(dpId);
+        InstanceIdentifier<BridgeRefEntry> dpnBridgeEntryIid =
+                InterfaceMetaUtils.getBridgeRefEntryIdentifier(BridgeRefEntryKey);
+        BridgeRefEntry bridgeRefEntry =
+                InterfaceMetaUtils.getBridgeRefEntryFromOperDS(dpnBridgeEntryIid, dataBroker);
+        if (bridgeRefEntry == null) {
+            futures.add(t.submit());
+            return futures;
+        }
+
+        InstanceIdentifier<?> bridgeIid = bridgeRefEntry.getBridgeReference().getValue();
+        InstanceIdentifier<TerminationPoint> tpIid = SouthboundUtils.createTerminationPointInstanceIdentifier(
+                InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), interfaceOld.getName());
+        t.delete(LogicalDatastoreType.CONFIGURATION, tpIid); */
+
+        futures.add(t.submit());
+        return futures;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateUpdateHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceStateUpdateHelper.java
new file mode 100644 (file)
index 0000000..02a3a2a
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+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.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsInterfaceStateUpdateHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceStateUpdateHelper.class);
+
+    public static List<ListenableFuture<Void>> updateState(InstanceIdentifier<FlowCapableNodeConnector> key,
+                                                           DataBroker dataBroker, String portName,
+                                                           FlowCapableNodeConnector flowCapableNodeConnectorNew,
+                                                           FlowCapableNodeConnector flowCapableNodeConnectorOld) {
+        LOG.debug("Update of Interface State for port: {}", portName);
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+        Interface.OperStatus operStatusNew =
+                flowCapableNodeConnectorNew.getState().isLinkDown() ? Interface.OperStatus.Down : Interface.OperStatus.Up;
+        Interface.AdminStatus adminStatusNew =
+                flowCapableNodeConnectorNew.getState().isBlocked() ? Interface.AdminStatus.Down : Interface.AdminStatus.Up;
+        MacAddress macAddressNew = flowCapableNodeConnectorNew.getHardwareAddress();
+
+        Interface.OperStatus operStatusOld =
+                flowCapableNodeConnectorOld.getState().isLinkDown() ? Interface.OperStatus.Down : Interface.OperStatus.Up;
+        Interface.AdminStatus adminStatusOld =
+                flowCapableNodeConnectorOld.getState().isBlocked() ? Interface.AdminStatus.Down : Interface.AdminStatus.Up;
+        MacAddress macAddressOld = flowCapableNodeConnectorOld.getHardwareAddress();
+
+        boolean opstateModified = false;
+        boolean adminStateModified = false;
+        boolean hardwareAddressModified = false;
+        if (!operStatusNew.equals(operStatusOld)) {
+            opstateModified = true;
+        }
+        if (!adminStatusNew.equals(adminStatusOld)) {
+            adminStateModified = true;
+        }
+        if (!macAddressNew.equals(macAddressOld)) {
+            hardwareAddressModified = true;
+        }
+
+        if (!opstateModified && !adminStateModified && !hardwareAddressModified) {
+            LOG.debug("If State entry for port: {} Not Modified.", portName);
+            return futures;
+        }
+
+        InstanceIdentifier<Interface> ifStateId = IfmUtil.buildStateInterfaceId(portName);
+        InterfaceBuilder ifaceBuilder = new InterfaceBuilder();
+
+        boolean modified = false;
+        if (opstateModified) {
+            LOG.debug("Opstate Modified for Port: {}", portName);
+            InterfaceKey interfaceKey = new InterfaceKey(portName);
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+                    InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+
+            // If interface config admin state is disabled, set operstate of the Interface State entity to Down.
+            if (iface != null && !iface.isEnabled()) {
+                operStatusNew = Interface.OperStatus.Down;
+            }
+
+            ifaceBuilder.setOperStatus(operStatusNew);
+            modified = true;
+        }
+
+        if (adminStateModified) {
+            LOG.debug("Admin state Modified for Port: {}", portName);
+            ifaceBuilder.setAdminStatus(adminStatusNew);
+            modified = true;
+        }
+
+        if (hardwareAddressModified) {
+            LOG.debug("Hw-Address Modified for Port: {}", portName);
+            PhysAddress physAddress = new PhysAddress(macAddressNew.getValue());
+            ifaceBuilder.setPhysAddress(physAddress);
+            modified = true;
+        }
+
+        /* FIXME: Is there chance that lower layer node-connector info is updated.
+                  Not Considering for now.
+         */
+
+        if (modified) {
+            ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(portName));
+            t.merge(LogicalDatastoreType.OPERATIONAL, ifStateId, ifaceBuilder.build());
+
+            InterfaceParentEntryKey interfaceParentEntryKey = new InterfaceParentEntryKey(portName);
+            InterfaceParentEntry interfaceParentEntry =
+                    InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(interfaceParentEntryKey, dataBroker);
+            if (interfaceParentEntry == null) {
+                futures.add(t.submit());
+                return futures;
+            }
+
+            List<InterfaceChildEntry> interfaceChildEntries = interfaceParentEntry.getInterfaceChildEntry();
+            if (interfaceChildEntries == null) {
+                futures.add(t.submit());
+                return futures;
+            }
+
+            LOG.debug("Updating if-state entries for Vlan-Trunk Members for port: {}", portName);
+            //FIXME: If the no. of child entries exceeds 100, perform txn updates in batches of 100.
+            for (InterfaceChildEntry interfaceChildEntry : interfaceChildEntries) {
+                InstanceIdentifier<Interface> ifChildStateId =
+                        IfmUtil.buildStateInterfaceId(interfaceChildEntry.getChildInterface());
+                t.merge(LogicalDatastoreType.OPERATIONAL, ifChildStateId, ifaceBuilder.build());
+            }
+        }
+
+        futures.add(t.submit());
+        return futures;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceTopologyStateAddHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceTopologyStateAddHelper.java
new file mode 100644 (file)
index 0000000..bf37408
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities.SouthboundUtils;
+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.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsInterfaceTopologyStateAddHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceTopologyStateAddHelper.class);
+    public static List<ListenableFuture<Void>> addPortToBridge(InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
+                                                               OvsdbBridgeAugmentation bridgeNew, DataBroker dataBroker) {
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+        if (bridgeNew.getDatapathId() == null) {
+            LOG.warn("DataPathId found as null for Bridge Augmentation: {}... retrying...", bridgeNew);
+            Optional<OvsdbBridgeAugmentation> bridgeNodeOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL, bridgeIid, dataBroker);
+            if (bridgeNodeOptional.isPresent()) {
+                bridgeNew = bridgeNodeOptional.get();
+            }
+            if (bridgeNew.getDatapathId() == null) {
+                LOG.warn("DataPathId found as null again for Bridge Augmentation: {}. Bailing out.", bridgeNew);
+                return futures;
+            }
+        }
+
+        String dpId = bridgeNew.getDatapathId().getValue();
+        String bridgeName = bridgeNew.getBridgeName().getValue();
+
+        if (dpId == null) {
+            LOG.error("Optained null dpid for bridge: {}", bridgeNew);
+            return futures;
+        }
+
+        dpId = dpId.replaceAll("[^\\d.]", "");
+        BigInteger ovsdbDpId = new BigInteger(dpId, 16);
+        BridgeRefEntryKey bridgeRefEntryKey = new BridgeRefEntryKey(ovsdbDpId);
+        InstanceIdentifier<BridgeRefEntry> bridgeEntryId =
+                InterfaceMetaUtils.getBridgeRefEntryIdentifier(bridgeRefEntryKey);
+        BridgeRefEntryBuilder tunnelDpnBridgeEntryBuilder =
+                new BridgeRefEntryBuilder().setKey(bridgeRefEntryKey).setDpid(ovsdbDpId)
+                        .setBridgeReference(new OvsdbBridgeRef(bridgeIid));
+        t.put(LogicalDatastoreType.OPERATIONAL, bridgeEntryId, tunnelDpnBridgeEntryBuilder.build(), true);
+
+        BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(ovsdbDpId);
+        InstanceIdentifier<BridgeEntry> bridgeEntryInstanceIdentifier =
+                InterfaceMetaUtils.getBridgeEntryIdentifier(bridgeEntryKey);
+        BridgeEntry bridgeEntry =
+                InterfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryInstanceIdentifier,
+                        dataBroker);
+        if (bridgeEntry == null) {
+            futures.add(t.submit());
+            return futures;
+        }
+
+        List<BridgeInterfaceEntry> bridgeInterfaceEntries = bridgeEntry.getBridgeInterfaceEntry();
+        for (BridgeInterfaceEntry bridgeInterfaceEntry : bridgeInterfaceEntries) {
+            String portName = bridgeInterfaceEntry.getInterfaceName();
+            InterfaceKey interfaceKey = new InterfaceKey(portName);
+            Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+            if (iface.getAugmentation(IfTunnel.class) != null) {
+                SouthboundUtils.addPortToBridge(bridgeIid, iface, bridgeNew, bridgeName, portName, dataBroker, t);
+                 InstanceIdentifier<TerminationPoint> tpIid = SouthboundUtils.createTerminationPointInstanceIdentifier(
+                        InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), portName);
+                InterfaceMetaUtils.createBridgeInterfaceEntryInConfigDS(bridgeEntryKey,
+                        new BridgeInterfaceEntryKey(portName), portName, tpIid, t);
+            }
+        }
+
+        futures.add(t.submit());
+        return futures;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceTopologyStateRemoveHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/statehelpers/OvsInterfaceTopologyStateRemoveHelper.java
new file mode 100644 (file)
index 0000000..b38708a
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.statehelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge.ref.info.BridgeRefEntryKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class OvsInterfaceTopologyStateRemoveHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(OvsInterfaceTopologyStateRemoveHelper.class);
+
+    public static List<ListenableFuture<Void>> removePortFromBridge(InstanceIdentifier<OvsdbBridgeAugmentation> bridgeIid,
+                                                               OvsdbBridgeAugmentation bridgeOld, DataBroker dataBroker) {
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();;
+
+        String dpId = bridgeOld.getDatapathId().getValue().replaceAll("[^\\d.]", "");
+        if (dpId == null) {
+            LOG.warn("Got Null DPID for Bridge: {}", bridgeOld);
+            return futures;
+        }
+
+        dpId = dpId.replaceAll("[^\\d.]", "");
+        BigInteger ovsdbDpId = new BigInteger(dpId,16);
+        BridgeRefEntryKey bridgeRefEntryKey = new BridgeRefEntryKey(ovsdbDpId);
+        InstanceIdentifier<BridgeRefEntry> bridgeEntryId =
+                InterfaceMetaUtils.getBridgeRefEntryIdentifier(bridgeRefEntryKey);
+        t.delete(LogicalDatastoreType.OPERATIONAL, bridgeEntryId);
+
+        futures.add(t.submit());
+        return futures;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/utilities/SouthboundUtils.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/utilities/SouthboundUtils.java
new file mode 100644 (file)
index 0000000..d921ac9
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities;
+
+import com.google.common.collect.Maps;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class SouthboundUtils {
+    private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class);
+    public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
+
+    public static void addPortToBridge(InstanceIdentifier<?> bridgeIid, Interface iface,
+                                       OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
+                                       String portName, DataBroker dataBroker, WriteTransaction t) {
+        IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
+        if (ifTunnel != null) {
+            addTunnelPortToBridge(ifTunnel, bridgeIid, iface, bridgeAugmentation, bridgeName, portName, dataBroker, t);
+            return;
+        }
+
+        IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class);
+        if (ifL2vlan != null) {
+            addVlanPortToBridge(bridgeIid, ifL2vlan, bridgeAugmentation, bridgeName, portName, dataBroker, t);
+        }
+    }
+
+    private static void addVlanPortToBridge(InstanceIdentifier<?> bridgeIid, IfL2vlan ifL2vlan,
+                                              OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
+                                              String portName, DataBroker dataBroker, WriteTransaction t) {
+        int vlanId = ifL2vlan.getVlanId().getValue();
+        addTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, portName, vlanId, null, null, dataBroker, t);
+    }
+
+    private static void addTunnelPortToBridge(IfTunnel ifTunnel, InstanceIdentifier<?> bridgeIid, Interface iface,
+                                             OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
+                                             String portName, DataBroker dataBroker, WriteTransaction t) {
+        Class type = null;
+        if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeGre.class)) {
+            type = InterfaceTypeGre.class;
+        } else if (ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
+            type = InterfaceTypeVxlan.class;
+        }
+
+        if (type == null) {
+            LOG.warn("Unknown Tunnel Type obtained while creating interface: {}", iface);
+            return;
+        }
+
+        int vlanId = 0;
+        IfL2vlan ifL2vlan = iface.getAugmentation(IfL2vlan.class);
+        if (ifL2vlan != null) {
+            vlanId = ifL2vlan.getVlanId().getValue();
+        }
+
+        Map<String, String> options = Maps.newHashMap();
+        options.put("key", "flow");
+
+        IpAddress localIp = ifTunnel.getTunnelSource();
+        options.put("local_ip", localIp.getIpv4Address().getValue());
+
+        IpAddress remoteIp = ifTunnel.getTunnelDestination();
+        options.put("remote_ip", remoteIp.getIpv4Address().getValue());
+
+        addTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, portName, vlanId, type, options, dataBroker, t);
+    }
+
+    private static void addTerminationPoint(InstanceIdentifier<?> bridgeIid, OvsdbBridgeAugmentation bridgeNode,
+                                            String bridgeName, String portName, int vlanId, Class type,
+                                            Map<String, String> options, DataBroker dataBroker, WriteTransaction t) {
+        InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
+                InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), portName);
+        OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
+
+        tpAugmentationBuilder.setName(portName);
+
+        if (type != null) {
+            tpAugmentationBuilder.setInterfaceType(type);
+        }
+
+        if (options != null) {
+            List<Options> optionsList = new ArrayList<Options>();
+            for (Map.Entry<String, String> entry : options.entrySet()) {
+                OptionsBuilder optionsBuilder = new OptionsBuilder();
+                optionsBuilder.setKey(new OptionsKey(entry.getKey()));
+                optionsBuilder.setOption(entry.getKey());
+                optionsBuilder.setValue(entry.getValue());
+                optionsList.add(optionsBuilder.build());
+            }
+            tpAugmentationBuilder.setOptions(optionsList);
+        }
+
+        if (vlanId != 0) {
+                tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Access);
+                tpAugmentationBuilder.setVlanTag(new VlanId(vlanId));
+        }
+
+        TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+        tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
+        tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
+
+        t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true);
+    }
+
+    private static InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(Node node,
+                                                                                                 String portName){
+        InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
+                .create(NetworkTopology.class)
+                .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
+                .child(Node.class,node.getKey())
+                .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
+
+        LOG.debug("Termination point InstanceIdentifier generated : {}", terminationPointPath);
+        return terminationPointPath;
+    }
+
+    public static InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(NodeKey nodekey,
+                                                                                                String portName){
+        InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
+                .create(NetworkTopology.class)
+                .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
+                .child(Node.class,nodekey)
+                .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
+
+        LOG.debug("Termination point InstanceIdentifier generated : {}",terminationPointPath);
+        return terminationPointPath;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/utilities/VlanTrunkSouthboundUtils.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/renderer/ovs/utilities/VlanTrunkSouthboundUtils.java
new file mode 100644 (file)
index 0000000..19868da
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.renderer.ovs.utilities;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class VlanTrunkSouthboundUtils {
+    private static final Logger LOG = LoggerFactory.getLogger(VlanTrunkSouthboundUtils.class);
+    public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
+
+    public static void addVlanPortToBridge(InstanceIdentifier<?> bridgeIid, IfL2vlan ifL2vlan,
+                                            OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
+                                            String parentInterface, DataBroker dataBroker, WriteTransaction t) {
+        LOG.info("Vlan Interface creation not supported yet. please visit later.");
+        int vlanId = ifL2vlan.getVlanId().getValue();
+        addTrunkTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, parentInterface, vlanId, dataBroker, t);
+    }
+
+    public static void updateVlanMemberInTrunk(InstanceIdentifier<?> bridgeIid, IfL2vlan ifL2vlan,
+                                           OvsdbBridgeAugmentation bridgeAugmentation, String bridgeName,
+                                           String parentInterface, DataBroker dataBroker, WriteTransaction t) {
+        LOG.info("Vlan Interface creation not supported yet. please visit later.");
+        int vlanId = ifL2vlan.getVlanId().getValue();
+        updateTerminationPoint(bridgeIid, bridgeAugmentation, bridgeName, parentInterface, vlanId, dataBroker, t);
+    }
+
+    private static void addTrunkTerminationPoint(InstanceIdentifier<?> bridgeIid, OvsdbBridgeAugmentation bridgeNode,
+                                                 String bridgeName, String parentInterface, int vlanId,
+                                                 DataBroker dataBroker, WriteTransaction t) {
+        if (vlanId == 0) {
+            LOG.error("Found vlanid 0 for bridge: {}, interface: {}", bridgeName, parentInterface);
+            return;
+        }
+
+        InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
+                InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), parentInterface);
+        OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
+        tpAugmentationBuilder.setName(parentInterface);
+        tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Trunk);
+        OvsdbTerminationPointAugmentation terminationPointAugmentation = null;
+        Optional<TerminationPoint> terminationPointOptional =
+                IfmUtil.read(LogicalDatastoreType.OPERATIONAL, tpIid, dataBroker);
+        if (terminationPointOptional.isPresent()) {
+            TerminationPoint terminationPoint = terminationPointOptional.get();
+            terminationPointAugmentation = terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
+            if (terminationPointAugmentation != null) {
+                List<Trunks> trunks = terminationPointAugmentation.getTrunks();
+                if (trunks == null) {
+                    trunks = new ArrayList<>();
+                }
+
+                trunks.add(new TrunksBuilder().setTrunk(new VlanId(vlanId)).build());
+                tpAugmentationBuilder.setTrunks(trunks);
+            }
+        } else {
+            List<Trunks> trunks = new ArrayList<>();
+            trunks.add(new TrunksBuilder().setTrunk(new VlanId(vlanId)).build());
+            tpAugmentationBuilder.setTrunks(trunks);
+        }
+
+        TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+        tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
+        tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
+
+        t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true);
+    }
+
+    public static void addTerminationPointWithTrunks(InstanceIdentifier<?> bridgeIid, List<Trunks> trunks,
+                                                     String parentInterface, WriteTransaction t) {
+        InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
+                InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), parentInterface);
+        OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
+        tpAugmentationBuilder.setName(parentInterface);
+        tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Trunk);
+        tpAugmentationBuilder.setTrunks(trunks);
+
+        TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+        tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
+        tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
+
+        t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true);
+    }
+
+    private static void updateTerminationPoint(InstanceIdentifier<?> bridgeIid, OvsdbBridgeAugmentation bridgeNode,
+                                           String bridgeName, String parentInterface, int vlanId,
+                                           DataBroker dataBroker, WriteTransaction t) {
+        if (vlanId == 0) {
+            LOG.error("Found vlanid 0 for bridge: {}, interface: {}", bridgeName, parentInterface);
+            return;
+        }
+
+        InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
+                InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), parentInterface);
+        OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
+        tpAugmentationBuilder.setName(parentInterface);
+        tpAugmentationBuilder.setVlanMode(OvsdbPortInterfaceAttributes.VlanMode.Trunk);
+        OvsdbTerminationPointAugmentation terminationPointAugmentation = null;
+        Optional<TerminationPoint> terminationPointOptional =
+                IfmUtil.read(LogicalDatastoreType.OPERATIONAL, tpIid, dataBroker);
+        if (terminationPointOptional.isPresent()) {
+            TerminationPoint terminationPoint = terminationPointOptional.get();
+            terminationPointAugmentation = terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
+            if (terminationPointAugmentation != null) {
+                List<Trunks> trunks = terminationPointAugmentation.getTrunks();
+                if (trunks != null) {
+                    trunks.remove(new TrunksBuilder().setTrunk(new VlanId(vlanId)).build());
+                }
+
+                tpAugmentationBuilder.setTrunks(trunks);
+                TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
+                tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
+                tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
+
+                t.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build(), true);
+            }
+        }
+    }
+
+    private static InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(NodeKey nodekey,
+                                                                                                String portName){
+        InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
+                .create(NetworkTopology.class)
+                .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
+                .child(Node.class,nodekey)
+                .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
+
+        LOG.debug("Termination point InstanceIdentifier generated : {}", terminationPointPath);
+        return terminationPointPath;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/rpcservice/InterfaceManagerRpcService.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/rpcservice/InterfaceManagerRpcService.java
new file mode 100644 (file)
index 0000000..fbf86df
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * 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
+ */
+
+package org.opendaylight.vpnservice.interfacemgr.rpcservice;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceMetaUtils;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.ActionType;
+import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
+import org.opendaylight.vpnservice.mdsalutil.InstructionType;
+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.iana._if.type.rev140508.Tunnel;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
+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.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.InterfaceChildInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info.InterfaceParentEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._interface.child.info._interface.parent.entry.InterfaceChildEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.BridgeEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.bridge._interface.info.bridge.entry.BridgeInterfaceEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.ParentRefs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.*;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Future;
+
+public class InterfaceManagerRpcService implements OdlInterfaceRpcService {
+    private static final Logger LOG = LoggerFactory.getLogger(InterfaceManagerRpcService.class);
+    DataBroker dataBroker;
+    public InterfaceManagerRpcService(DataBroker dataBroker) {
+        this.dataBroker = dataBroker;
+    }
+
+    @Override
+    public Future<RpcResult<GetDpidFromInterfaceOutput>> getDpidFromInterface(GetDpidFromInterfaceInput input) {
+        String interfaceName = input.getIntfName();
+        RpcResultBuilder<GetDpidFromInterfaceOutput> rpcResultBuilder;
+        try {
+            BigInteger dpId = null;
+            InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
+            Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+            if (Tunnel.class.equals(interfaceInfo.getType())) {
+                ParentRefs parentRefs = interfaceInfo.getAugmentation(ParentRefs.class);
+                dpId = parentRefs.getDatapathNodeIdentifier();
+            } else {
+                org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+                        InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
+                String lowerLayerIf = ifState.getLowerLayerIf().get(0);
+                NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
+                dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+            }
+            GetDpidFromInterfaceOutputBuilder output = new GetDpidFromInterfaceOutputBuilder().setDpid(
+                    (dpId));
+            rpcResultBuilder = RpcResultBuilder.success();
+            rpcResultBuilder.withResult(output.build());
+        } catch (Exception e) {
+            LOG.error("Retrieval of datapath id for the key {} failed due to {}", interfaceName, e);
+            rpcResultBuilder = RpcResultBuilder.failed();
+        }
+        return Futures.immediateFuture(rpcResultBuilder.build());
+    }
+
+    @Override
+    public Future<RpcResult<GetEndpointIpForDpnOutput>> getEndpointIpForDpn(GetEndpointIpForDpnInput input) {
+        RpcResultBuilder<GetEndpointIpForDpnOutput> rpcResultBuilder;
+        try {
+            BridgeEntryKey bridgeEntryKey = new BridgeEntryKey(input.getDpid());
+            InstanceIdentifier<BridgeEntry> bridgeEntryInstanceIdentifier =
+                    InterfaceMetaUtils.getBridgeEntryIdentifier(bridgeEntryKey);
+            BridgeEntry bridgeEntry =
+                    InterfaceMetaUtils.getBridgeEntryFromConfigDS(bridgeEntryInstanceIdentifier,
+                            dataBroker);
+            // local ip of any of the bridge interface entry will be the dpn end point ip
+            BridgeInterfaceEntry bridgeInterfaceEntry = bridgeEntry.getBridgeInterfaceEntry().get(0);
+            InterfaceKey interfaceKey = new InterfaceKey(bridgeInterfaceEntry.getInterfaceName());
+            Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+            IfTunnel tunnel = interfaceInfo.getAugmentation(IfTunnel.class);
+            GetEndpointIpForDpnOutputBuilder endpointIpForDpnOutput = new GetEndpointIpForDpnOutputBuilder().setLocalIps(Arrays.asList(tunnel.getTunnelSource()));
+            rpcResultBuilder = RpcResultBuilder.success();
+            rpcResultBuilder.withResult(endpointIpForDpnOutput.build());
+        }catch(Exception e){
+            LOG.error("Retrieval of endpoint of for dpn {} failed due to {}" ,input.getDpid(), e);
+            rpcResultBuilder = RpcResultBuilder.failed();
+        }
+        return Futures.immediateFuture(rpcResultBuilder.build());
+    }
+
+    @Override
+    public Future<RpcResult<GetEgressInstructionsForInterfaceOutput>> getEgressInstructionsForInterface(GetEgressInstructionsForInterfaceInput input) {
+        RpcResultBuilder<GetEgressInstructionsForInterfaceOutput> rpcResultBuilder;
+        try {
+            List<InstructionInfo> instructionInfo = new ArrayList<InstructionInfo>();
+            List<ActionInfo> actionInfo = getEgressActionInfosForInterface(input.getIntfName());
+            instructionInfo.add(new InstructionInfo(InstructionType.write_actions, actionInfo));
+                    GetEgressInstructionsForInterfaceOutputBuilder output = new GetEgressInstructionsForInterfaceOutputBuilder().
+                    setInstruction(buildInstructions(instructionInfo));
+            rpcResultBuilder = RpcResultBuilder.success();
+            rpcResultBuilder.withResult(output.build());
+        }catch(Exception e){
+            LOG.error("Retrieval of egress actions for the key {} failed due to {}" ,input.getIntfName(), e);
+            rpcResultBuilder = RpcResultBuilder.failed();
+        }
+        return Futures.immediateFuture(rpcResultBuilder.build());
+    }
+
+    @Override
+    public Future<RpcResult<GetEgressActionsForInterfaceOutput>> getEgressActionsForInterface(GetEgressActionsForInterfaceInput input) {
+        RpcResultBuilder<GetEgressActionsForInterfaceOutput> rpcResultBuilder;
+        try {
+            List<Action> actionsList = getEgressActionsForInterface(input.getIntfName());
+            GetEgressActionsForInterfaceOutputBuilder output = new GetEgressActionsForInterfaceOutputBuilder().
+                    setAction(actionsList);
+            rpcResultBuilder = RpcResultBuilder.success();
+            rpcResultBuilder.withResult(output.build());
+        }catch(Exception e){
+            LOG.error("Retrieval of egress actions for the key {} failed due to {}" ,input.getIntfName(), e);
+            rpcResultBuilder = RpcResultBuilder.failed();
+        }
+        return Futures.immediateFuture(rpcResultBuilder.build());
+    }
+
+    public static InstanceIdentifier<InterfaceChildEntry> getInterfaceChildEntryIdentifier(InterfaceParentEntryKey parentEntryKey, InterfaceChildEntryKey interfaceChildEntryKey) {
+        InstanceIdentifier.InstanceIdentifierBuilder<InterfaceChildEntry> interfaceChildEntryInstanceIdentifierBuilder =
+                InstanceIdentifier.builder(InterfaceChildInfo.class).child(InterfaceParentEntry.class, parentEntryKey).child(InterfaceChildEntry.class, interfaceChildEntryKey);
+        return interfaceChildEntryInstanceIdentifierBuilder.build();
+    }
+
+    public static InterfaceChildEntry getInterfaceChildEntryFromConfigDS(String interfaceName,
+                                                         DataBroker dataBroker) {
+        InterfaceParentEntryKey parentEntryKey = new InterfaceParentEntryKey(interfaceName);
+        InterfaceChildEntryKey childEntryKey = new InterfaceChildEntryKey(interfaceName);
+        InstanceIdentifier<InterfaceChildEntry> interfaceChildEntryInstanceIdentifier = getInterfaceChildEntryIdentifier(parentEntryKey, childEntryKey);
+        Optional<InterfaceChildEntry> interfaceChildEntryOptional =
+                IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceChildEntryInstanceIdentifier, dataBroker);
+        if (!interfaceChildEntryOptional.isPresent()) {
+            return null;
+        }
+        return interfaceChildEntryOptional.get();
+    }
+
+    @Override
+    public Future<RpcResult<GetPortFromInterfaceOutput>> getPortFromInterface(GetPortFromInterfaceInput input) {
+        RpcResultBuilder<GetPortFromInterfaceOutput> rpcResultBuilder;
+        String interfaceName = input.getIntfName();
+        try {
+            BigInteger dpId = null;
+            long portNo = 0;
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+                        InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
+            String lowerLayerIf = ifState.getLowerLayerIf().get(0);
+            NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
+            dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+            portNo = Long.valueOf(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
+            // FIXME Assuming portName and interfaceName are same
+            GetPortFromInterfaceOutputBuilder output = new GetPortFromInterfaceOutputBuilder().setDpid(dpId).
+                    setPortname(interfaceName).setPortno(Long.valueOf(portNo));
+            rpcResultBuilder = RpcResultBuilder.success();
+            rpcResultBuilder.withResult(output.build());
+        }catch(Exception e){
+            LOG.error("Retrieval of lport tag for the key {} failed due to {}" ,input.getIntfName(), e);
+            rpcResultBuilder = RpcResultBuilder.failed();
+        }
+        return Futures.immediateFuture(rpcResultBuilder.build());
+    }
+
+    @Override
+    public Future<RpcResult<GetInterfaceFromPortOutput>> getInterfaceFromPort(GetInterfaceFromPortInput input) {
+        /*RpcResultBuilder<GetInterfaceFromPortOutput> rpcResultBuilder;
+        try {
+            Interface interfaceInfo = null;
+            NodeId nodeId = IfmUtil.buildDpnNodeId(input.getDpid());
+            Node node = getNodeFromInventoryOperDS(nodeId, dataBroker);
+            ChildInterfaceNames childInterfaceNames = node.getAugmentation(ChildInterfaceNames.class);
+            for(OfInterfaceRefInfo ofInterfaceRefInfo : childInterfaceNames.getOfInterfaceRefInfo()){
+               interfaceInfo = getInterfaceFromTunnelKey(ofInterfaceRefInfo.getOfIntfName(), input.getInterfaceId(),
+                       input.getInterfaceType());
+            }
+            GetInterfaceFromPortOutputBuilder output = new GetInterfaceFromPortOutputBuilder().
+                    setInterfaceName(interfaceInfo == null ? null : interfaceInfo.getName());
+            rpcResultBuilder = RpcResultBuilder.success();
+            rpcResultBuilder.withResult(output.build());
+        }catch(Exception e){
+            LOG.error("Retrieval of interface for the key {} failed due to {}" ,input.getPortno(), e);
+            rpcResultBuilder = RpcResultBuilder.failed();
+        }
+        return Futures.immediateFuture(rpcResultBuilder.build());
+        */
+        return null;
+    }
+
+    public List<ActionInfo> getEgressActionInfosForInterface(String interfaceName) {
+        Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName),
+                dataBroker);
+        List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+                InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
+
+        String lowerLayerIf = ifState.getLowerLayerIf().get(0);
+        NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
+        String portNo = IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId);
+        Class<? extends InterfaceType> ifType = interfaceInfo.getType();
+        if(L2vlan.class.equals(ifType)){
+            IfL2vlan vlanIface = interfaceInfo.getAugmentation(IfL2vlan.class);
+            LOG.trace("L2Vlan: {}",vlanIface);
+            long vlanVid = (vlanIface == null) ? 0 : vlanIface.getVlanId().getValue();
+            if (vlanVid != 0) {
+                listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
+                listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
+                        new String[] { Long.toString(vlanVid) }));
+            }
+            listActionInfo.add(new ActionInfo(ActionType.output, new String[] {portNo}));
+        }else if(Tunnel.class.equals(ifType)){
+            listActionInfo.add(new ActionInfo(ActionType.output, new String[] { portNo}));
+        }
+        return listActionInfo;
+    }
+
+    public List<Action> getEgressActionsForInterface(String interfaceName) {
+            List<ActionInfo> listActionInfo = getEgressActionInfosForInterface(interfaceName);
+            List<Action> actionsList = new ArrayList<>();
+            for (ActionInfo actionInfo : listActionInfo) {
+                actionsList.add(actionInfo.buildAction());
+            }
+            return actionsList;
+    }
+
+    protected static List<Instruction> buildInstructions(List<InstructionInfo> listInstructionInfo) {
+        if (listInstructionInfo != null) {
+            List<Instruction> instructions = new ArrayList<Instruction>();
+            int instructionKey = 0;
+
+            for (InstructionInfo instructionInfo : listInstructionInfo) {
+                instructions.add(instructionInfo.buildInstruction(instructionKey));
+                instructionKey++;
+            }
+            return instructions;
+        }
+
+        return null;
+    }
+
+    public static Node getNodeFromInventoryOperDS(NodeId nodeId, DataBroker dataBroker) {
+        InstanceIdentifier<Node> nodeIdentifier = InstanceIdentifier.builder(Nodes.class)
+                .child(Node.class, new NodeKey(nodeId)).build();
+
+        Optional<Node> nodeOptional = IfmUtil.read(LogicalDatastoreType.OPERATIONAL,
+                nodeIdentifier, dataBroker);
+        if (!nodeOptional.isPresent()) {
+            return null;
+        }
+        return nodeOptional.get();
+    }
+
+    public Interface getInterfaceFromTunnelKey(String interfaceName, BigInteger tunnelKey,
+                                               Class<? extends TunnelTypeBase> ifType){
+
+        /*Interface interfaceInfo = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
+
+        if(ifType.isAssignableFrom(IfL2vlan.class)){
+            IfL2vlan vlanIface = interfaceInfo.getAugmentation(IfL2vlan.class);
+            LOG.trace("L2Vlan: {}",vlanIface);
+            long vlanVid = (vlanIface == null) ? 0 : vlanIface.getVlanId();
+            if(tunnelKey.intValue() == vlanVid){
+               return interfaceInfo;
+            }
+        }else if(ifType.isAssignableFrom(TunnelTypeBase.class)){
+            IfTunnel ifTunnel = interfaceInfo.getAugmentation(IfTunnel.class);
+            TunnelResources tunnelResources = ifTunnel.getTunnelResources();
+            if(ifType.isAssignableFrom(TunnelTypeGre.class)) {
+                IfGre ifGre = tunnelResources.getAugmentation(IfGre.class);
+                if (ifGre.getGreKey() == tunnelKey) {
+                    return interfaceInfo;
+                }
+            }else if(ifType.isAssignableFrom(TunnelTypeVxlan.class)){
+                IfVxlan ifVxlan = tunnelResources.getAugmentation(IfVxlan.class);
+                if(ifVxlan.getVni() == tunnelKey){
+                    return interfaceInfo;
+                }
+            }
+        }
+        return null;*/
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/confighelpers/FlowBasedServicesConfigBindHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/confighelpers/FlowBasedServicesConfigBindHelper.java
new file mode 100644 (file)
index 0000000..bd1c994
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.confighelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+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.iana._if.type.rev140508.Tunnel;
+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.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class FlowBasedServicesConfigBindHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesConfigBindHelper.class);
+
+    public static List<ListenableFuture<Void>> bindService(InstanceIdentifier<BoundServices> instanceIdentifier,
+                                                           BoundServices boundServiceNew, DataBroker dataBroker) {
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = null;
+        String interfaceName =
+                InstanceIdentifier.keyOf(instanceIdentifier.firstIdentifierOf(ServicesInfo.class)).getInterfaceName();
+
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+                InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
+        if (ifState == null || ifState.getOperStatus() == OperStatus.Down) {
+            LOG.info("Not Binding Service since for Interface: {}", interfaceName);
+            return futures;
+        }
+
+        // Get the Parent ServiceInfo
+        ServicesInfo servicesInfo = FlowBasedServicesUtils.getServicesInfoForInterface(interfaceName, dataBroker);
+        if (servicesInfo == null) {
+            LOG.error("Reached Impossible part 1 in the code during bind service for: {}", boundServiceNew);
+            return futures;
+        }
+
+        InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
+        Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+
+        List<BoundServices> allServices = servicesInfo.getBoundServices();
+        if (allServices.isEmpty()) {
+            LOG.error("Reached Impossible part 2 in the code during bind service for: {}", boundServiceNew);
+            return futures;
+        }
+
+        NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker);
+        long portNo = Long.parseLong(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
+        BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+
+        Long lportTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker);
+        if (allServices.size() == 1) {
+            // If only one service present, install instructions in table 0.
+            int vlanId = 0;
+            List<MatchInfo> matches = null;
+            if (iface.getType().isAssignableFrom(L2vlan.class)) {
+                vlanId = iface.getAugmentation(IfL2vlan.class).getVlanId().getValue();
+                matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, vlanId);
+            } else if (iface.getType().isAssignableFrom(Tunnel.class)){
+                matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface);
+            }
+
+            if (matches != null) {
+                FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, vlanId, boundServiceNew,
+                        dataBroker, t, matches, lportTag.intValue(), IfmConstants.VLAN_INTERFACE_INGRESS_TABLE);
+            }
+
+            if (t != null) {
+                futures.add(t.submit());
+            }
+            return futures;
+        }
+
+        boolean isCurrentServiceHighestPriority = true;
+        Map<Short, BoundServices> tmpServicesMap = new ConcurrentHashMap<>();
+        short highestPriority = 0xFF;
+        for (BoundServices boundService : allServices) {
+            if (boundService.getServicePriority() < boundServiceNew.getServicePriority()) {
+                isCurrentServiceHighestPriority = false;
+                break;
+            }
+            if (!boundService.equals(boundServiceNew)) {
+                tmpServicesMap.put(boundService.getServicePriority(), boundService);
+                if (boundService.getServicePriority() < highestPriority) {
+                    highestPriority = boundService.getServicePriority();
+                }
+            }
+            LOG.error("Reached unexpected part 1 of the code when handling bind service for interface: {}, when binding" +
+                    "service: {}", iface, boundServiceNew);
+        }
+
+        if (!isCurrentServiceHighestPriority) {
+            FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, boundServiceNew, iface, dataBroker,  t,
+                    lportTag.intValue());
+        } else {
+            BoundServices serviceToReplace = tmpServicesMap.get(highestPriority);
+            FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, serviceToReplace, iface, dataBroker, t,
+                    lportTag.intValue());
+            int vlanId = 0;
+            List<MatchInfo> matches = null;
+            if (iface.getType().isAssignableFrom(L2vlan.class)) {
+                vlanId = iface.getAugmentation(IfL2vlan.class).getVlanId().getValue();
+                matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, vlanId);
+            } else if (iface.getType().isAssignableFrom(Tunnel.class)){
+                matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface);
+            }
+
+            if (matches != null) {
+                FlowBasedServicesUtils.removeIngressFlow(iface, serviceToReplace, dpId, dataBroker, t);
+                FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, vlanId, boundServiceNew, dataBroker, t,
+                        matches, lportTag.intValue(), IfmConstants.VLAN_INTERFACE_INGRESS_TABLE);
+            }
+        }
+
+        if (t != null) {
+            futures.add(t.submit());
+        }
+        return futures;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/confighelpers/FlowBasedServicesConfigUnbindHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/confighelpers/FlowBasedServicesConfigUnbindHelper.java
new file mode 100644 (file)
index 0000000..847b3db
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.confighelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+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.iana._if.type.rev140508.Tunnel;
+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.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class FlowBasedServicesConfigUnbindHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesConfigUnbindHelper.class);
+
+    public static List<ListenableFuture<Void>> unbindService(InstanceIdentifier<BoundServices> instanceIdentifier,
+                                                             BoundServices boundServiceOld, DataBroker dataBroker) {
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = null;
+
+        String interfaceName =
+                InstanceIdentifier.keyOf(instanceIdentifier.firstIdentifierOf(ServicesInfo.class)).getInterfaceName();
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+                InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(interfaceName, dataBroker);
+        if (ifState == null || ifState.getOperStatus() == OperStatus.Down) {
+            LOG.info("Not unbinding Service since operstatus is {} for Interface: {}",
+                    ifState.getOperStatus(), interfaceName);
+            return futures;
+        }
+
+        // Get the Parent ServiceInfo
+        ServicesInfo servicesInfo = FlowBasedServicesUtils.getServicesInfoForInterface(interfaceName, dataBroker);
+        if (servicesInfo == null) {
+            LOG.error("Reached Impossible part in the code for bound service: {}", boundServiceOld);
+            return futures;
+        }
+
+        InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
+        Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+        NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker);
+        long portNo = Long.parseLong(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
+        BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+        Long lportTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker);
+        int vlanId = 0;
+        if (iface.getType().isAssignableFrom(L2vlan.class)) {
+            vlanId = iface.getAugmentation(IfL2vlan.class).getVlanId().getValue();
+        }
+        List<BoundServices> boundServices = servicesInfo.getBoundServices();
+        if (boundServices.isEmpty()) {
+            // Remove entry from Ingress Table.
+            FlowBasedServicesUtils.removeIngressFlow(iface, boundServiceOld, dpId, dataBroker, t);
+            if (t != null) {
+                futures.add(t.submit());
+            }
+            return futures;
+        }
+
+        Map<Short, BoundServices> tmpServicesMap = new ConcurrentHashMap<>();
+        short highestPriority = 0xFF;
+        for (BoundServices boundService : boundServices) {
+            tmpServicesMap.put(boundService.getServicePriority(), boundService);
+            if (boundService.getServicePriority() < highestPriority) {
+                highestPriority = boundService.getServicePriority();
+            }
+        }
+
+        if (highestPriority < boundServiceOld.getServicePriority()) {
+            FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, iface, boundServiceOld, dataBroker, t);
+            if (t != null) {
+                futures.add(t.submit());
+            }
+            return futures;
+        }
+
+        List<MatchInfo> matches = null;
+        if (iface.getType().isAssignableFrom(L2vlan.class)) {
+            matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, vlanId);
+        } else if (iface.getType().isAssignableFrom(Tunnel.class)){
+            matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface);
+        }
+
+        BoundServices toBeMoved = tmpServicesMap.get(highestPriority);
+        FlowBasedServicesUtils.removeIngressFlow(iface, boundServiceOld, dpId, dataBroker, t);
+        FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, vlanId, toBeMoved, dataBroker, t,
+                matches, lportTag.intValue(), IfmConstants.VLAN_INTERFACE_INGRESS_TABLE);
+        FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, iface, toBeMoved, dataBroker, t);
+
+        if (t != null) {
+            futures.add(t.submit());
+        }
+        return futures;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/listeners/FlowBasedServicesConfigListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/listeners/FlowBasedServicesConfigListener.java
new file mode 100644 (file)
index 0000000..8b1d955
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * 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
+ */
+
+package org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.listeners;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.confighelpers.FlowBasedServicesConfigBindHelper;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.confighelpers.FlowBasedServicesConfigUnbindHelper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.ServiceBindings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+public class FlowBasedServicesConfigListener extends AsyncDataTreeChangeListenerBase<BoundServices, FlowBasedServicesConfigListener> {
+    private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesConfigListener.class);
+    private DataBroker dataBroker;
+
+    public FlowBasedServicesConfigListener(final DataBroker dataBroker) {
+        super(BoundServices.class, FlowBasedServicesConfigListener.class);
+        this.dataBroker = dataBroker;
+    }
+
+    @Override
+    protected InstanceIdentifier<BoundServices> getWildCardPath() {
+        return InstanceIdentifier.create(ServiceBindings.class).child(ServicesInfo.class)
+                .child(BoundServices.class);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<BoundServices> key, BoundServices boundServiceOld) {
+        String interfaceName = InstanceIdentifier.keyOf(key.firstIdentifierOf(ServicesInfo.class)).getInterfaceName();
+        LOG.info("Service Binding Entry removed for Interface: {}, Data: {}",
+                interfaceName, boundServiceOld);
+
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+        RendererConfigRemoveWorker configWorker = new RendererConfigRemoveWorker(key, boundServiceOld);
+        coordinator.enqueueJob(interfaceName, configWorker);
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<BoundServices> key, BoundServices boundServiceOld,
+                          BoundServices boundServiceNew) {
+        LOG.error("Service Binding entry update not allowed for: {}, Data: {}",
+                InstanceIdentifier.keyOf(key.firstIdentifierOf(ServicesInfo.class)).getInterfaceName(), boundServiceNew);
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<BoundServices> key, BoundServices boundServicesNew) {
+        String interfaceName = InstanceIdentifier.keyOf(key.firstIdentifierOf(ServicesInfo.class)).getInterfaceName();
+        LOG.info("Service Binding Entry created for Interface: {}, Data: {}",
+                interfaceName, boundServicesNew);
+
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+        RendererConfigAddWorker configWorker = new RendererConfigAddWorker(key, boundServicesNew);
+        coordinator.enqueueJob(interfaceName, configWorker);
+    }
+
+    @Override
+    protected FlowBasedServicesConfigListener getDataTreeChangeListener() {
+        return FlowBasedServicesConfigListener.this;
+    }
+
+    private class RendererConfigAddWorker implements Callable<List<ListenableFuture<Void>>> {
+        InstanceIdentifier<BoundServices> instanceIdentifier;
+        BoundServices boundServicesNew;
+
+        public RendererConfigAddWorker(InstanceIdentifier<BoundServices> instanceIdentifier,
+                                       BoundServices boundServicesNew) {
+            this.instanceIdentifier = instanceIdentifier;
+            this.boundServicesNew = boundServicesNew;
+        }
+
+        @Override
+        public List<ListenableFuture<Void>> call() throws Exception {
+            return FlowBasedServicesConfigBindHelper.bindService(instanceIdentifier,
+                    boundServicesNew, dataBroker);
+        }
+    }
+
+    private class RendererConfigRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
+        InstanceIdentifier<BoundServices> instanceIdentifier;
+        BoundServices boundServicesNew;
+
+        public RendererConfigRemoveWorker(InstanceIdentifier<BoundServices> instanceIdentifier,
+                                       BoundServices boundServicesNew) {
+            this.instanceIdentifier = instanceIdentifier;
+            this.boundServicesNew = boundServicesNew;
+        }
+
+        @Override
+        public List<ListenableFuture<Void>> call() throws Exception {
+            return FlowBasedServicesConfigUnbindHelper.unbindService(instanceIdentifier,
+                    boundServicesNew, dataBroker);
+        }
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/listeners/FlowBasedServicesInterfaceStateListener.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/listeners/FlowBasedServicesInterfaceStateListener.java
new file mode 100644 (file)
index 0000000..9ec65bc
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.listeners;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.vpnservice.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.statehelpers.FlowBasedServicesStateBindHelper;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.statehelpers.FlowBasedServicesStateUnbindHelper;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+public class FlowBasedServicesInterfaceStateListener extends AsyncDataTreeChangeListenerBase<Interface, FlowBasedServicesInterfaceStateListener> {
+    private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesInterfaceStateListener.class);
+    private DataBroker dataBroker;
+
+    public FlowBasedServicesInterfaceStateListener(final DataBroker dataBroker) {
+        super(Interface.class, FlowBasedServicesInterfaceStateListener.class);
+        this.dataBroker = dataBroker;
+    }
+
+    @Override
+    protected InstanceIdentifier<Interface> getWildCardPath() {
+        return InstanceIdentifier.create(InterfacesState.class).child(Interface.class);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<Interface> key, Interface interfaceStateOld) {
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+        RendererStateInterfaceUnbindWorker stateUnbindWorker =
+                new RendererStateInterfaceUnbindWorker(interfaceStateOld);
+        coordinator.enqueueJob(interfaceStateOld.getName(), stateUnbindWorker);
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<Interface> key, Interface interfaceStateOld, Interface interfaceStateNew) {
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+        if (interfaceStateNew.getOperStatus() == Interface.OperStatus.Down) {
+            RendererStateInterfaceUnbindWorker stateUnbindWorker =
+                    new RendererStateInterfaceUnbindWorker(interfaceStateNew);
+            coordinator.enqueueJob(interfaceStateNew.getName(), stateUnbindWorker);
+            return;
+        }
+
+        RendererStateInterfaceBindWorker stateBindWorker = new RendererStateInterfaceBindWorker(interfaceStateNew);
+        coordinator.enqueueJob(interfaceStateNew.getName(), stateBindWorker);
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<Interface> key, Interface interfaceStateNew) {
+        if (interfaceStateNew.getOperStatus() == Interface.OperStatus.Down) {
+            LOG.info("Interface: {} operstate is down when adding. Not Binding services", interfaceStateNew.getName());
+            return;
+        }
+
+        DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
+        RendererStateInterfaceBindWorker stateBindWorker = new RendererStateInterfaceBindWorker(interfaceStateNew);
+        coordinator.enqueueJob(interfaceStateNew.getName(), stateBindWorker);
+    }
+
+    @Override
+    protected FlowBasedServicesInterfaceStateListener getDataTreeChangeListener() {
+        return FlowBasedServicesInterfaceStateListener.this;
+    }
+
+    private class RendererStateInterfaceBindWorker implements Callable<List<ListenableFuture<Void>>> {
+        Interface iface;
+
+        public RendererStateInterfaceBindWorker(Interface iface) {
+            this.iface = iface;
+        }
+
+        @Override
+        public List<ListenableFuture<Void>> call() throws Exception {
+            return FlowBasedServicesStateBindHelper.bindServicesOnInterface(iface, dataBroker);
+        }
+    }
+
+    private class RendererStateInterfaceUnbindWorker implements Callable<List<ListenableFuture<Void>>> {
+        Interface iface;
+
+        public RendererStateInterfaceUnbindWorker(Interface iface) {
+            this.iface = iface;
+        }
+
+        @Override
+        public List<ListenableFuture<Void>> call() throws Exception {
+            return FlowBasedServicesStateUnbindHelper.unbindServicesFromInterface(iface, dataBroker);
+        }
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/statehelpers/FlowBasedServicesStateBindHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/statehelpers/FlowBasedServicesStateBindHelper.java
new file mode 100644 (file)
index 0000000..0e067c4
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.statehelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+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.iana._if.type.rev140508.Tunnel;
+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.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FlowBasedServicesStateBindHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesStateBindHelper.class);
+
+    public static List<ListenableFuture<Void>> bindServicesOnInterface(Interface ifaceState,
+                                                             DataBroker dataBroker) {
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+        ServicesInfo servicesInfo = FlowBasedServicesUtils.getServicesInfoForInterface(ifaceState.getName(), dataBroker);
+        if (servicesInfo == null) {
+            return futures;
+        }
+
+        List<BoundServices> allServices = servicesInfo.getBoundServices();
+        if (allServices == null || allServices.isEmpty()) {
+            return futures;
+        }
+
+        BoundServices highestPriorityBoundService = null;
+        short highestPriority = 0xFF;
+        for (BoundServices boundService : allServices) {
+            if (boundService.getServicePriority() < highestPriority) {
+                highestPriorityBoundService = boundService;
+                highestPriority = boundService.getServicePriority();
+            }
+        }
+
+        InterfaceKey interfaceKey = new InterfaceKey(ifaceState.getName());
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+                    InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+
+        NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker);
+        long portNo = Long.parseLong(IfmUtil.getPortNoFromNodeConnectorId(nodeConnectorId));
+        BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+        Long lportTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker);
+        int vlanId = 0;
+        List<MatchInfo> matches = null;
+        if (iface.getType().isAssignableFrom(L2vlan.class)) {
+            vlanId = iface.getAugmentation(IfL2vlan.class).getVlanId().getValue();
+            matches = FlowBasedServicesUtils.getMatchInfoForVlanPortAtIngressTable(dpId, portNo, vlanId);
+        } else if (iface.getType().isAssignableFrom(Tunnel.class)){
+            matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable (dpId, portNo, iface);
+        }
+
+        if (matches != null) {
+            FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, vlanId, highestPriorityBoundService,
+                    dataBroker, t, matches, lportTag.intValue(), IfmConstants.VLAN_INTERFACE_INGRESS_TABLE);
+        }
+
+        for (BoundServices boundService : allServices) {
+            if (!boundService.equals(highestPriorityBoundService)) {
+                FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, boundService, iface,
+                         dataBroker, t, lportTag.intValue());
+            }
+        }
+
+        futures.add(t.submit());
+        return futures;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/statehelpers/FlowBasedServicesStateUnbindHelper.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/statehelpers/FlowBasedServicesStateUnbindHelper.java
new file mode 100644 (file)
index 0000000..2370580
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.statehelpers;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
+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.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FlowBasedServicesStateUnbindHelper {
+    private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesStateUnbindHelper.class);
+
+    public static List<ListenableFuture<Void>> unbindServicesFromInterface(Interface ifaceState,
+                                                                           DataBroker dataBroker) {
+        List<ListenableFuture<Void>> futures = new ArrayList<>();
+        WriteTransaction t = dataBroker.newWriteOnlyTransaction();
+
+        ServicesInfo servicesInfo = FlowBasedServicesUtils.getServicesInfoForInterface(ifaceState.getName(), dataBroker);
+        if (servicesInfo == null) {
+            return futures;
+        }
+
+        List<BoundServices> allServices = servicesInfo.getBoundServices();
+        if (allServices == null || allServices.isEmpty()) {
+            return futures;
+        }
+
+        BoundServices highestPriorityBoundService = null;
+        short highestPriority = 0xFF;
+        for (BoundServices boundService : allServices) {
+            if (boundService.getServicePriority() < highestPriority) {
+                highestPriorityBoundService = boundService;
+                highestPriority = boundService.getServicePriority();
+            }
+        }
+
+        InterfaceKey interfaceKey = new InterfaceKey(ifaceState.getName());
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface =
+                InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceKey, dataBroker);
+
+        NodeConnectorId nodeConnectorId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker);
+        BigInteger dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId));
+        Long lportTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker);
+
+        FlowBasedServicesUtils.removeIngressFlow(iface, highestPriorityBoundService, dpId,
+                dataBroker, t);
+
+        for (BoundServices boundService : allServices) {
+            if (!boundService.equals(highestPriorityBoundService)) {
+                FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, iface, boundService, dataBroker, t);
+            }
+        }
+
+        return futures;
+    }
+}
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/utilities/FlowBasedServicesUtils.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/servicebindings/flowbased/utilities/FlowBasedServicesUtils.java
new file mode 100644 (file)
index 0000000..8df055b
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.interfacemgr.IfmConstants;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.ServiceBindings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.StypeOpenflow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfoKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FlowBasedServicesUtils {
+    private static final Logger LOG = LoggerFactory.getLogger(FlowBasedServicesUtils.class);
+
+    public static ServicesInfo getServicesInfoForInterface(String interfaceName, DataBroker dataBroker) {
+        ServicesInfoKey servicesInfoKey = new ServicesInfoKey(interfaceName);
+        InstanceIdentifier.InstanceIdentifierBuilder<ServicesInfo> servicesInfoIdentifierBuilder =
+                InstanceIdentifier.builder(ServiceBindings.class).child(ServicesInfo.class, servicesInfoKey);
+        Optional<ServicesInfo> servicesInfoOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION,
+                servicesInfoIdentifierBuilder.build(), dataBroker);
+
+        if (servicesInfoOptional.isPresent()) {
+            return servicesInfoOptional.get();
+        }
+
+        return null;
+    }
+
+    public static NodeConnectorId getNodeConnectorIdFromInterface(Interface iface, DataBroker dataBroker) {
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
+                InterfaceManagerCommonUtils.getInterfaceStateFromOperDS(iface.getName(), dataBroker);
+        List<String> ofportIds = ifState.getLowerLayerIf();
+        return new NodeConnectorId(ofportIds.get(0));
+    }
+
+    public static List<MatchInfo> getMatchInfoForVlanPortAtIngressTable(BigInteger dpId, long portNo, long vlanId) {
+        List<MatchInfo> matches = new ArrayList<>();
+        matches.add(new MatchInfo(MatchFieldType.in_port, new BigInteger[] {dpId, BigInteger.valueOf(portNo)}));
+        if (vlanId > 0) {
+            LOG.error("VlanId matching support is not fully available in Be.");
+            matches.add(new MatchInfo(MatchFieldType.vlan_vid, new long[]{vlanId}));
+        }
+        return matches;
+    }
+
+    public static List<MatchInfo> getMatchInfoForTunnelPortAtIngressTable(BigInteger dpId, long portNo, Interface iface) {
+        List<MatchInfo> matches = new ArrayList<MatchInfo>();
+        matches.add(new MatchInfo(MatchFieldType.in_port, new BigInteger[]{dpId, BigInteger.valueOf(portNo)}));
+        /*IfTunnel tunnel = iface.getAugmentation(IfTunnel.class);
+        TunnelResources tunnelResources = tunnel.getTunnelResources();
+        if (tunnelResources.getTunnelType().isAssignableFrom(TunnelTypeGre.class)) {
+            IfGre ifgre = tunnelResources.getAugmentation(IfGre.class);
+            BigInteger grekey = ifgre.getGreKey();
+            // FIXME: Add tunnel-id match information
+
+        } else if (tunnelResources.getTunnelType().isAssignableFrom(TunnelTypeVxlan.class)) {
+            IfVxlan ifVxlan = tunnelResources.getAugmentation(IfVxlan.class);
+            BigInteger vni = ifVxlan.getVni();
+            // FIXME: Add tunnel-id match information
+        }*/
+
+        return matches;
+    }
+
+    public static List<MatchInfo> getMatchInfoForDispatcherTable(BigInteger dpId, Interface iface,
+                                                                 int interfaceTag, short servicePriority) {
+        List<MatchInfo> matches = new ArrayList<MatchInfo>();
+        matches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
+                MetaDataUtil.getMetaDataForLPortDispatcher(interfaceTag, servicePriority),
+                MetaDataUtil.getMetaDataMaskForLPortDispatcher() }));
+        /*if (iface.getType().isAssignableFrom(Tunnel.class)) {
+            IfTunnel tunnel = iface.getAugmentation(IfTunnel.class);
+            TunnelResources tunnelResources = tunnel.getTunnelResources();
+            if (tunnelResources.getTunnelType().isAssignableFrom(TunnelTypeGre.class)) {
+                IfGre ifgre = tunnelResources.getAugmentation(IfGre.class);
+                BigInteger grekey = ifgre.getGreKey();
+                // FIXME: Add tunnel-id match information
+
+            } else if (tunnelResources.getTunnelType().isAssignableFrom(TunnelTypeVxlan.class)) {
+                IfVxlan ifVxlan = tunnelResources.getAugmentation(IfVxlan.class);
+                BigInteger vni = ifVxlan.getVni();
+                // FIXME: Add tunnel-id match information
+            }
+        }*/
+        return matches;
+    }
+
+    public static Long getLPortTag(Interface iface, DataBroker dataBroker) {
+        /*ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
+        String portName = parentRefs.getParentInterface();
+        BigInteger dpIdFromInterface = parentRefs.getDatapathNodeIdentifier();
+        String portKey = FlowBasedServicesUtils.getInterfaceRefInfo(dpIdFromInterface.toString(), portName);
+        if (iface.getType().isAssignableFrom(L2vlan.class)) {
+            InterfacesMetaKey interfacesMetaKey = new InterfacesMetaKey(portKey);
+            InterfacesInfoKey interfacesInfoKey = new InterfacesInfoKey(iface.getName());
+            InterfacesInfo interfacesInfo = VlanInterfaceUtilities.getInterfacesInfoFromConfigDS(interfacesMetaKey,
+                    interfacesInfoKey, dataBroker);
+            return interfacesInfo.getLporttag();
+        } else if (iface.getType().isAssignableFrom(Tunnel.class)) {
+            TunnelInterfaceRefInfoKey tunnelInterfaceRefInfoKey = new TunnelInterfaceRefInfoKey(portKey);
+            TunnelInterfaceEntries tunnelInterfaceEntries =
+                    TunnelInterfaceUtilities.getTunnelInterfaceRefEntriesFromConfigDs(
+                            tunnelInterfaceRefInfoKey, iface.getName(), dataBroker);
+            return tunnelInterfaceEntries.getLportTag();
+        } */
+        return 0L;
+    }
+
+    public static void installInterfaceIngressFlow(BigInteger dpId, int vlanId,
+                                                   BoundServices boundServiceNew,
+                                                   DataBroker dataBroker, WriteTransaction t,
+                                                   List<MatchInfo> matches, int lportTag, short tableId) {
+        List<Instruction> instructions = boundServiceNew.getAugmentation(StypeOpenflow.class).getInstruction();
+
+        int serviceInstructionsSize = instructions.size();
+        List<Instruction> instructionSet = new ArrayList<Instruction>();
+        if (vlanId != 0) {
+            // incrementing instructionSize and using it as actionKey. Because it won't clash with any other instructions
+            int actionKey = ++serviceInstructionsSize;
+            instructionSet.add(MDSALUtil.buildAndGetPopVlanActionInstruction(actionKey, ++serviceInstructionsSize));
+        }
+
+        if (lportTag != 0L) {
+            BigInteger[] metadataValues = IfmUtil.mergeOpenflowMetadataWriteInstructions(instructions);
+            short sIndex = boundServiceNew.getServicePriority();
+            BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(lportTag,
+                    ++sIndex, metadataValues[0]);
+            BigInteger metadataMask = MetaDataUtil.getMetaDataMaskForLPortDispatcher(
+                    MetaDataUtil.METADATA_MASK_SERVICE_INDEX,
+                    MetaDataUtil.METADATA_MASK_LPORT_TAG, metadataValues[1]);
+            instructionSet.add(MDSALUtil.buildAndGetWriteMetadaInstruction(metadata, metadataMask,
+                    ++serviceInstructionsSize));
+        }
+
+        if (instructions != null && !instructions.isEmpty()) {
+            for (Instruction info : instructions) {
+                // Skip meta data write as that is handled already
+                if (info.getInstruction() instanceof WriteMetadataCase) {
+                    continue;
+                }
+                instructionSet.add(info);
+            }
+        }
+
+        String serviceRef = boundServiceNew.getServiceName();
+        StypeOpenflow stypeOpenflow = boundServiceNew.getAugmentation(StypeOpenflow.class);
+        Flow ingressFlow = MDSALUtil.buildFlowNew(tableId, serviceRef,
+                stypeOpenflow.getFlowPriority(), serviceRef, 0, 0,
+                stypeOpenflow.getFlowCookie(), matches, instructionSet);
+        installFlow(dpId, ingressFlow, dataBroker, t);
+    }
+
+    private static void installFlow(BigInteger dpId, Flow flow, DataBroker dataBroker, WriteTransaction t) {
+        FlowKey flowKey = new FlowKey(new FlowId(flow.getId()));
+        Node nodeDpn = buildInventoryDpnNode(dpId);
+        InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class)
+                .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
+                .child(Table.class, new TableKey(flow.getTableId())).child(Flow.class,flowKey).build();
+
+        t.put(LogicalDatastoreType.CONFIGURATION, flowInstanceId, flow, true);
+    }
+
+    private static Node buildInventoryDpnNode(BigInteger dpnId) {
+        NodeId nodeId = new NodeId("openflow:" + dpnId);
+        Node nodeDpn = new NodeBuilder().setId(nodeId).setKey(new NodeKey(nodeId)).build();
+
+        return nodeDpn;
+    }
+
+    public static void installLPortDispatcherFlow(BigInteger dpId, BoundServices boundService, Interface iface,
+                                                  DataBroker dataBroker, WriteTransaction t, int interfaceTag) {
+        LOG.debug("Installing LPort Dispatcher Flows {}, {}", dpId, iface);
+        short serviceIndex = boundService.getServicePriority();
+        String serviceRef = boundService.getServiceName();
+        List<MatchInfo> matches = FlowBasedServicesUtils.getMatchInfoForDispatcherTable(dpId, iface,
+                interfaceTag, serviceIndex);
+
+        // Get the metadata and mask from the service's write metadata instruction
+        StypeOpenflow stypeOpenFlow = boundService.getAugmentation(StypeOpenflow.class);
+        List<Instruction> serviceInstructions = stypeOpenFlow.getInstruction();
+        int instructionSize = serviceInstructions.size();
+        BigInteger[] metadataValues = IfmUtil.mergeOpenflowMetadataWriteInstructions(serviceInstructions);
+        BigInteger metadata = MetaDataUtil.getMetaDataForLPortDispatcher(interfaceTag, ++serviceIndex, metadataValues[0]);
+        BigInteger metadataMask = MetaDataUtil.getMetaDataMaskForLPortDispatcher(MetaDataUtil.METADATA_MASK_SERVICE_INDEX,
+                MetaDataUtil.METADATA_MASK_LPORT_TAG, metadataValues[1]);
+
+        // build the final instruction for LPort Dispatcher table flow entry
+        List<Instruction> instructions = new ArrayList<Instruction>();
+        instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(metadata, metadataMask, ++instructionSize));
+        if (serviceInstructions != null && !serviceInstructions.isEmpty()) {
+            for (Instruction info : serviceInstructions) {
+                // Skip meta data write as that is handled already
+                if (info.getInstruction() instanceof WriteMetadataCase) {
+                    continue;
+                }
+                instructions.add(info);
+            }
+        }
+
+        // build the flow and install it
+        Flow ingressFlow = MDSALUtil.buildFlowNew(stypeOpenFlow.getDispatcherTableId(), serviceRef,
+                boundService.getServicePriority(), serviceRef, 0, 0, stypeOpenFlow.getFlowCookie(), matches, instructions);
+        installFlow(dpId, ingressFlow, dataBroker, t);
+    }
+
+    public static void removeIngressFlow(Interface iface, BoundServices serviceOld, BigInteger dpId,
+                                         DataBroker dataBroker, WriteTransaction t) {
+        LOG.debug("Removing Ingress Flows");
+        String flowKeyStr = iface.getName() + serviceOld.getServicePriority() +
+                serviceOld.getServiceName() + IfmConstants.VLAN_INTERFACE_INGRESS_TABLE;
+        FlowKey flowKey = new FlowKey(new FlowId(flowKeyStr));
+        Node nodeDpn = buildInventoryDpnNode(dpId);
+        InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class)
+                .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
+                .child(Table.class, new TableKey(IfmConstants.VLAN_INTERFACE_INGRESS_TABLE)).child(Flow.class, flowKey).build();
+
+        t.delete(LogicalDatastoreType.CONFIGURATION, flowInstanceId);
+    }
+
+    public static void removeLPortDispatcherFlow(BigInteger dpId, Interface iface, BoundServices boundServicesOld,
+                                                 DataBroker dataBroker, WriteTransaction t) {
+        LOG.debug("Removing LPort Dispatcher Flows {}, {}", dpId, iface);
+        Long interfaceTag = FlowBasedServicesUtils.getLPortTag(iface, dataBroker);
+
+        StypeOpenflow stypeOpenFlow = boundServicesOld.getAugmentation(StypeOpenflow.class);
+        String flowKeyStr = iface.getName() + boundServicesOld.getServicePriority() +
+                boundServicesOld.getServiceName() + stypeOpenFlow.getDispatcherTableId();
+        FlowKey flowKey = new FlowKey(new FlowId(flowKeyStr));
+        Node nodeDpn = buildInventoryDpnNode(dpId);
+        InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class)
+                .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
+                .child(Table.class, new TableKey(stypeOpenFlow.getDispatcherTableId())).child(Flow.class, flowKey).build();
+
+        t.delete(LogicalDatastoreType.CONFIGURATION, flowInstanceId);
+    }
+
+    public static String getInterfaceRefInfo(String dpId, String portName) {
+        String portRefInfo = "";
+        if (!"".equals(dpId)) {
+            portRefInfo = dpId.toString() + ":";
+        }
+        portRefInfo = portRefInfo + portName;
+        return portRefInfo;
+    }
+}
\ No newline at end of file
index e4435ff33aa5287f8c527473bcf091a993b0ed74..c5e8e32372824a255a6fb9c4c826c9cb14553f53 100644 (file)
@@ -27,6 +27,8 @@ public class InterfacemgrImplModule extends org.opendaylight.yang.gen.v1.urn.ope
     @Override
     public java.lang.AutoCloseable createInstance() {
         InterfacemgrProvider provider = new InterfacemgrProvider();
+        provider.setRpcProviderRegistry(getRpcRegistryDependency());
+
         getBrokerDependency().registerProvider(provider);
         return provider;
     }
index d53803fabbf67103e26bc31971b7184c9aa52728..1c8851d2de73f1ae863ef4010bc69214ca3433cb 100644 (file)
@@ -32,6 +32,14 @@ module interfacemgr-impl {
                     }
                 }
             }
+            container rpc-registry {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity md-sal-binding:binding-rpc-registry;
+                    }
+                }
+            }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/AsyncDataChangeListenerBase.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/AsyncDataChangeListenerBase.java
new file mode 100644 (file)
index 0000000..fac5659
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * 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
+ */
+package org.opendaylight.vpnservice.datastoreutils;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.md.sal.binding.api.*;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+public abstract class AsyncDataChangeListenerBase<T extends DataObject, K extends DataChangeListener> implements DataChangeListener, AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(AsyncDataChangeListenerBase.class);
+
+    private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_CORE_SIZE = 1;
+    private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_MAX_SIZE = 1;
+    private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_KEEP_ALIVE_TIME_SECS = 300;
+    private static final int STARTUP_LOOP_TICK = 500;
+    private static final int STARTUP_LOOP_MAX_RETRIES = 8;
+
+    private static ThreadPoolExecutor dataChangeHandlerExecutor = new ThreadPoolExecutor(
+            DATATREE_CHANGE_HANDLER_THREAD_POOL_CORE_SIZE,
+            DATATREE_CHANGE_HANDLER_THREAD_POOL_MAX_SIZE,
+            DATATREE_CHANGE_HANDLER_THREAD_POOL_KEEP_ALIVE_TIME_SECS,
+            TimeUnit.SECONDS,
+            new LinkedBlockingQueue<Runnable>());
+
+    private ListenerRegistration<K> listenerRegistration;
+    protected final Class<T> clazz;
+    private final Class<K> eventClazz;
+
+    /**
+     * @param clazz - for which the data change event is received
+     */
+    public AsyncDataChangeListenerBase(Class<T> clazz, Class<K> eventClazz) {
+        this.clazz = Preconditions.checkNotNull(clazz, "Class can not be null!");
+        this.eventClazz = Preconditions.checkNotNull(eventClazz, "eventClazz can not be null!");
+    }
+
+    public void registerListener(final LogicalDatastoreType dsType, final DataBroker db) {
+        try {
+            TaskRetryLooper looper = new TaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
+            listenerRegistration = looper.loopUntilNoException(new Callable<ListenerRegistration<K>>() {
+                @Override
+                public ListenerRegistration call() throws Exception {
+                    return db.registerDataChangeListener(dsType, getWildCardPath(), getDataChangeListener(), getDataChangeScope());
+                }
+            });
+        } catch (final Exception e) {
+            LOG.warn("{}: Data Tree Change listener registration failed.", eventClazz.getName());
+            LOG.debug("{}: Data Tree Change listener registration failed: {}", eventClazz.getName(), e);
+            throw new IllegalStateException( eventClazz.getName() + "{}startup failed. System needs restart.", e);
+        }
+    }
+
+    @Override
+    public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
+        if (changeEvent == null) {
+            return;
+        }
+
+        DataChangeHandler dataChangeHandler = new DataChangeHandler(changeEvent);
+        dataChangeHandlerExecutor.execute(dataChangeHandler);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void createData(final Map<InstanceIdentifier<?>, DataObject> createdData) {
+        final Set<InstanceIdentifier<?>> keys = createdData.keySet() != null
+                ? createdData.keySet() : Collections.<InstanceIdentifier<?>>emptySet();
+        for (InstanceIdentifier<?> key : keys) {
+            if (clazz.equals(key.getTargetType())) {
+                InstanceIdentifier<T> createKeyIdent = key.firstIdentifierOf(clazz);
+                final Optional<DataObject> value = Optional.of(createdData.get(key));
+                if (value.isPresent()) {
+                    this.add(createKeyIdent, (T)value.get());
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void updateData(final Map<InstanceIdentifier<?>, DataObject> updateData,
+                            final Map<InstanceIdentifier<?>, DataObject> originalData) {
+
+        final Set<InstanceIdentifier<?>> keys = updateData.keySet() != null
+                ? updateData.keySet() : Collections.<InstanceIdentifier<?>>emptySet();
+        for (InstanceIdentifier<?> key : keys) {
+            if (clazz.equals(key.getTargetType())) {
+                InstanceIdentifier<T> updateKeyIdent = key.firstIdentifierOf(clazz);
+                final Optional<DataObject> value = Optional.of(updateData.get(key));
+                final Optional<DataObject> original = Optional.of(originalData.get(key));
+                if (value.isPresent() && original.isPresent()) {
+                    this.update(updateKeyIdent, (T) original.get(), (T) value.get());
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void removeData(final Set<InstanceIdentifier<?>> removeData,
+                            final Map<InstanceIdentifier<?>, DataObject> originalData) {
+
+        for (InstanceIdentifier<?> key : removeData) {
+            if (clazz.equals(key.getTargetType())) {
+                final InstanceIdentifier<T> ident = key.firstIdentifierOf(clazz);
+                final DataObject removeValue = originalData.get(key);
+                this.remove(ident, (T)removeValue);
+            }
+        }
+    }
+
+    @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("Interface Manager Closed");
+    }
+
+    protected abstract void remove(InstanceIdentifier<T> identifier, T del);
+
+    protected abstract void update(InstanceIdentifier<T> identifier, T original, T update);
+
+    protected abstract void add(InstanceIdentifier<T> identifier, T add);
+
+    protected abstract InstanceIdentifier<T> getWildCardPath();
+
+    protected abstract DataChangeListener getDataChangeListener();
+
+    protected abstract AsyncDataBroker.DataChangeScope getDataChangeScope();
+
+    public class DataChangeHandler implements Runnable {
+        final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent;
+
+        public DataChangeHandler(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
+            this.changeEvent = changeEvent;
+        }
+
+        @Override
+        public void run() {
+            Preconditions.checkNotNull(changeEvent,"Async ChangeEvent can not be null!");
+
+            /* All DataObjects for create */
+            final Map<InstanceIdentifier<?>, DataObject> createdData = changeEvent.getCreatedData() != null
+                    ? changeEvent.getCreatedData() : Collections.<InstanceIdentifier<?>, DataObject>emptyMap();
+            /* All DataObjects for remove */
+            final Set<InstanceIdentifier<?>> removeData = changeEvent.getRemovedPaths() != null
+                    ? changeEvent.getRemovedPaths() : Collections.<InstanceIdentifier<?>>emptySet();
+            /* All DataObjects for updates */
+            final Map<InstanceIdentifier<?>, DataObject> updateData = changeEvent.getUpdatedData() != null
+                    ? changeEvent.getUpdatedData() : Collections.<InstanceIdentifier<?>, DataObject>emptyMap();
+            /* All Original DataObjects */
+            final Map<InstanceIdentifier<?>, DataObject> originalData = changeEvent.getOriginalData() != null
+                    ? changeEvent.getOriginalData() : Collections.<InstanceIdentifier<?>, DataObject>emptyMap();
+
+            createData(createdData);
+            updateData(updateData, originalData);
+            removeData(removeData, originalData);
+        }
+    }
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/AsyncDataTreeChangeListenerBase.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/AsyncDataTreeChangeListenerBase.java
new file mode 100644 (file)
index 0000000..39bbdb9
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * 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
+ */
+
+package org.opendaylight.vpnservice.datastoreutils;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.md.sal.binding.api.*;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.concurrent.Callable;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+public abstract class AsyncDataTreeChangeListenerBase<T extends DataObject, K extends DataTreeChangeListener> implements DataTreeChangeListener<T>, AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(AsyncDataTreeChangeListenerBase.class);
+
+    private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_CORE_SIZE = 1;
+    private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_MAX_SIZE = 1;
+    private static final int DATATREE_CHANGE_HANDLER_THREAD_POOL_KEEP_ALIVE_TIME_SECS = 300;
+    private static final int STARTUP_LOOP_TICK = 500;
+    private static final int STARTUP_LOOP_MAX_RETRIES = 8;
+
+    private ListenerRegistration<K> listenerRegistration;
+
+    private static ThreadPoolExecutor dataTreeChangeHandlerExecutor = new ThreadPoolExecutor(
+            DATATREE_CHANGE_HANDLER_THREAD_POOL_CORE_SIZE,
+            DATATREE_CHANGE_HANDLER_THREAD_POOL_MAX_SIZE,
+            DATATREE_CHANGE_HANDLER_THREAD_POOL_KEEP_ALIVE_TIME_SECS,
+            TimeUnit.SECONDS,
+            new LinkedBlockingQueue<Runnable>());
+
+    protected final Class<T> clazz;
+    private final Class<K> eventClazz;
+
+    public AsyncDataTreeChangeListenerBase(Class<T> clazz, Class<K> eventClazz) {
+        this.clazz = Preconditions.checkNotNull(clazz, "Class can not be null!");
+        this.eventClazz = Preconditions.checkNotNull(eventClazz, "eventClazz can not be null!");
+    }
+
+    @Override
+    public void onDataTreeChanged(Collection<DataTreeModification<T>> changes) {
+        if (changes == null || changes.isEmpty()) {
+            return;
+        }
+
+        DataTreeChangeHandler dataTreeChangeHandler = new DataTreeChangeHandler(changes);
+        dataTreeChangeHandlerExecutor.execute(dataTreeChangeHandler);
+    }
+
+    public void registerListener(LogicalDatastoreType dsType, final DataBroker db) {
+        final DataTreeIdentifier<T> treeId = new DataTreeIdentifier<>(dsType, getWildCardPath());
+        try {
+            TaskRetryLooper looper = new TaskRetryLooper(STARTUP_LOOP_TICK, STARTUP_LOOP_MAX_RETRIES);
+            listenerRegistration = looper.loopUntilNoException(new Callable<ListenerRegistration<K>>() {
+                @Override
+                public ListenerRegistration<K> call() throws Exception {
+                    return db.registerDataTreeChangeListener(treeId, getDataTreeChangeListener());
+                }
+            });
+        } catch (final Exception e) {
+            LOG.warn("{}: Data Tree Change listener registration failed.", eventClazz.getName());
+            LOG.debug("{}: Data Tree Change listener registration failed: {}", eventClazz.getName(), e);
+            throw new IllegalStateException( eventClazz.getName() + "{}startup failed. System needs restart.", e);
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (final Exception e) {
+                LOG.error("Error when cleaning up DataTreeChangeListener.", e);
+            }
+            listenerRegistration = null;
+        }
+    }
+
+    protected abstract InstanceIdentifier<T> getWildCardPath();
+    protected abstract void remove(InstanceIdentifier<T> key, T dataObjectModification);
+    protected abstract void update(InstanceIdentifier<T> key, T dataObjectModificationBefore, T dataObjectModificationAfter);
+    protected abstract void add(InstanceIdentifier<T> key, T dataObjectModification);
+    protected abstract K getDataTreeChangeListener();
+
+    public class DataTreeChangeHandler implements Runnable {
+        Collection<DataTreeModification<T>> changes;
+
+        public DataTreeChangeHandler(Collection<DataTreeModification<T>> changes) {
+            this.changes = changes;
+        }
+
+
+
+        @Override
+        public void run() {
+            for (DataTreeModification<T> change : changes) {
+                final InstanceIdentifier<T> key = change.getRootPath().getRootIdentifier();
+                final DataObjectModification<T> mod = change.getRootNode();
+
+                switch (mod.getModificationType()) {
+                    case DELETE:
+                        remove(key, mod.getDataBefore());
+                        break;
+                    case SUBTREE_MODIFIED:
+                        update(key, mod.getDataBefore(), mod.getDataAfter());
+                        break;
+                    case WRITE:
+                        if (mod.getDataBefore() == null) {
+                            add(key, mod.getDataAfter());
+                        } else {
+                            update(key, mod.getDataBefore(), mod.getDataAfter());
+                        }
+                        break;
+                    default:
+                        // FIXME: May be not a good idea to throw.
+                        throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/DataStoreJobCoordinator.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/DataStoreJobCoordinator.java
new file mode 100644 (file)
index 0000000..8a31ca3
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * 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
+ */
+
+package org.opendaylight.vpnservice.datastoreutils;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.TimeUnit;
+
+public class DataStoreJobCoordinator {
+    private static final Logger LOG = LoggerFactory.getLogger(DataStoreJobCoordinator.class);
+
+    private static final int THREADPOOL_SIZE = Runtime.getRuntime().availableProcessors();
+
+    private ForkJoinPool fjPool;
+    private Map<Integer,Map<String, JobQueue>> jobQueueMap = new ConcurrentHashMap<>();
+
+    private static DataStoreJobCoordinator instance;
+
+    static {
+        instance = new DataStoreJobCoordinator();
+    }
+
+    public static DataStoreJobCoordinator getInstance() {
+        return instance;
+    }
+
+    /**
+     *
+     */
+    private DataStoreJobCoordinator() {
+        fjPool = new ForkJoinPool();
+
+        for (int i = 0; i < THREADPOOL_SIZE; i++) {
+            Map<String, JobQueue> jobEntriesMap = new ConcurrentHashMap<String, JobQueue>();
+            jobQueueMap.put(i, jobEntriesMap);
+        }
+
+        new Thread(new JobQueueHandler()).start();
+    }
+
+    public void enqueueJob(String key,
+                           Callable<List<ListenableFuture<Void>>> mainWorker) {
+        enqueueJob(key, mainWorker, null, 0);
+    }
+
+    public void enqueueJob(String key,
+                           Callable<List<ListenableFuture<Void>>> mainWorker,
+                           RollbackCallable rollbackWorker) {
+        enqueueJob(key, mainWorker, rollbackWorker, 0);
+    }
+
+    public void enqueueJob(String key,
+                           Callable<List<ListenableFuture<Void>>> mainWorker,
+                           int maxRetries) {
+        enqueueJob(key, mainWorker, null, maxRetries);
+    }
+
+    /**
+     *
+     * @param key
+     * @param mainWorker
+     * @param rollbackWorker
+     * @param maxRetries
+     *
+     * This is used by the external applications to enqueue a Job with an appropriate key.
+     * A JobEntry is created and queued appropriately.
+     */
+
+    public void enqueueJob(String key,
+                           Callable<List<ListenableFuture<Void>>> mainWorker,
+                           RollbackCallable rollbackWorker,
+                           int maxRetries) {
+        JobEntry jobEntry = new JobEntry(key, mainWorker, rollbackWorker, maxRetries);
+        Integer hashKey = getHashKey(key);
+        LOG.debug("Obtained Hashkey: {}, for jobkey: {}", hashKey, key);
+
+        Map<String, JobQueue> jobEntriesMap = jobQueueMap.get(hashKey);
+        synchronized (jobEntriesMap) {
+            JobQueue jobQueue = jobEntriesMap.get(key);
+            if (jobQueue == null) {
+                jobQueue = new JobQueue();
+            }
+            jobQueue.addEntry(jobEntry);
+            jobEntriesMap.put(key, jobQueue);
+        }
+
+        jobQueueMap.put(hashKey, jobEntriesMap); // Is this really needed ?
+    }
+
+    /**
+     * clearJob is used to cleanup the submitted job from the jobqueue.
+     **/
+    private void clearJob(JobEntry jobEntry) {
+        Map<String, JobQueue> jobEntriesMap = jobQueueMap.get(getHashKey(jobEntry.getKey()));
+        synchronized (jobEntriesMap) {
+            JobQueue jobQueue = jobEntriesMap.get(jobEntry.getKey());
+            jobQueue.setExecutingEntry(null);
+            if (jobQueue.getWaitingEntries().isEmpty()) {
+                jobEntriesMap.remove(jobEntry.getKey());
+            }
+        }
+    }
+
+    /**
+     *
+     * @param key
+     * @return generated hashkey
+     *
+     * Used to generate the hashkey in to the jobQueueMap.
+     */
+    private Integer getHashKey(String key) {
+        int code = key.hashCode();
+        return (code % THREADPOOL_SIZE + THREADPOOL_SIZE) % THREADPOOL_SIZE;
+    }
+
+    /**
+     * JobCallback class is used as a future callback for
+     * main and rollback workers to handle success and failure.
+     */
+    private class JobCallback implements FutureCallback<List<Void>> {
+        private JobEntry jobEntry;
+
+        public JobCallback(JobEntry jobEntry) {
+            this.jobEntry = jobEntry;
+        }
+
+        /**
+         * @param voids
+         * This implies that all the future instances have returned success. -- TODO: Confirm this
+         */
+        @Override
+        public void onSuccess(List<Void> voids) {
+            clearJob(jobEntry);
+        }
+
+        /**
+         *
+         * @param throwable
+         * This method is used to handle failure callbacks.
+         * If more retry needed, the retrycount is decremented and mainworker is executed again.
+         * After retries completed, rollbackworker is executed.
+         * If rollbackworker fails, this is a double-fault. Double fault is logged and ignored.
+         */
+
+        @Override
+        public void onFailure(Throwable throwable) {
+            LOG.warn("Job: {} failed with exception: {}", jobEntry, throwable.getStackTrace());
+            if (jobEntry.getMainWorker() == null) {
+                LOG.error("Job: {} failed with Double-Fault. Bailing Out.", jobEntry);
+                clearJob(jobEntry);
+                return;
+            }
+
+            if (jobEntry.decrementRetryCountAndGet() > 0) {
+                MainTask worker = new MainTask(jobEntry);
+                fjPool.execute(worker);
+                return;
+            }
+
+            if (jobEntry.getRollbackWorker() != null) {
+                jobEntry.setMainWorker(null);
+                RollbackTask rollbackTask = new RollbackTask(jobEntry);
+                fjPool.execute(rollbackTask);
+                return;
+            }
+
+            clearJob(jobEntry);
+        }
+    }
+
+    /**
+     * RollbackTask is used to execute the RollbackCallable provided by the application
+     * in the eventuality of a failure.
+     */
+
+    private class RollbackTask implements Runnable {
+        private JobEntry jobEntry;
+
+        public RollbackTask(JobEntry jobEntry) {
+            this.jobEntry = jobEntry;
+        }
+
+        @Override
+        public void run() {
+            RollbackCallable callable = jobEntry.getRollbackWorker();
+            callable.setFutures(jobEntry.getFutures());
+            List<ListenableFuture<Void>> futures = null;
+
+            try {
+                futures = callable.call();
+            } catch (Exception e){
+                LOG.error("Exception when executing jobEntry: {}, exception: {}", jobEntry, e.getStackTrace());
+                e.printStackTrace();
+            }
+
+            if (futures == null || futures.isEmpty()) {
+                clearJob(jobEntry);
+                return;
+            }
+
+            ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
+            Futures.addCallback(listenableFuture, new JobCallback(jobEntry));
+            jobEntry.setFutures(futures);
+        }
+    }
+
+    /**
+     * MainTask is used to execute the MainWorker callable.
+     */
+
+    private class MainTask implements Runnable {
+        private JobEntry jobEntry;
+
+        public MainTask(JobEntry jobEntry) {
+            this.jobEntry = jobEntry;
+        }
+
+        @Override
+        public void run() {
+            List<ListenableFuture<Void>> futures = null;
+            try {
+                futures = jobEntry.getMainWorker().call();
+            } catch (Exception e){
+                LOG.error("Exception when executing jobEntry: {}, exception: {}", jobEntry, e.getStackTrace());
+                e.printStackTrace();
+            }
+
+            if (futures == null || futures.isEmpty()) {
+                clearJob(jobEntry);
+                return;
+            }
+
+            ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
+            Futures.addCallback(listenableFuture, new JobCallback(jobEntry));
+            jobEntry.setFutures(futures);
+        }
+    }
+
+    private class JobQueueHandler implements Runnable {
+        @Override
+        public void run() {
+            LOG.debug("Starting JobQueue Handler Thread.");
+            while (true) {
+                try {
+                    boolean jobAddedToPool = false;
+                    for (int i = 0; i < THREADPOOL_SIZE; i++) {
+                        Map<String, JobQueue> jobEntriesMap = jobQueueMap.get(i);
+                        if (jobEntriesMap.isEmpty()) {
+                            continue;
+                        }
+
+                        synchronized (jobEntriesMap) {
+                            Iterator it = jobEntriesMap.entrySet().iterator();
+                            while (it.hasNext()) {
+                                Map.Entry<String, JobQueue> entry = (Map.Entry)it.next();
+                                if (entry.getValue().getExecutingEntry() != null) {
+                                    continue;
+                                }
+                                JobEntry jobEntry = entry.getValue().getWaitingEntries().poll();
+                                if (jobEntry != null) {
+                                    entry.getValue().setExecutingEntry(jobEntry);
+                                    MainTask worker = new MainTask(jobEntry);
+                                    fjPool.execute(worker);
+                                    jobAddedToPool = true;
+                                } else {
+                                    it.remove();
+                                }
+                            }
+                        }
+                    }
+
+                    if (!jobAddedToPool) {
+                        TimeUnit.SECONDS.sleep(1);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                } catch (Throwable e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/JobEntry.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/JobEntry.java
new file mode 100644 (file)
index 0000000..bb9849a
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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
+ */
+
+package org.opendaylight.vpnservice.datastoreutils;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * JobEntry is the entity built per job submitted by the application and
+ * enqueued to the book-keeping data structure.
+ */
+public class JobEntry {
+    final private String key;
+    private Callable<List<ListenableFuture<Void>>> mainWorker;
+    final private RollbackCallable rollbackWorker;
+    private AtomicInteger retryCount;
+    private List<ListenableFuture<Void>> futures;
+
+    public JobEntry(String key,
+                    Callable<List<ListenableFuture<Void>>> mainWorker,
+                    RollbackCallable rollbackWorker,
+                    int maxRetries) {
+        this.key = key;
+        this.mainWorker = mainWorker;
+        this.rollbackWorker = rollbackWorker;
+        retryCount = new AtomicInteger(maxRetries);
+    }
+
+    /**
+     *
+     * @return
+     *
+     * The key provided by the application that segregates the
+     * callables that can be run parallely.
+     * NOTE: Currently, this is a string. Can be converted to Object where
+     * Object implementation should provide the hashcode and equals methods.
+     */
+    public String getKey() {
+        return key;
+    }
+
+    public Callable<List<ListenableFuture<Void>>> getMainWorker() {
+        return mainWorker;
+    }
+
+    public void setMainWorker(Callable<List<ListenableFuture<Void>>> mainWorker) {
+        this.mainWorker = mainWorker;
+    }
+
+    public RollbackCallable getRollbackWorker() {
+        return rollbackWorker;
+    }
+
+    public int decrementRetryCountAndGet() {
+        return retryCount.decrementAndGet();
+    }
+
+    public List<ListenableFuture<Void>> getFutures() {
+        return futures;
+    }
+
+    public void setFutures(List<ListenableFuture<Void>> futures) {
+        this.futures = futures;
+    }
+
+    @Override
+    public String toString() {
+        return "JobEntry{" +
+                "key='" + key + '\'' +
+                ", mainWorker=" + mainWorker +
+                ", rollbackWorker=" + rollbackWorker +
+                ", retryCount=" + retryCount +
+                ", futures=" + futures +
+                '}';
+    }
+}
\ No newline at end of file
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/JobQueue.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/JobQueue.java
new file mode 100644 (file)
index 0000000..6447731
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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
+ */
+
+package org.opendaylight.vpnservice.datastoreutils;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class JobQueue {
+    private ConcurrentLinkedQueue<JobEntry> waitingEntries;
+    private JobEntry executingEntry;
+
+    public JobQueue() {
+        waitingEntries = new ConcurrentLinkedQueue<JobEntry>();
+    }
+
+    public void addEntry(JobEntry entry) {
+        waitingEntries.add(entry); // FIXME - Try/Catch.
+    }
+
+    public ConcurrentLinkedQueue<JobEntry> getWaitingEntries() {
+        return waitingEntries;
+    }
+
+    public JobEntry getExecutingEntry() {
+        return executingEntry;
+    }
+
+    public void setExecutingEntry(JobEntry executingEntry) {
+        this.executingEntry = executingEntry;
+    }
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/RollbackCallable.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/RollbackCallable.java
new file mode 100644 (file)
index 0000000..6b8fe23
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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
+ */
+
+package org.opendaylight.vpnservice.datastoreutils;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+public abstract class RollbackCallable implements Callable<List<ListenableFuture<Void>>> {
+
+    private List<ListenableFuture<Void>> futures;
+
+    public RollbackCallable() {
+    }
+
+    public List<ListenableFuture<Void>> getFutures() {
+        return futures;
+    }
+
+    public void setFutures(List<ListenableFuture<Void>> futures) {
+        this.futures = futures;
+    }
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/TaskRetryLooper.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/datastoreutils/TaskRetryLooper.java
new file mode 100644 (file)
index 0000000..94b6643
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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
+ */
+
+package org.opendaylight.vpnservice.datastoreutils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.Callable;
+
+public class TaskRetryLooper {
+    private static final Logger LOG = LoggerFactory.getLogger(TaskRetryLooper.class);
+
+    private final long tick;
+    private final int maxRetries;
+
+    /**
+     * @param tick       sleep between steps in miliseconds
+     * @param maxRetries retries limit
+     */
+    public TaskRetryLooper(long tick, int maxRetries) {
+        this.tick = tick;
+        this.maxRetries = maxRetries;
+    }
+
+    public <T> T loopUntilNoException(Callable<T> task) throws Exception {
+        T output = null;
+
+        Exception taskException = null;
+        for (int i = 0; i < maxRetries; i++) {
+            taskException = null;
+            try {
+                output = task.call();
+                break;
+            } catch (Exception exception) {
+                LOG.debug("looper step failed: {}", exception.getMessage());
+                taskException = exception;
+            }
+
+            try {
+                Thread.sleep(tick);
+            } catch (InterruptedException e) {
+                LOG.debug("interrupted: {}", e.getMessage(), e);
+            }
+        }
+
+        if (taskException != null) {
+            throw taskException;
+        }
+
+        LOG.debug("looper step succeeded: {}", output);
+        return output;
+    }
+}
\ No newline at end of file
index 1f09d8bc842531434c639ec94b1534f67e3cb01a..23b7b619ea430a87bf6b7d9c84c55b156c9fb140 100644 (file)
@@ -16,6 +16,10 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.LinkedBlockingQueue;
 
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
@@ -27,7 +31,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.I
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadataBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
@@ -102,6 +114,23 @@ public class MDSALUtil {
                 .setCookie(new FlowCookie(cookie)).build();
     }
 
+    public static Flow buildFlowNew(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
+                                 int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo, List<Instruction> listInstructionInfo) {
+        return MDSALUtil.buildFlowNew(tableId, flowId, priority, flowName, idleTimeOut, hardTimeOut, cookie,
+                listMatchInfo, listInstructionInfo, true);
+    }
+
+    private static Flow buildFlowNew(short tableId, String flowId, int priority, String flowName, int idleTimeOut,
+                                  int hardTimeOut, BigInteger cookie, List<MatchInfo> listMatchInfo,
+                                  List<Instruction> listInstructionInfo, boolean isStrict) {
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        return new FlowBuilder().setMatch(buildMatches(listMatchInfo)).setKey(key)
+                .setPriority(Integer.valueOf(priority)).setInstructions(new InstructionsBuilder().setInstruction(listInstructionInfo).build())
+                .setBarrier(false).setInstallHw(true).setHardTimeout(hardTimeOut).setIdleTimeout(idleTimeOut)
+                .setFlowName(flowName).setTableId(Short.valueOf(tableId)).setStrict(isStrict)
+                .setCookie(new FlowCookie(cookie)).build();
+    }
+
     public static GroupEntity buildGroupEntity(BigInteger dpnId, long groupId, String groupName, GroupTypes groupType,
             List<BucketInfo> listBucketInfo) {
 
@@ -283,4 +312,28 @@ public class MDSALUtil {
         // TODO Auto-generated method stub
         return null;
     }
+
+    public static Instruction buildAndGetPopVlanActionInstruction(int actionKey, int instructionKey) {
+        Action popVlanAction = new ActionBuilder().setAction(
+                new PopVlanActionCaseBuilder().setPopVlanAction(new PopVlanActionBuilder().build()).build())
+                .setKey(new ActionKey(actionKey)).build();
+        List<Action> listAction = new ArrayList<Action> ();
+        listAction.add(popVlanAction);
+        ApplyActions applyActions = new ApplyActionsBuilder().setAction(listAction).build();
+        ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();
+        InstructionBuilder instructionBuilder = new InstructionBuilder();
+
+        instructionBuilder.setInstruction(applyActionsCase);
+        instructionBuilder.setKey(new InstructionKey(instructionKey));
+        return instructionBuilder.build();
+    }
+
+    public static Instruction buildAndGetWriteMetadaInstruction(BigInteger metadata,
+                                                                BigInteger mask, int instructionKey) {
+        return new InstructionBuilder()
+                .setInstruction(
+                        new WriteMetadataCaseBuilder().setWriteMetadata(
+                                new WriteMetadataBuilder().setMetadata(metadata).setMetadataMask(mask).build())
+                                .build()).setKey(new InstructionKey(instructionKey)).build();
+    }
 }
index 01d5adea23d1c9c593db7bef9553ed2a4391acfe..deb8c7573fd7b457b6f8177987179b839aff4774 100644 (file)
@@ -11,4 +11,58 @@ import java.math.BigInteger;
 
 public class MetaDataUtil {
     public static final BigInteger METADATA_MASK_VRFID = new BigInteger("00000000FFFFFFFF", 16);
+    public static final BigInteger METADATA_MASK_LPORT_TAG = new BigInteger("1FFFFF0000000000", 16);
+    public static final BigInteger METADATA_MASK_SERVICE = new BigInteger("000000FFFF000000", 16);
+    public static final BigInteger METADATA_MASK_SERVICE_INDEX = new BigInteger("E000000000000000", 16);
+    public static final BigInteger METADATA_MASK_LPORT_WRITE = new BigInteger("00FFFF0000000000", 16);
+    public static final BigInteger METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID = new BigInteger("08000000FFFFFF00", 16);
+    public static final BigInteger METADATA_MASK_LABEL_ITM = new BigInteger("40FFFFFF000000FF", 16);
+
+    public static BigInteger getMetaDataForLPortDispatcher(int lportTag, short serviceIndex) {
+        return getServiceIndexMetaData(serviceIndex).or(getLportTagMetaData(lportTag));
+    }
+
+    public static BigInteger getMetaDataForLPortDispatcher(int lportTag, short serviceIndex,
+                                                           BigInteger serviceMetaData) {
+        return getServiceIndexMetaData(serviceIndex).or(getLportTagMetaData(lportTag)).or(serviceMetaData);
+    }
+
+    public static BigInteger getServiceIndexMetaData(int serviceIndex) {
+        return new BigInteger("7", 16).and(BigInteger.valueOf(serviceIndex)).shiftLeft(61);
+    }
+
+    public static BigInteger getLportTagMetaData(int lportTag) {
+        return new BigInteger("1FFFFF", 16).and(BigInteger.valueOf(lportTag)).shiftLeft(40);
+    }
+
+    public static BigInteger getMetaDataMaskForLPortDispatcher() {
+        return METADATA_MASK_SERVICE_INDEX.or(METADATA_MASK_LPORT_TAG);
+    }
+
+    public static BigInteger getMetadataLPort(int lPortTag) {
+        return (new BigInteger("FFFF", 16).and(BigInteger.valueOf(lPortTag))).shiftLeft(40);
+    }
+
+    public static BigInteger getLportFromMetadata(BigInteger metadata) {
+        return (metadata.and(METADATA_MASK_LPORT_TAG)).shiftRight(40);
+    }
+
+    public static int getElanTagFromMetadata(BigInteger metadata) {
+        return (((metadata.and(MetaDataUtil.METADATA_MASK_SERVICE)).
+                shiftRight(24))).intValue();
+    }
+
+    public static BigInteger getMetaDataMaskForLPortDispatcher(BigInteger metadataMaskForServiceIndex,
+                                                               BigInteger metadataMaskForLPortTag, BigInteger metadataMaskForService) {
+        return metadataMaskForServiceIndex.or(metadataMaskForLPortTag).or(metadataMaskForService);
+    }
+
+    /**
+     * For the tunnel id with VNI and valid-vni-flag set, the most significant byte
+     * should have 08. So, shifting 08 to 7 bytes (56 bits) and the result is OR-ed with
+     * VNI being shifted to 1 byte.
+     */
+    public static BigInteger getTunnelIdWithValidVniBitAndVniSet(int vni) {
+        return BigInteger.valueOf(0X08).shiftLeft(56).or(BigInteger.valueOf(vni).shiftLeft(8));
+    }
 }
index ec09bbdd3a44c8af3eb464322d411e92cc7f8621..a86ad65110f507fe1eaf7f2a7e72d3e32155b3c1 100644 (file)
@@ -9,14 +9,22 @@ package org.opendaylight.vpnservice.mdsalutil.interfaces;
 
 import java.math.BigInteger;
 import java.util.List;
+
+import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
 import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
 import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 
 public interface IMdsalApiManager {
 
     public void installFlow(FlowEntity flowEntity);
 
+    public CheckedFuture<Void,TransactionCommitFailedException> installFlow(BigInteger dpId, Flow flowEntity);
+
+    public CheckedFuture<Void,TransactionCommitFailedException> removeFlow(BigInteger dpId, FlowEntity flowEntity);
+
     public void removeFlow(FlowEntity flowEntity);
 
     public void installGroup(GroupEntity groupEntity);
index 5ca603cab20c0536699c4986291dc60a3b3bb7c0..05accb360841696586d5ffb090c1a0c93ce768db 100644 (file)
@@ -128,6 +128,18 @@ public class MDSALManager implements AutoCloseable {
         }
     }
 
+    public CheckedFuture<Void,TransactionCommitFailedException> installFlow(BigInteger dpId, Flow flow) {
+        FlowKey flowKey = new FlowKey( new FlowId(flow.getId()) );
+        Node nodeDpn = buildDpnNode(dpId);
+        InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class)
+                .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
+                .child(Table.class, new TableKey(flow.getTableId())).child(Flow.class,flowKey).build();
+
+        WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction();
+        modification.put(LogicalDatastoreType.CONFIGURATION, flowInstanceId, flow, true);
+        return modification.submit();
+    }
+
     public void installGroup(GroupEntity groupEntity) {
         try {
             Group group = groupEntity.getGroupBuilder().build();
@@ -181,7 +193,7 @@ public class MDSALManager implements AutoCloseable {
 
 
                 WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction();
-                modification.delete(LogicalDatastoreType.CONFIGURATION,flowInstanceId );
+                modification.delete(LogicalDatastoreType.CONFIGURATION,flowInstanceId);
 
                 CheckedFuture<Void,TransactionCommitFailedException> submitFuture  = modification.submit();
 
@@ -210,6 +222,18 @@ public class MDSALManager implements AutoCloseable {
         }
     }
 
+    public CheckedFuture<Void,TransactionCommitFailedException> removeFlowNew(FlowEntity flowEntity) {
+        s_logger.debug("Remove flow {}",flowEntity);
+        Node nodeDpn = buildDpnNode(flowEntity.getDpnId());
+        FlowKey flowKey = new FlowKey(new FlowId(flowEntity.getFlowId()));
+        InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class)
+                    .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
+                    .child(Table.class, new TableKey(flowEntity.getTableId())).child(Flow.class, flowKey).build();
+        WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction();
+        modification.delete(LogicalDatastoreType.CONFIGURATION,flowInstanceId );
+        return modification.submit();
+    }
+
     public void removeGroup(GroupEntity groupEntity) {
         try {
             Node nodeDpn = buildDpnNode(groupEntity.getDpnId());
index 398e16f6a8ba8b928dadfd4b463f6adeb465cc65..eca7a5cd3126252c350beded1e778510fccbdf91 100644 (file)
@@ -10,13 +10,17 @@ package org.opendaylight.vpnservice.mdsalutil.internal;
 import java.math.BigInteger;
 
 import java.util.List;
+
+import com.google.common.util.concurrent.CheckedFuture;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
 import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
 import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -55,6 +59,16 @@ public class MDSALUtilProvider implements BindingAwareConsumer, IMdsalApiManager
           mdSalMgr.installFlow(flowEntity);
     }
 
+    @Override
+    public CheckedFuture<Void, TransactionCommitFailedException> installFlow(BigInteger dpId, Flow flowEntity) {
+        return mdSalMgr.installFlow(dpId, flowEntity);
+    }
+
+    @Override
+    public CheckedFuture<Void, TransactionCommitFailedException> removeFlow(BigInteger dpId, FlowEntity flowEntity) {
+        return mdSalMgr.removeFlowNew(flowEntity);
+    }
+
     @Override
     public void removeFlow(FlowEntity flowEntity) {
         mdSalMgr.removeFlow(flowEntity);
index 1543a81947a6de5e16e3f9a4d42d4a5d02fdbda4..c0a99838a00997d7e5171bde6cf1e46dbb5d33ca 100644 (file)
@@ -195,11 +195,11 @@ public class NexthopManager implements L3nexthopService, AutoCloseable {
         }
     }
 
-    public void createRemoteNextHop(String ifName, String ofPortId, String ipAddress) {
+    public void createRemoteNextHop(String ifName, String ipAddress) {
         String nhKey = new String("nexthop." + ifName + ipAddress);
         int groupId = createNextHopPointer(nhKey);
 
-        BigInteger dpnId = getDpnId(ofPortId);
+        BigInteger dpnId = interfaceManager.getDpnForInterface(ifName);
         TunnelNexthop nexthop = getTunnelNexthop(dpnId, ipAddress);
         if (nexthop == null) {
             List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
@@ -434,7 +434,7 @@ public class NexthopManager implements L3nexthopService, AutoCloseable {
         
     }
 
-    private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
+    <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
             InstanceIdentifier<T> path) {
 
         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
index 49a7bdbbf43fd81b6ad60680709680f374b2dcb9..d5ddfd21936a95b106f8b02182389043413353a6 100644 (file)
@@ -9,18 +9,20 @@ package org.opendaylight.vpnservice.nexthopmgr;
 
 
 import java.math.BigInteger;
+
+import com.google.common.base.Optional;
 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.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
 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;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
+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.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -60,7 +62,7 @@ public class OdlInterfaceChangeListener extends AbstractDataChangeListener<Inter
 
     private void registerListener(final DataBroker db) {
         try {
-            listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+            listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
                     getWildCardPath(), OdlInterfaceChangeListener.this, DataChangeScope.SUBTREE);
         } catch (final Exception e) {
             LOG.error("Nexthop Manager Interfaces DataChange listener registration fail!", e);
@@ -69,36 +71,59 @@ public class OdlInterfaceChangeListener extends AbstractDataChangeListener<Inter
     }
 
     @Override
-    protected void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
-        LOG.trace("Adding Interface : key: " + identifier + ", value=" + intrf );
-
-        if (intrf.getType().equals(L3tunnel.class)) {
-            IfL3tunnel intfData = intrf.getAugmentation(IfL3tunnel.class);
-            IpAddress gatewayIp = intfData.getGatewayIp();
-            IpAddress remoteIp = (gatewayIp == null) ? intfData.getRemoteIp() : gatewayIp;
-            NodeConnectorId ofPort = intrf.getAugmentation(BaseIds.class).getOfPortId();
-            nexthopManager.createRemoteNextHop(intrf.getName(), ofPort.toString(), remoteIp.getIpv4Address().getValue());
+    protected void add(InstanceIdentifier<Interface> identifier, Interface interfaceInfo) {
+        LOG.trace("Adding Interface : key: " + identifier + ", value=" + interfaceInfo );
+        // READ interface config information
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface intrf =
+                getInterfaceFromConfigDS(nexthopManager, new InterfaceKey(interfaceInfo.getName()));
+
+        if(intrf != null && intrf.getType().equals(Tunnel.class)){
+            IfTunnel intfData = intrf.getAugmentation(IfTunnel.class);
+            IpAddress gatewayIp = intfData.getTunnelGateway();
+            IpAddress remoteIp = (gatewayIp == null) ? intfData.getTunnelDestination() : gatewayIp;
+            nexthopManager.createRemoteNextHop(intrf.getName(), remoteIp.getIpv4Address().getValue());
         }
     }
 
-
     private InstanceIdentifier<Interface> getWildCardPath() {
-        return InstanceIdentifier.create(Interfaces.class).child(Interface.class);
+        return InstanceIdentifier.create(InterfacesState.class).child(Interface.class);
     }
 
     @Override
     protected void remove(InstanceIdentifier<Interface> identifier,
-            Interface intrf) {
-        LOG.trace("Removing interface : key: " + identifier + ", value=" + intrf );
-        if (intrf.getType().equals(L3tunnel.class)) {
+            Interface interfaceInfo) {
+        LOG.trace("Removing interface : key: " + identifier + ", value=" + interfaceInfo );
+        // READ interface config information
+        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface intrf =
+                getInterfaceFromConfigDS(nexthopManager, new InterfaceKey(interfaceInfo.getName()));
+
+        if (intrf != null && intrf.getType().equals(Tunnel.class)) {
             BigInteger dpnId = interfaceManager.getDpnForInterface(intrf);
-            IfL3tunnel intfData = intrf.getAugmentation(IfL3tunnel.class);
-            IpAddress gatewayIp = intfData.getGatewayIp();
-            IpAddress remoteIp = (gatewayIp == null) ? intfData.getRemoteIp() : gatewayIp;
+            IfTunnel intfData = intrf.getAugmentation(IfTunnel.class);
+            IpAddress gatewayIp = intfData.getTunnelGateway();
+            IpAddress remoteIp = (gatewayIp == null) ? intfData.getTunnelDestination() : gatewayIp;
             nexthopManager.removeRemoteNextHop(dpnId, intrf.getName(), remoteIp.getIpv4Address().getValue());
         }
     }
 
+    public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface getInterfaceFromConfigDS(NexthopManager nexthopManager, InterfaceKey interfaceKey) {
+        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> interfaceId =
+                getInterfaceIdentifier(interfaceKey);
+        Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> interfaceOptional =
+                nexthopManager.read(LogicalDatastoreType.CONFIGURATION, interfaceId);
+        if (!interfaceOptional.isPresent()) {
+            return null;
+        }
+
+        return interfaceOptional.get();
+    }
+
+    public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> getInterfaceIdentifier(InterfaceKey interfaceKey) {
+        InstanceIdentifier.InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> interfaceInstanceIdentifierBuilder =
+                InstanceIdentifier.builder(Interfaces.class).child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface.class, interfaceKey);
+        return interfaceInstanceIdentifierBuilder.build();
+    }
+
     @Override
     protected void update(InstanceIdentifier<Interface> identifier,
             Interface original, Interface update) {
index 1aead8bef2f483851edc05798871cf731b811f28..d6c481ffd382c98735706538b0bc94ae098219de 100644 (file)
@@ -5,25 +5,25 @@
  * 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;
 
-import java.math.BigInteger;
 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.interfacemgr.interfaces.IInterfaceManager;
 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
 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.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.math.BigInteger;
+
 public class InterfaceChangeListener extends AbstractDataChangeListener<Interface> implements AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(InterfaceChangeListener.class);
 
@@ -82,7 +82,7 @@ public class InterfaceChangeListener extends AbstractDataChangeListener<Interfac
     @Override
     protected void remove(InstanceIdentifier<Interface> identifier, Interface intrf) {
         LOG.trace("Remove interface event - key: {}, value: {}", identifier, intrf );
-        if (intrf.getType().equals(L3tunnel.class)) {
+        if (intrf.getType().equals(Tunnel.class)) {
           BigInteger dpnId =  interfaceManager.getDpnForInterface(intrf);
           String ifName = intrf.getName();
           LOG.debug("Removing tunnel interface associated with Interface {}", intrf.getName());
index 3585a6f17578884fc0007bb483abef5c30509eb7..b56c1d060e2000bcb66fde682cbe505165a161d6 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.vpnservice;
 
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
 
 import java.math.BigInteger;
 import java.util.Collection;
@@ -321,7 +321,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
 
         int priority = VpnConstants.DEFAULT_FLOW_PRIORITY;
         short gotoTableId = VpnConstants.FIB_TABLE;
-        if(intf.getType().equals(L3tunnel.class)){
+        if(intf.getType().equals(Tunnel.class)){
             gotoTableId = VpnConstants.LFIB_TABLE;
         }
 
@@ -607,7 +607,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
             LOG.trace("Operation Interface update event - Old: {}, New: {}", original, update);
             String interfaceName = update.getName();
             Interface intf = getInterface(interfaceName);
-            if (intf != null && intf.getType().equals(L3tunnel.class)) {
+            if (intf != null && intf.getType().equals(Tunnel.class)) {
                 BigInteger dpnId = interfaceManager.getDpnForInterface(interfaceName);
                 if(update.getOperStatus().equals(OperStatus.Up)) {
                     //Create ingress to LFIB
@@ -639,7 +639,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
             LOG.trace("Operational Interface add event - {}", add);
             String interfaceName = add.getName();
             Interface intf = getInterface(interfaceName);
-            if (intf != null && intf.getType().equals(L3tunnel.class)) {
+            if (intf != null && intf.getType().equals(Tunnel.class)) {
                 BigInteger dpnId = interfaceManager.getDpnForInterface(interfaceName);
                 if(add.getOperStatus().equals(OperStatus.Up)) {
                     //Create ingress to LFIB