ELAN FT Support for BE 68/32568/8
authorepgoraj <p.govinda.rajulu@ericsson.com>
Thu, 14 Jan 2016 11:55:23 +0000 (17:25 +0530)
committerepgoraj <p.govinda.rajulu@ericsson.com>
Thu, 14 Jan 2016 14:27:44 +0000 (19:57 +0530)
Change-Id: Iedbdea5f47c2bbe706acbed80cd89eac6d3c0e6a
Signed-off-by: epgoraj <p.govinda.rajulu@ericsson.com>
65 files changed:
elanmanager/elanmanager-api/pom.xml [new file with mode: 0644]
elanmanager/elanmanager-api/src/main/java/org/opendaylight/elanmanager/api/IElanService.java [new file with mode: 0644]
elanmanager/elanmanager-api/src/main/java/org/opendaylight/elanmanager/exceptions/MacNotFoundException.java [new file with mode: 0644]
elanmanager/elanmanager-api/src/main/yang/elan-statistics.yang [new file with mode: 0644]
elanmanager/elanmanager-api/src/main/yang/elan.yang [new file with mode: 0644]
elanmanager/elanmanager-api/src/main/yang/elanmanager-api.yang [new file with mode: 0644]
elanmanager/elanmanager-impl/pom.xml [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/config/default-config.xml [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanAdd.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanDelete.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanGet.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceAdd.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceDelete.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceGet.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceUpdate.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanMacTableFlush.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanMacTableGet.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanUpdate.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/StaticMacAdd.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/StaticMacDelete.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanForwardingEntriesHandler.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInstanceManager.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInterfaceManager.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanItmEventListener.java [new file with mode: 0755]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanNodeListener.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanPacketInHandler.java [new file with mode: 0755]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanServiceProvider.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanSmacFlowEventListener.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/statisitcs/ElanStatisticsImpl.java [new file with mode: 0755]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/utils/ElanCLIUtils.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/utils/ElanConstants.java [new file with mode: 0755]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/utils/ElanUtils.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/elanservice/impl/rev150216/ElanServiceImplModule.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/elanservice/impl/rev150216/ElanServiceImplModuleFactory.java [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml [new file with mode: 0644]
elanmanager/elanmanager-impl/src/main/yang/elanservice-impl.yang [new file with mode: 0644]
elanmanager/pom.xml [new file with mode: 0644]
features/pom.xml
features/src/main/features/features.xml
interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/exceptions/InterfaceAlreadyExistsException.java [new file with mode: 0644]
interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/exceptions/InterfaceNotFoundException.java [new file with mode: 0644]
interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/exceptions/InterfaceServiceNotFoundException.java [new file with mode: 0644]
interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/IfmConstants.java [new file with mode: 0644]
interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/InterfaceInfo.java [new file with mode: 0644]
interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/InterfaceServiceUtil.java [new file with mode: 0644]
interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/LogicalGroupInterfaceInfo.java [new file with mode: 0644]
interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/VlanInterfaceInfo.java [new file with mode: 0644]
interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/interfaces/IInterfaceManager.java
interfacemgr/interfacemgr-api/src/main/yang/interface-statistics.yang [new file with mode: 0644]
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/InterfacemgrProvider.java
itm/itm-api/src/main/java/org/opendaylight/vpnservice/itm/globals/ITMConstants.java
mdsalutil/mdsalutil-api/pom.xml
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/ActionType.java [changed mode: 0644->0755]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/FlowInfoKey.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/GroupInfoKey.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/MatchFieldType.java [changed mode: 0644->0755]
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
mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/NotifyTask.java [new file with mode: 0644]
nexthopmgr/nexthopmgr-impl/src/main/java/org/opendaylight/vpnservice/nexthopmgr/NexthopManager.java [changed mode: 0644->0755]
pom.xml

diff --git a/elanmanager/elanmanager-api/pom.xml b/elanmanager/elanmanager-api/pom.xml
new file mode 100644 (file)
index 0000000..af6914a
--- /dev/null
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <groupId>org.opendaylight.vpnservice</groupId>
+    <artifactId>config-parent</artifactId>
+    <version>0.2.0-SNAPSHOT</version>
+    <relativePath>../../commons/config-parent</relativePath>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.opendaylight.vpnservice</groupId>
+  <artifactId>elanmanager-api</artifactId>
+  <version>${vpnservices.version}</version>
+  <packaging>bundle</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.mdsal</groupId>
+      <artifactId>yang-binding</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.mdsal.model</groupId>
+      <artifactId>yang-ext</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.mdsal.model</groupId>
+      <artifactId>ietf-inet-types</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.mdsal.model</groupId>
+      <artifactId>ietf-yang-types</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.mdsal.model</groupId>
+      <artifactId>ietf-interfaces</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.mdsal.model</groupId>
+      <artifactId>iana-if-type-2014-05-08</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller.model</groupId>
+      <artifactId>model-inventory</artifactId>
+      <version>${controller.mdsal.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>interfacemgr-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>config-api</artifactId>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/elanmanager/elanmanager-api/src/main/java/org/opendaylight/elanmanager/api/IElanService.java b/elanmanager/elanmanager-api/src/main/java/org/opendaylight/elanmanager/api/IElanService.java
new file mode 100644 (file)
index 0000000..a6f51b4
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.elanmanager.api;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.elanmanager.exceptions.MacNotFoundException;
+
+import java.util.Collection;
+import java.util.List;
+
+public interface IElanService {
+    public boolean createElanInstance(String elanInstanceName, long MacTimeout, String description);
+    public void updateElanInstance(String elanInstanceName, long newMacTimout, String newDescription);
+    public boolean deleteElanInstance(String elanInstanceName);
+
+    public void addElanInterface(String elanInstanceName, String interfaceName, List<String> staticMacAddresses, String description);
+    public void updateElanInterface(String elanInstanceName, String interfaceName, List<String> updatedStaticMacAddresses, String newDescription);
+    public void deleteElanInterface(String elanInstanceName, String interfaceName);
+
+    public void addStaticMacAddress(String elanInstanceName, String interfaceName, String macAddress);
+    public void deleteStaticMacAddress(String elanInstanceName, String interfaceName, String macAddress) throws MacNotFoundException;
+    public Collection<MacEntry> getElanMacTable(String elanInstanceName);
+    public void flushMACTable(String elanInstanceName);
+    public ElanInstance getElanInstance(String elanInstanceName);
+    public List<ElanInstance> getElanInstances();
+    public List<String> getElanInterfaces(String elanInstanceName);
+
+}
diff --git a/elanmanager/elanmanager-api/src/main/java/org/opendaylight/elanmanager/exceptions/MacNotFoundException.java b/elanmanager/elanmanager-api/src/main/java/org/opendaylight/elanmanager/exceptions/MacNotFoundException.java
new file mode 100644 (file)
index 0000000..fc53471
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.elanmanager.exceptions;
+
+public class MacNotFoundException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    public MacNotFoundException() {
+
+    }
+
+    public MacNotFoundException(String message) {
+        super(message);
+    }
+}
diff --git a/elanmanager/elanmanager-api/src/main/yang/elan-statistics.yang b/elanmanager/elanmanager-api/src/main/yang/elan-statistics.yang
new file mode 100644 (file)
index 0000000..ff81823
--- /dev/null
@@ -0,0 +1,32 @@
+module elan-statistics {
+    namespace "urn:opendaylight:vpnservice:elan:statistics";
+    prefix elan-stats;
+
+    import ietf-interfaces {
+        prefix if;
+    }
+
+    import interface-statistics {
+        prefix if-stats;
+    }
+
+    revision "2015-08-24" {
+        description "YANG model describes rpc to retrieve the different
+               ELAN interface statistics ie. packet/byte counts";
+    }
+
+    rpc get-elan-interface-statistics {
+        input {
+            leaf interface-name {
+                type leafref {
+                    path "/if:interfaces/if:interface/if:name";
+                }
+            }
+        }
+        output {
+            container stat-result {
+                uses if-stats:stat-reply;
+            }
+        }
+    }
+}
diff --git a/elanmanager/elanmanager-api/src/main/yang/elan.yang b/elanmanager/elanmanager-api/src/main/yang/elan.yang
new file mode 100644 (file)
index 0000000..5b4b105
--- /dev/null
@@ -0,0 +1,240 @@
+module elan {
+
+    namespace "urn:opendaylight:vpnservice:elan";
+    prefix elan;
+
+    import ietf-interfaces {
+        prefix if;
+    }
+
+    import ietf-yang-types {
+        prefix yang;
+    }
+
+
+    revision "2015-06-02" {
+        description "elan module";
+    }
+
+  /*
+   * elan instance view.
+   */
+  container elan-instances {
+    description
+      "elan instances configuration parameters.
+       elan instances support both the VLAN and VNI based elans.";
+
+    list elan-instance {
+        max-elements "unbounded";
+        min-elements "0";
+        key "elan-instance-name";
+        description
+            "Specifies the name of the elan instance. It is a string of 1 to 31
+             case-sensitive characters.";
+        leaf elan-instance-name {
+            type string;
+            description
+              "The name of the elan-instance.";
+        }
+        leaf elan-tag {
+            type    uint32;
+            description "ELAN unique identifier which is unique across all the tenants. This will be created internally and if provided, the value will be discarded.";
+        }
+        leaf mac-timeout {
+            type uint32 {
+              range "0..65535";
+            }
+            description "MAC Table entry ageing time in seconds. A value of 0 will indicate that the MAC will never expire.";
+        }
+        leaf description {
+            description
+                "A textual description of elan instance, the elan instance description
+                helps users memorize the elan instance.";
+
+            type string {
+                length "1..254";
+            }
+        }
+    }
+  }
+
+  /*
+   * Binding Interfaces to a elan Instance.
+   */
+  container elan-interfaces {
+    description
+        "elan is enabled on interfaces.";
+
+    list elan-interface  {
+        key "name";
+        max-elements "unbounded";
+        min-elements "0";
+        leaf name {
+            type leafref {
+                path "/if:interfaces/if:interface/if:name";
+            }
+        }
+        leaf elan-instance-name {
+            mandatory true;
+            type string;
+        }
+        leaf-list static-mac-entries {
+            type yang:phys-address;
+        }
+        leaf description {
+            description
+                "A textual description of elan port, the elan port description
+                helps users memorize the elan port.";
+
+            type string {
+                 length "1..254";
+            }
+        }
+    }
+  }
+
+    /* operational data stores */
+  container elan-state {
+    config false;
+    description
+      "operational state of elans.";
+
+    list elan {
+        key "name";
+        description "The list of interfaces on the device.";
+        max-elements "unbounded";
+        min-elements "0";
+        leaf name {
+            type string;
+            description
+              "The name of the elan-instance.";
+        }
+        leaf-list elan-interfaces{
+            type leafref {
+                path "/if:interfaces/if:interface/if:name";
+            }
+            description "Interfaces connected to this elan instance.";
+        }
+    }
+  }
+
+  grouping forwarding-entries {
+    description "Details of the MAC entries";
+
+    list mac-entry {
+      key "mac-address";
+      description "Details of a MAC address";
+      max-elements "unbounded";
+      min-elements "0";
+
+      leaf mac-address {
+          type yang:phys-address;
+      }
+
+      leaf interface {
+         type leafref {
+             path "/if:interfaces/if:interface/if:name";
+         }
+      }
+
+      leaf controllerLearnedForwardingEntryTimestamp {
+        type uint64;
+      }
+
+      leaf isStaticAddress {
+        type boolean;
+      }
+    }
+  }
+
+  container elan-forwarding-tables {
+    config false;
+    description
+      "MAC tables for each elan instance";
+
+    list mac-table {
+        max-elements "unbounded";
+        min-elements "0";
+        key "elan-instance-name";
+        description
+            "Specifies the name of the elan instance. It is a string of 1 to 31
+             case-sensitive characters.";
+
+        leaf elan-instance-name {
+            type string;
+            description
+              "The name of the elan-instance.";
+        }
+
+        uses forwarding-entries;
+    }
+  }
+
+    container elan-interface-forwarding-entries {
+        config false;
+
+        list elan-interface-mac {
+            key "elan-interface";
+            description "All the MAC addresses learned on a particular elan interface";
+            max-elements "unbounded";
+            min-elements "0";
+            leaf elan-interface {
+                type leafref {
+                    path "/if:interfaces/if:interface/if:name";
+                }
+            }
+
+            uses forwarding-entries;
+        }
+    }
+
+    container elan-dpn-interfaces {
+        config false;
+
+        list elan-dpn-interfaces-list {
+            key "elan-instance-name";
+            description "All the dpns of this elan and all the ports of the corresponding dpns";
+            max-elements "unbounded";
+            min-elements "0";
+
+            leaf elan-instance-name {
+                type string;
+                description "The name of the elan-instance.";
+            }
+
+            list dpn-interfaces {
+                key "dp-id";
+                description "A DPN in which the elan spans across";
+                max-elements "unbounded";
+                min-elements "0";
+
+                leaf dp-id {
+                    type uint64;
+                }
+
+                leaf-list interfaces {
+                    type leafref {
+                        path "/if:interfaces/if:interface/if:name";
+                    }
+                }
+            }
+        }
+    }
+
+    container elan-tag-name-map {
+        config false;
+
+        list elan-tag-name {
+            key elan-tag;
+            leaf elan-tag {
+                type uint32;
+            }
+
+            leaf name {
+                type string;
+                description
+                "The name of the elan-instance.";
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/elanmanager/elanmanager-api/src/main/yang/elanmanager-api.yang b/elanmanager/elanmanager-api/src/main/yang/elanmanager-api.yang
new file mode 100644 (file)
index 0000000..e0508ba
--- /dev/null
@@ -0,0 +1,20 @@
+module elanmanager-api {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:elanmanager:api";
+    prefix "elanmanager-api";
+
+    import config { prefix config; revision-date 2013-04-05; }
+
+    description
+        "Service definition for elanmanager project";
+
+    revision "2015-07-07" {
+        description
+            "Initial revision";
+    }
+
+    identity elanmanager-api {
+        base "config:service-type";
+        config:java-class "org.opendaylight.elanmanager.api.IElanService";
+    }
+}
\ No newline at end of file
diff --git a/elanmanager/elanmanager-impl/pom.xml b/elanmanager/elanmanager-impl/pom.xml
new file mode 100644 (file)
index 0000000..3939c93
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: --><!--
+Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <parent>
+    <groupId>org.opendaylight.vpnservice</groupId>
+    <artifactId>config-parent</artifactId>
+    <version>0.2.0-SNAPSHOT</version>
+    <relativePath>../../commons/config-parent</relativePath>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.opendaylight.vpnservice</groupId>
+  <artifactId>elanmanager-impl</artifactId>
+  <version>${vpnservices.version}</version>
+  <packaging>bundle</packaging>
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>elanmanager-api</artifactId>
+      <version>${vpnservices.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>mdsalutil-api</artifactId>
+      <version>${vpnservices.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>interfacemgr-api</artifactId>
+      <version>${vpnservices.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.vpnservice</groupId>
+      <artifactId>idmanager-api</artifactId>
+      <version>${vpnservices.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.vpnservice</groupId>
+      <artifactId>itm-api</artifactId>
+      <version>${vpnservices.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-broker-impl</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.karaf.shell</groupId>
+      <artifactId>org.apache.karaf.shell.console</artifactId>
+      <version>3.0.3</version>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/elanmanager/elanmanager-impl/src/main/config/default-config.xml b/elanmanager/elanmanager-impl/src/main/config/default-config.xml
new file mode 100644 (file)
index 0000000..f4f4991
--- /dev/null
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<snapshot>
+    <required-capabilities>
+        <capability>urn:opendaylight:params:xml:ns:yang:elanservice:impl?module=elanservice-impl&amp;revision=2015-02-16</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:mdsalutil:api?module=odl-mdsalutil&amp;revision=2015-04-10</capability>
+        <capability>urn:opendaylight:vpnservice:itm?module=itm&amp;revision=2015-07-01</capability>
+        <capability>urn:opendaylight:vpnservice:interfacemgr?module=odl-interface&amp;revision=2015-03-31</capability>
+    </required-capabilities>
+    <configuration>
+
+        <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:elanservice:impl">prefix:elanservice-impl</type>
+                    <name>elanservice-default</name>
+                    <broker>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
+                        <name>binding-osgi-broker</name>
+                    </broker>
+                    <rpcregistry>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+                        <name>binding-rpc-broker</name>
+                    </rpcregistry>
+                    <mdsalutil>
+                        <type xmlns:mdsalutil="urn:opendaylight:params:xml:ns:yang:mdsalutil:api">mdsalutil:odl-mdsalutil</type>
+                        <name>mdsalutil-service</name>
+                    </mdsalutil>
+                    <odlinterface>
+                        <type xmlns:odlif="urn:opendaylight:vpnservice:interfacemgr">odlif:odl-interface</type>
+                        <name>interfacemgr-service</name>
+                    </odlinterface>
+                    <itmmanager>
+                        <type xmlns:itm="urn:opendaylight:vpnservice:itm">itm:itm</type>
+                        <name>itm</name>
+                    </itmmanager>
+                    <notification-service>
+                        <type xmlns:bindingimpl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">bindingimpl:binding-new-notification-service</type>
+                        <name>binding-notification-adapter</name>
+                    </notification-service>
+                </module>
+            </modules>
+            <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <service>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:elanmanager:api">prefix:elanmanager-api</type>
+                    <instance>
+                        <name>elanmanager</name>
+                        <provider>/modules/module[type='elanservice-impl'][name='elanservice-default']</provider>
+                    </instance>
+                </service>
+            </services>
+        </data>
+    </configuration>
+</snapshot>
\ No newline at end of file
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanAdd.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanAdd.java
new file mode 100644 (file)
index 0000000..440710e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.elanmanager.api.IElanService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(scope = "elan", name = "add", description = "adding Elan Instance")
+public class ElanAdd extends OsgiCommandSupport {
+
+    @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+    private String elanName;
+    @Argument(index = 1, name = "macTimeOut", description = "MAC Time-Out", required = false, multiValued = false)
+    private long macTimeOut = 30;
+    @Argument(index = 2, name = "elanDescr", description = "ELAN-Description", required = false, multiValued = false)
+    private String elanDescr;
+    private static final Logger logger = LoggerFactory.getLogger(ElanAdd.class);
+    private IElanService elanProvider;
+    public static int MAX_LENGTH = 31;
+
+    public void setElanProvider(IElanService elanServiceProvider) {
+        this.elanProvider = elanServiceProvider;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            logger.debug("Executing create ElanInstance command" + "\t" + elanName + "\t" + macTimeOut + "\t" + elanDescr + "\t");
+            if(elanName.length()<= MAX_LENGTH) {
+                boolean isSuccess = elanProvider.createElanInstance(elanName, macTimeOut, elanDescr);
+                if (isSuccess) {
+                    System.out.println("Elan Instance is created successfully");
+                }
+            } else {
+                System.out.println("Failed to create Elan Instance, max length is allowed 1 .. 31");
+            }
+        } catch (Exception e) {
+            logger.error("Elan Instance failed to create {}", e);
+            e.printStackTrace();
+        }
+        return null;
+    }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanDelete.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanDelete.java
new file mode 100644 (file)
index 0000000..46be93e
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.elanmanager.api.IElanService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(scope = "elan", name = "delete", description = "Deleting the Elan Instance")
+public class ElanDelete extends OsgiCommandSupport {
+
+    @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+    private String elanName;
+
+    private static final Logger logger = LoggerFactory.getLogger(ElanDelete.class);
+    private IElanService elanProvider;
+
+    public void setElanProvider(IElanService elanServiceProvider) {
+        this.elanProvider = elanServiceProvider;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            logger.debug("Executing the Deletion of ElanInstance command" + "\t" + elanName + "\t");
+           boolean isSuccess =  elanProvider.deleteElanInstance(elanName);
+            if(isSuccess) {
+                System.out.println("Elan Instance deleted successfully");
+            } else {
+                System.out.println("ELan Instance failed to delete");
+            }
+        } catch (Exception e) {
+            logger.error("Failed to delete Elan Instance {}", e);
+            e.printStackTrace();
+        }
+        return null;
+    }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanGet.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanGet.java
new file mode 100644 (file)
index 0000000..27a4103
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.elanmanager.api.IElanService;
+import org.opendaylight.vpnservice.elan.utils.ElanCLIUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+@Command(scope = "elan", name = "show", description = "display Elan Instance")
+public class ElanGet extends OsgiCommandSupport {
+
+    private static final Logger logger = LoggerFactory.getLogger(ElanGet.class);
+
+    @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = false, multiValued = false)
+    private String elanName;
+    private IElanService elanProvider;
+
+    public void setElanProvider(IElanService elanServiceProvider) {
+        this.elanProvider = elanServiceProvider;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            logger.debug("Executing Get ElanInstance command" + "\t" + elanName +  "\t");
+            if(elanName != null) {
+                ElanInstance elanInstance = elanProvider.getElanInstance(elanName);
+                if (elanInstance == null) {
+                    System.out.println("No Elan Instance present with name:" + elanName);
+                } else {
+                    System.out.println(getElanHeaderOutput());
+                    System.out.println(String.format(ElanCLIUtils.ELAN_CLI_FORMAT, elanInstance.getElanInstanceName(), elanInstance.getMacTimeout(), elanInstance.getElanTag(), elanInstance.getDescription()));
+                }
+
+            } else {
+               List<ElanInstance> elanInstanceList = elanProvider.getElanInstances();
+                if(elanInstanceList != null && !elanInstanceList.isEmpty()) {
+                    System.out.println(getElanHeaderOutput());
+                    for(ElanInstance elanInstance : elanInstanceList) {
+                        System.out.println(String.format(ElanCLIUtils.ELAN_CLI_FORMAT, elanInstance.getElanInstanceName(), elanInstance.getMacTimeout(), elanInstance.getElanTag(), elanInstance.getDescription()));
+                    }
+                } else {
+                    System.out.println("No Elan Instances are present");
+                }
+
+            }
+        } catch (Exception e) {
+            logger.error("Elan Instance failed to get {}", e);
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private Object getElanHeaderOutput() {
+        StringBuilder headerBuilder = new StringBuilder();
+        headerBuilder.append(String.format(ElanCLIUtils.ELAN_CLI_FORMAT, "Elan Instance", "Mac-TimeOut", "Tag"));
+        headerBuilder.append('\n');
+        headerBuilder.append(ElanCLIUtils.HEADER_UNDERLINE);
+        return headerBuilder.toString();
+    }
+}
+
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceAdd.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceAdd.java
new file mode 100644 (file)
index 0000000..ff1ad19
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.elanmanager.api.IElanService;
+
+@Command(scope = "elanInterface", name = "add", description = "adding Elan Interface")
+public class ElanInterfaceAdd extends OsgiCommandSupport {
+
+    @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+    private String elanName;
+    @Argument(index = 1, name = "interfaceName", description = "InterfaceName", required = true, multiValued = false)
+    private String interfaceName;
+    @Argument(index = 2, name = "staticMacAddresses", description = "StaticMacAddresses", required = false, multiValued = true)
+    private List<String> staticMacAddresses;
+    @Argument(index = 3, name = "elanInterfaceDescr", description = "ELAN Interface-Description", required = false, multiValued = false)
+    private String elanInterfaceDescr;
+    private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceAdd.class);
+    private IElanService elanProvider;
+
+    public void setElanProvider(IElanService elanServiceProvider) {
+        this.elanProvider = elanServiceProvider;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            logger.debug("Executing create ElanInterface command" + "\t" + elanName + "\t" + interfaceName + "\t" + staticMacAddresses + "\t" +
+            elanInterfaceDescr + "\t");
+            elanProvider.addElanInterface(elanName, interfaceName, staticMacAddresses, elanInterfaceDescr);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceDelete.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceDelete.java
new file mode 100644 (file)
index 0000000..6a3f93f
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.elanmanager.api.IElanService;
+
+@Command(scope = "elanInterface", name = "delete", description = "deleting Elan Interface")
+public class ElanInterfaceDelete  extends OsgiCommandSupport {
+
+    @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+    private String elanName;
+    @Argument(index = 1, name = "interfaceName", description = "InterfaceName", required = true, multiValued = false)
+    private String interfaceName;
+    private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceDelete.class);
+    private IElanService elanProvider;
+
+    public void setElanProvider(IElanService elanServiceProvider) {
+        this.elanProvider = elanServiceProvider;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            logger.debug("Deleting ElanInterface command" + "\t" + elanName + "\t" + interfaceName + "\t");
+            elanProvider.deleteElanInterface(elanName, interfaceName);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceGet.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceGet.java
new file mode 100644 (file)
index 0000000..a07f3de
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.elanmanager.api.IElanService;
+import org.opendaylight.vpnservice.elan.utils.ElanCLIUtils;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+@Command(scope = "elanInterface", name = "show", description = "display Elan Interfaces for the ElanInstance")
+public class ElanInterfaceGet extends OsgiCommandSupport {
+
+    private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceGet.class);
+
+    @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = false, multiValued = false)
+    private String elanName;
+    private IInterfaceManager interfaceManager;
+    public static int MAX_LENGTH = 31;
+    private IElanService elanProvider;
+    public static boolean isDisplay = true;
+
+    public void setElanProvider(IElanService elanServiceProvider) {
+        this.elanProvider = elanServiceProvider;
+    }
+
+    public void setInterfaceManager(IInterfaceManager interfaceManager) {
+        this.interfaceManager = interfaceManager;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            logger.debug("Executing Get ElanInterface command for the corresponding Elan Instance" + "\t" + elanName +  "\t");
+            if(elanName != null) {
+                ElanInstance elanInstance = elanProvider.getElanInstance(elanName);
+                List<String> elanInterfaces = elanProvider.getElanInterfaces(elanName);
+                if (elanInterfaces == null) {
+                    System.out.println("No Elan Interfaces present for ELan Instance:" + elanName);
+                    return null;
+                }
+                System.out.println(getElanInterfaceHeaderOutput());
+                displayInterfaces(elanInstance, elanInterfaces);
+
+            } else {
+                List<ElanInstance> elanInstances = elanProvider.getElanInstances();
+                if(!elanInstances.isEmpty()) {
+                    System.out.println(getElanInterfaceHeaderOutput());
+                    for(ElanInstance elanInstance : elanInstances) {
+                        List<String> elanInterfaces = elanProvider.getElanInterfaces(elanInstance.getElanInstanceName());
+                        displayInterfaces(elanInstance, elanInterfaces);
+                        System.out.println("\n");
+                    }
+                }
+
+            }
+        } catch (Exception e) {
+            logger.error("Elan Instance failed to get {}", e);
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private Object getElanInterfaceHeaderOutput() {
+        StringBuilder headerBuilder = new StringBuilder();
+        headerBuilder.append(String.format(ElanCLIUtils.ELAN_INTERFACE_CLI_FORMAT, "ElanInstance/Tag", "ElanInterface/Tag", "OpState" , "AdminState"));
+        headerBuilder.append('\n');
+        headerBuilder.append(ElanCLIUtils.HEADER_UNDERLINE);
+        return headerBuilder.toString();
+    }
+
+    private void displayInterfaces(ElanInstance elanInstance, List<String> interfaceList) {
+        if(!interfaceList.isEmpty()) {
+            for (String elanInterface : interfaceList)
+            {
+                InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(elanInterface);
+                if (interfaceInfo != null) {
+                    System.out.println(String.format(ElanCLIUtils.ELAN_INTERFACE_CLI_FORMAT, elanInstance.getElanInstanceName()+"/"+elanInstance.getElanTag(), elanInterface+"/"+interfaceInfo.getInterfaceTag(), interfaceInfo.getOpState(), interfaceInfo.getAdminState()));
+                }
+            }
+        }
+    }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceUpdate.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanInterfaceUpdate.java
new file mode 100644 (file)
index 0000000..d4526fe
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.elanmanager.api.IElanService;
+
+@Command(scope = "elanInterface", name = "update", description = "updating Elan Interface")
+public class ElanInterfaceUpdate extends OsgiCommandSupport {
+
+    @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+    private String elanName;
+    @Argument(index = 1, name = "interfaceName", description = "InterfaceName", required = true, multiValued = false)
+    private String interfaceName;
+    @Argument(index = 2, name = "staticMacAddresses", description = "StaticMacAddresses", required = false, multiValued = true)
+    private List<String> staticMacAddresses;
+    @Argument(index = 3, name = "elanInterfaceDescr", description = "ELAN Interface-Description", required = false, multiValued = false)
+    private String elanInterfaceDescr;
+    private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceUpdate.class);
+    private IElanService elanProvider;
+
+    public void setElanProvider(IElanService elanServiceProvider) {
+        this.elanProvider = elanServiceProvider;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            logger.debug("Executing updating ElanInterface command" + "\t" + elanName + "\t" + interfaceName + "\t" + staticMacAddresses + "\t" +
+                    elanInterfaceDescr + "\t");
+            elanProvider.updateElanInterface(elanName, interfaceName, staticMacAddresses, elanInterfaceDescr);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}
+
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanMacTableFlush.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanMacTableFlush.java
new file mode 100644 (file)
index 0000000..8448347
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import java.math.BigInteger;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.elanmanager.api.IElanService;
+
+@Command(scope = "elanmactable", name = "flush", description = "Flush the Mac Entries for Elan Instance")
+public class ElanMacTableFlush extends OsgiCommandSupport {
+
+    @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+    private String elanName;
+
+    private static final Logger logger = LoggerFactory.getLogger(ElanMacTableFlush.class);
+    private IElanService elanProvider;
+
+    public void setElanProvider(IElanService elanServiceProvider) {
+        this.elanProvider = elanServiceProvider;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            logger.debug("Executing create ElanInstance command" + "\t" + elanName + "\t");
+            elanProvider.flushMACTable(elanName);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanMacTableGet.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanMacTableGet.java
new file mode 100644 (file)
index 0000000..2b4a662
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.elanmanager.api.IElanService;
+import org.opendaylight.vpnservice.elan.utils.ElanCLIUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+
+@Command(scope = "elanmactable", name = "show", description = "get Elan Mac table")
+public class ElanMacTableGet extends OsgiCommandSupport {
+
+    private static final Logger logger = LoggerFactory.getLogger(ElanMacTableGet.class);
+
+    @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+    private String elanName;
+    private IElanService elanProvider;
+
+    public void setElanProvider(IElanService elanServiceProvider) {
+        this.elanProvider = elanServiceProvider;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            logger.debug("Executing updating ElanInterface command" + "\t");
+            Collection<MacEntry> macTables = elanProvider.getElanMacTable(elanName);
+            if(!macTables.isEmpty()) {
+                SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yy:HH:mm:SS");
+                System.out.println(getMacTableHeaderOutput());
+                System.out.println(elanName);
+                for(MacEntry mac : macTables) {
+                    boolean isStatic = mac.isIsStaticAddress();
+                    System.out.println(String.format(ElanCLIUtils.MAC_TABLE_CLI_FORMAT, "", mac.getInterface(), mac.getMacAddress().getValue(), ""));
+                    System.out.println(String.format(ElanCLIUtils.MAC_TABLE_CLI_FORMAT, "", isStatic, "", isStatic? "-" : formatter.format(new Date(mac.getControllerLearnedForwardingEntryTimestamp().longValue()))));
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private Object getMacTableHeaderOutput() {
+        StringBuilder headerBuilder = new StringBuilder();
+        headerBuilder.append(String.format(ElanCLIUtils.MAC_TABLE_CLI_FORMAT, "Elan Instance", "Interface Name", "MacAddress", ""));
+        headerBuilder.append('\n');
+        headerBuilder.append(String.format(ElanCLIUtils.MAC_TABLE_CLI_FORMAT, "", "Is Static?", "" , "TimeStamp"));
+        headerBuilder.append('\n');
+        headerBuilder.append(ElanCLIUtils.HEADER_UNDERLINE);
+        return headerBuilder.toString();
+    }
+}
+
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanUpdate.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/ElanUpdate.java
new file mode 100644 (file)
index 0000000..a40e667
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import java.math.BigInteger;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.elanmanager.api.IElanService;
+
+@Command(scope = "elan", name = "update", description = "updating the Elan Instance")
+public class ElanUpdate  extends OsgiCommandSupport {
+
+    @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+    private String elanName;
+    @Argument(index = 1, name = "macTimeOut", description = "MAC Time-Out", required = false, multiValued = false)
+    private long macTimeOut;
+    @Argument(index = 2, name = "elanDescr", description = "ELAN-Description", required = false, multiValued = false)
+    private String elanDescr;
+    private static final Logger logger = LoggerFactory.getLogger(ElanUpdate.class);
+    private IElanService elanProvider;
+
+    public void setElanProvider(IElanService elanServiceProvider) {
+        this.elanProvider = elanServiceProvider;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            logger.debug("Updating the ElanInstance command" + "\t" + elanName + "\t" + macTimeOut + "\t" + elanDescr + "\t");
+            elanProvider.updateElanInstance(elanName, macTimeOut, elanDescr);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/StaticMacAdd.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/StaticMacAdd.java
new file mode 100644 (file)
index 0000000..3eb4a2e
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.elanmanager.api.IElanService;
+
+@Command(scope = "staticMac", name = "add", description = "adding Static Mac Address")
+public class StaticMacAdd extends OsgiCommandSupport {
+
+    @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+    private String elanName;
+    @Argument(index = 1, name = "interfaceName", description = "InterfaceName", required = true, multiValued = false)
+    private String interfaceName;
+    @Argument(index = 2, name = "staticMacAddress", description = "StaticMacAddress", required = true, multiValued = false)
+    private String staticMacAddress;
+    private static final Logger logger = LoggerFactory.getLogger(StaticMacAdd.class);
+    private IElanService elanProvider;
+
+    public void setElanProvider(IElanService elanServiceProvider) {
+        this.elanProvider = elanServiceProvider;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            logger.debug("Executing create ElanInterface command" + "\t" + elanName + "\t" + interfaceName + "\t" + staticMacAddress + "\t");
+            elanProvider.addStaticMacAddress(elanName, interfaceName, staticMacAddress);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/StaticMacDelete.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/cli/StaticMacDelete.java
new file mode 100644 (file)
index 0000000..4789437
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.elanmanager.api.IElanService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Command(scope = "staticMac", name = "delete", description = "deleting Static Mac Address")
+public class StaticMacDelete  extends OsgiCommandSupport {
+
+    @Argument(index = 0, name = "elanName", description = "ELAN-NAME", required = true, multiValued = false)
+    private String elanName;
+    @Argument(index = 1, name = "interfaceName", description = "InterfaceName", required = true, multiValued = false)
+    private String interfaceName;
+    @Argument(index = 2, name = "staticMacAddress", description = "StaticMacAddress", required = true, multiValued = false)
+    private String staticMacAddress;
+    private static final Logger logger = LoggerFactory.getLogger(StaticMacDelete.class);
+    private IElanService elanProvider;
+
+    public void setElanProvider(IElanService elanServiceProvider) {
+        this.elanProvider = elanServiceProvider;
+    }
+
+    @Override
+    protected Object doExecute() {
+        try {
+            logger.debug("Executing create ElanInterface command" + "\t" + elanName + "\t" + interfaceName + "\t" + staticMacAddress + "\t");
+            elanProvider.deleteStaticMacAddress(elanName, interfaceName, staticMacAddress);
+        } catch (Exception e) {
+
+            e.printStackTrace();
+        }
+        return null;
+    }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanForwardingEntriesHandler.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanForwardingEntriesHandler.java
new file mode 100644 (file)
index 0000000..4acb68d
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+
+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.LogicalDatastoreType;
+import org.opendaylight.vpnservice.elan.utils.ElanUtils;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+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.elan.rev150602.ElanInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryKey;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class ElanForwardingEntriesHandler extends AbstractDataChangeListener<ElanInterface> implements AutoCloseable {
+    private DataBroker broker;
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+
+    private IMdsalApiManager mdsalManager;
+
+    private IITMProvider itmManager;
+
+    private static final Logger logger = LoggerFactory.getLogger(ElanForwardingEntriesHandler.class);
+
+
+    public ElanForwardingEntriesHandler(DataBroker db, IMdsalApiManager mdsalManager){
+        super(ElanInterface.class);
+        this.broker = db;
+        this.mdsalManager = mdsalManager;
+    }
+
+    public void setIITMManager(IITMProvider itmManager) {
+        this.itmManager = itmManager;
+    }
+
+    private InstanceIdentifier<?> getWildCardPath() {
+        return InstanceIdentifier.create(ElanInterfaces.class).child(ElanInterface.class);
+    }
+
+    public void updateElanInterfaceForwardingTablesList(String elanInstanceName, String interfaceName, String existingInterfaceName, MacEntry mac) {
+        if(existingInterfaceName == interfaceName) {
+            logger.error(String.format("Static MAC address %s has already been added for the same ElanInstance %s on the same Logical Interface Port %s."
+                    + " No operation will be done.", mac.getMacAddress().toString(), elanInstanceName, interfaceName));
+        } else {
+            logger.warn(String.format("Static MAC address %s had already been added for ElanInstance %s on Logical Interface Port %s. "
+                    + "This would be considered as MAC movement scenario and old static mac will be removed and new static MAC will be added"
+                    + "for ElanInstance %s on Logical Interface Port %s", mac.getMacAddress().toString(), elanInstanceName, interfaceName, elanInstanceName, interfaceName));
+            //Update the  ElanInterface Forwarding Container & ElanForwarding Container
+            deleteElanInterfaceForwardingTablesList(existingInterfaceName, mac);
+            createElanInterfaceForwardingTablesList(interfaceName, mac);
+            updateElanForwardingTablesList(elanInstanceName, interfaceName, mac);
+        }
+
+    }
+
+    public void addElanInterfaceForwardingTableList(ElanInstance elanInstance, String interfaceName, PhysAddress physAddress) {
+        MacEntry macEntry = new MacEntryBuilder().setIsStaticAddress(true).setMacAddress(physAddress).setInterface(interfaceName).setKey(new MacEntryKey(physAddress)).build();
+        createElanForwardingTablesList(elanInstance.getElanInstanceName(), macEntry);
+        createElanInterfaceForwardingTablesList(interfaceName, macEntry);
+    }
+
+    public void deleteElanInterfaceForwardingTablesList(String interfaceName, MacEntry mac) {
+        InstanceIdentifier<MacEntry> existingMacEntryId = ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, mac.getMacAddress());
+        MacEntry existingInterfaceMacEntry = ElanUtils.getInterfaceMacEntriesOperationalDataPathFromId(existingMacEntryId);
+        if(existingInterfaceMacEntry != null) {
+            ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, existingMacEntryId);
+        }
+    }
+
+    public void createElanInterfaceForwardingTablesList(String interfaceName, MacEntry mac) {
+        InstanceIdentifier<MacEntry> existingMacEntryId = ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, mac.getMacAddress());
+        MacEntry existingInterfaceMacEntry = ElanUtils.getInterfaceMacEntriesOperationalDataPathFromId(existingMacEntryId);
+        if(existingInterfaceMacEntry == null) {
+            MacEntry macEntry = new MacEntryBuilder().setMacAddress(mac.getMacAddress()).setInterface(interfaceName).setIsStaticAddress(true).setKey(new MacEntryKey(mac.getMacAddress())).build();
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, existingMacEntryId, macEntry);
+
+        }
+    }
+
+    public void updateElanForwardingTablesList(String elanName, String interfaceName, MacEntry mac) {
+        InstanceIdentifier<MacEntry> macEntryId =  ElanUtils.getMacEntryOperationalDataPath(elanName, mac.getMacAddress());
+        MacEntry existingMacEntry = ElanUtils.getMacEntryFromElanMacId(macEntryId);
+        if(existingMacEntry != null) {
+            ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+            MacEntry newMacEntry = new MacEntryBuilder().setInterface(interfaceName).setIsStaticAddress(true).setMacAddress(mac.getMacAddress()).setKey(new MacEntryKey(mac.getMacAddress())).build();
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, macEntryId, newMacEntry);
+        }
+    }
+
+    private void createElanForwardingTablesList(String elanName, MacEntry macEntry) {
+        InstanceIdentifier<MacEntry> macEntryId = ElanUtils.getMacEntryOperationalDataPath(elanName, macEntry.getMacAddress());
+        Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+        if(!existingMacEntry.isPresent()) {
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, macEntryId, macEntry);
+        }
+    }
+
+    public void deleteElanInterfaceForwardingEntries(ElanInstance elanInfo, InterfaceInfo interfaceInfo, MacEntry macEntry) {
+        InstanceIdentifier<MacEntry> macEntryId = ElanUtils.getMacEntryOperationalDataPath(elanInfo.getElanInstanceName(), macEntry.getMacAddress());
+        ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+        ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
+    }
+
+    public void deleteElanInterfaceMacForwardingEntries(String interfaceName, PhysAddress physAddress) {
+        InstanceIdentifier<MacEntry> macEntryId = ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
+        ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<ElanInterface> identifier, ElanInterface del) {
+
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<ElanInterface> identifier, ElanInterface original, ElanInterface update) {
+
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<ElanInterface> identifier, ElanInterface add) {
+
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (final Exception e) {
+                logger.error("Error when cleaning up Elan DataChangeListener.", e);
+            }
+            listenerRegistration = null;
+        }
+    }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInstanceManager.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInstanceManager.java
new file mode 100644 (file)
index 0000000..d1aca50
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+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.mdsalutil.AbstractDataChangeListener;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.elan.utils.ElanUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanDpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInstances;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.Elan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+public class ElanInstanceManager extends AbstractDataChangeListener<ElanInstance> implements AutoCloseable {
+    private DataBroker broker;
+    private static ElanInstanceManager elanInstanceManager = new ElanInstanceManager();
+    private ListenerRegistration<DataChangeListener> elanInstanceListenerRegistration;
+    private IdManagerService idManager;
+    private ElanInterfaceManager elanInterfaceManager;
+
+    private static final Logger logger = LoggerFactory.getLogger(ElanInstanceManager.class);
+
+    private ElanInstanceManager() {
+        super(ElanInstance.class);
+
+    }
+
+    public static ElanInstanceManager getElanInstanceManager() {
+        return elanInstanceManager;
+    }
+
+    public void setIdManager(IdManagerService idManager) {
+        this.idManager = idManager;
+    }
+
+    public void setDataBroker(DataBroker broker) {
+        this.broker = broker;
+    }
+
+    public void setElanInterfaceManager(ElanInterfaceManager elanInterfaceManager) {
+        this.elanInterfaceManager = elanInterfaceManager;
+    }
+
+
+    public void registerListener() {
+        try {
+            elanInstanceListenerRegistration = broker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+                    getElanInstanceWildcardPath(), ElanInstanceManager.this, DataChangeScope.SUBTREE);
+        } catch (final Exception e) {
+            logger.error("ELAN Instance DataChange listener registration failed !", e);
+            throw new IllegalStateException("ELAN Instance registration Listener failed.", e);
+        }
+    }
+
+    private InstanceIdentifier<?> getElanInstanceWildcardPath() {
+        return InstanceIdentifier.create(ElanInstances.class).child(ElanInstance.class);
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (elanInstanceListenerRegistration != null) {
+            elanInstanceListenerRegistration.close();
+        }
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<ElanInstance> identifier, ElanInstance del) {
+        logger.trace("Remove ElanInstance - Key: {}, value: {}", identifier, del);
+        String elanName = del.getElanInstanceName();
+        //check the elan Instance present in the Operational DataStore
+        Elan existingElan = ElanUtils.getElanByName(elanName);
+        long elanTag = del.getElanTag();
+        //Cleaning up the existing Elan Instance
+        if(existingElan != null) {
+            List<String> elanInterfaces =  existingElan.getElanInterfaces();
+            if(elanInterfaces != null && !elanInterfaces.isEmpty()) {
+                for (String elanInterfaceName : elanInterfaces) {
+                    InstanceIdentifier<ElanInterface> elanInterfaceId = ElanUtils.getElanInterfaceConfigurationDataPathId(elanInterfaceName);
+                    elanInterfaceManager.removeElanInterface(del, elanInterfaceName);
+                    ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, elanInterfaceId);
+                }
+            }
+            ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
+            ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, getElanDpnOperationDataPath(elanName));
+            ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanTag));
+        }
+        // Release tag
+        ElanUtils.releaseId(idManager, ElanConstants.ELAN_ID_POOL_NAME, elanName);
+
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<ElanInstance> identifier, ElanInstance original, ElanInstance update) {
+        if (original.getElanTag() == update.getElanTag()) {
+            return;
+        } else if (update.getElanTag() == null) {
+            // update the elan-Instance with new properties
+            if(original.getMacTimeout() == update.getMacTimeout() && original.getDescription().equalsIgnoreCase(update.getDescription())) {
+               return;
+            }
+            ElanUtils.UpdateOperationalDataStore(broker, idManager, update);
+            return;
+        }
+        elanInterfaceManager.handleunprocessedElanInterfaces(update);
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<ElanInstance> identifier, ElanInstance elanInstanceAdded) {
+        Elan elanInfo = ElanUtils.getElanByName(elanInstanceAdded.getElanInstanceName());
+        if(elanInfo == null) {
+            ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstanceAdded);
+        }
+    }
+
+    public ElanInstance getElanInstanceByName(String elanInstanceName) {
+        InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
+        Optional<ElanInstance> elanInstance = ElanUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
+        if(elanInstance.isPresent()) {
+            return elanInstance.get();
+        }
+        return null;
+    }
+
+    public List<DpnInterfaces> getElanDPNByName(String elanInstanceName) {
+        InstanceIdentifier<ElanDpnInterfacesList> elanIdentifier = getElanDpnOperationDataPath(elanInstanceName);
+        Optional<ElanDpnInterfacesList> elanInstance = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanIdentifier);
+        if(elanInstance.isPresent()) {
+            ElanDpnInterfacesList elanDPNs =  elanInstance.get();
+            return elanDPNs.getDpnInterfaces();
+        }
+        return null;
+    }
+
+    private InstanceIdentifier<ElanDpnInterfacesList> getElanDpnOperationDataPath(String elanInstanceName) {
+        return InstanceIdentifier.builder(ElanDpnInterfaces.class).child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName)).build();
+    }
+
+    private InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
+        return InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
+    }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInterfaceManager.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanInterfaceManager.java
new file mode 100644 (file)
index 0000000..b933578
--- /dev/null
@@ -0,0 +1,1133 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+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.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.elan.utils.ElanUtils;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceType;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.itm.globals.ITMConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
+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.flow.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder;
+
+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.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.vpnservice.mdsalutil.*;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+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.group.types.rev131018.GroupTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanDpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanForwardingTables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.Elan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+
+public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterface> implements AutoCloseable {
+
+    private static ElanInterfaceManager elanInterfaceManager = new ElanInterfaceManager();
+    private ListenerRegistration<DataChangeListener> elanInterfaceListenerRegistration;
+    private ListenerRegistration<DataChangeListener> itmInterfaceListenerRegistration;
+    private OdlInterfaceRpcService interfaceManagerRpcService;
+    private DataBroker broker;
+    private IMdsalApiManager mdsalManager;
+    private IInterfaceManager interfaceManager;
+    private IdManagerService idManager;
+    private IITMProvider itmManager;
+    private ElanForwardingEntriesHandler elanForwardingEntriesHandler;
+    private Map<String, ConcurrentLinkedQueue<ElanInterface>> unProcessedElanInterfaces =
+            new ConcurrentHashMap<String, ConcurrentLinkedQueue<ElanInterface>> ();
+
+    private static final Logger logger = LoggerFactory.getLogger(ElanInterfaceManager.class);
+
+    public ElanInterfaceManager() {
+        super(ElanInterface.class);
+    }
+
+    public static ElanInterfaceManager getElanInterfaceManager() {
+        return elanInterfaceManager;
+    }
+
+    public void setMdSalApiManager(IMdsalApiManager mdsalManager) {
+        this.mdsalManager = mdsalManager;
+    }
+
+    public void setInterfaceManagerRpcService(OdlInterfaceRpcService ifManager) {
+        this.interfaceManagerRpcService = ifManager;
+    }
+
+    public void setElanForwardingEntriesHandler(ElanForwardingEntriesHandler elanForwardingEntriesHandler) {
+        this.elanForwardingEntriesHandler = elanForwardingEntriesHandler;
+    }
+
+    public void setInterfaceManager(IInterfaceManager interfaceManager) {
+        this.interfaceManager = interfaceManager;
+    }
+
+    public void setDataBroker(DataBroker broker) {
+        this.broker = broker;
+    }
+
+    public void setIITMManager(IITMProvider itmManager) {
+        this.itmManager = itmManager;
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (elanInterfaceListenerRegistration != null) {
+            try {
+                elanInterfaceListenerRegistration.close();
+            } catch (final Exception e) {
+                logger.error("Error when cleaning up DataChangeListener.", e);
+            }
+            elanInterfaceListenerRegistration = null;
+        }
+    }
+
+    public void registerListener() {
+        try {
+            elanInterfaceListenerRegistration = broker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+                    getElanInterfaceWildcardPath(), ElanInterfaceManager.this, DataChangeScope.SUBTREE);
+        } catch (final Exception e) {
+            logger.error("ELAN Interface DataChange listener registration failed !", e);
+            throw new IllegalStateException("ELAN Interface registration Listener failed.", e);
+        }
+    }
+
+    private InstanceIdentifier<?> getElanInterfaceWildcardPath() {
+        return InstanceIdentifier.create(ElanInterfaces.class).child(ElanInterface.class);
+    }
+
+    public void setIdManager(IdManagerService idManager) {
+        this.idManager = idManager;
+    }
+
+    @Override
+    protected void remove(InstanceIdentifier<ElanInterface> identifier, ElanInterface del) {
+        String interfaceName =  del.getName();
+        ElanInstance elanInfo = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
+        removeElanInterface(elanInfo, interfaceName);
+    }
+
+    public void removeElanService(ElanInterface del, int vlanId) {
+        ElanInstance elanInstance = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
+        String interfaceName = del.getName();
+        InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(interfaceName, InterfaceType.VLAN_INTERFACE);
+        removeElanInterface(elanInstance, interfaceInfo);
+        unbindService(elanInstance, interfaceName, vlanId);
+    }
+
+    public void removeElanInterface(ElanInstance elanInfo, String interfaceName) {
+        String elanName = elanInfo.getElanInstanceName();
+        InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+        if (interfaceInfo == null) {
+            ElanInterfaceMac elanInterfaceMac =  ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
+            if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
+               List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
+                for(MacEntry macEntry : macEntries) {
+                    ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getMacEntryOperationalDataPath(elanName, macEntry.getMacAddress()));
+                }
+            }
+            ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName));
+            Elan elanState = ElanUtils.getElanByName(elanName);
+            List<String> elanInterfaces = elanState.getElanInterfaces();
+            elanInterfaces.remove(interfaceName);
+            if(elanInterfaces.isEmpty()) {
+                ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
+                ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
+                ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
+                ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanName));
+            } else {
+                Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
+                MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
+            }
+            return;
+        }
+        removeElanInterface(elanInfo, interfaceInfo);
+        unbindService(elanInfo, interfaceName);
+    }
+
+    private void removeElanInterface(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+
+        BigInteger dpId = interfaceInfo.getDpId();
+        String elanName = elanInfo.getElanInstanceName();
+        String interfaceName = interfaceInfo.getInterfaceName();
+        Elan elanState = ElanUtils.getElanByName(elanName);
+        logger.debug("Removing the Interface:{} from elan:{}", interfaceName, elanName);
+        InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
+        Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
+        if(existingElanInterface.isPresent()) {
+            List<MacEntry> macEntries = existingElanInterface.get().getMacEntry();
+            if(macEntries != null && !macEntries.isEmpty()) {
+                for (MacEntry macEntry : macEntries) {
+                    logger.debug("removing the  mac-entry:{} present on elanInterface:{}", macEntry.getMacAddress().getValue(), interfaceName);
+                    elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(elanInfo, interfaceInfo, macEntry);
+                }
+            }
+        }
+
+        /*
+         *This condition check is mainly to get DPN-ID in pre-provision deletion scenario after stopping CSS
+         */
+        if(dpId.equals(ElanConstants.INVALID_DPN)) {
+            ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
+            if(elanDpnInterfacesList != null && !elanDpnInterfacesList.getDpnInterfaces().isEmpty()) {
+                List<DpnInterfaces> dpnIfList = elanDpnInterfacesList.getDpnInterfaces();
+                for (DpnInterfaces dpnInterface : dpnIfList) {
+                    DpnInterfaces dpnIfLists = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpnInterface.getDpId());
+                    if (dpnIfLists.getInterfaces().contains(interfaceName)) {
+                        logger.debug("deleting the elanInterface from the ElanDpnInterface cache in pre-provision scenario of elan:{} dpn:{} interfaceName:{}", elanName, dpId, interfaceName);
+                        removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
+                        break;
+                    }
+                }
+            }
+        } else {
+            removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
+        }
+
+        ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
+        List<String> elanInterfaces = elanState.getElanInterfaces();
+        elanInterfaces.remove(interfaceName);
+        removeStaticELanFlows(elanInfo, interfaceInfo);
+        if(elanInterfaces.isEmpty()) {
+            ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
+            ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnOperationDataPath(elanName));
+            ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanName));
+            ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanInfo.getElanTag()));
+            //ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanName));
+        } else {
+            Elan updateElanState = new ElanBuilder().setElanInterfaces(elanInterfaces).setName(elanName).setKey(new ElanKey(elanName)).build();
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName), updateElanState);
+        }
+    }
+
+    private void removeElanDpnInterfaceFromOperationalDataStore(String elanName, BigInteger dpId, String interfaceName) {
+        DpnInterfaces dpnInterfaces =  ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
+        if(dpnInterfaces != null) {
+            List<String> interfaceLists = dpnInterfaces.getInterfaces();
+            interfaceLists.remove(interfaceName);
+            updateElanDpnInterfacesList(elanName, dpId, interfaceLists);
+        }
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<ElanInterface> identifier, ElanInterface original, ElanInterface update) {
+        // updating the static-Mac Entries for the existing elanInterface
+        String elanName = update.getElanInstanceName();
+        String interfaceName = update.getName();
+        InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+        List<PhysAddress> existingPhysAddress = original.getStaticMacEntries();
+        List<PhysAddress> updatedPhysAddress = update.getStaticMacEntries();
+        if(updatedPhysAddress != null && !updatedPhysAddress.isEmpty()) {
+            List<PhysAddress> existingClonedPhyAddress = new ArrayList<>();
+            if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
+                existingClonedPhyAddress.addAll(0, existingPhysAddress);
+                existingPhysAddress.removeAll(updatedPhysAddress);
+                updatedPhysAddress.removeAll(existingClonedPhyAddress);
+                // removing the PhyAddress which are not presented in the updated List
+                for(PhysAddress physAddress: existingPhysAddress) {
+                    removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
+                }
+            }
+            // Adding the new PhysAddress which are presented in the updated List
+            if(updatedPhysAddress.size() > 0) {
+                for(PhysAddress physAddress: updatedPhysAddress) {
+                    InstanceIdentifier<MacEntry> macId =  getMacEntryOperationalDataPath(elanName, physAddress);
+                    Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
+                    if(existingMacEntry.isPresent()) {
+                        elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
+                    } else {
+                        elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(ElanUtils.getElanInstanceByName(elanName), interfaceName, physAddress);
+                    }
+                }
+            }
+        } else if(existingPhysAddress != null && !existingPhysAddress.isEmpty()) {
+            for( PhysAddress physAddress : existingPhysAddress) {
+                removeInterfaceStaticMacEntires(elanName, interfaceName, physAddress);
+            }
+        }
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<ElanInterface> identifier, ElanInterface elanInterfaceAdded) {
+        String elanInstanceName = elanInterfaceAdded.getElanInstanceName();
+        String interfaceName = elanInterfaceAdded.getName();
+        InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+        ElanInstance elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
+
+        if (elanInstance == null) {
+            elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setDescription(elanInterfaceAdded.getDescription()).build();
+            //Add the ElanInstance in the Configuration data-store
+            ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstance);
+            elanInstance = ElanUtils.getElanInstanceByName(elanInstanceName);
+        }
+
+
+        Long elanTag = elanInstance.getElanTag();
+        // If elan tag is not updated, then put the elan interface into unprocessed entry map and entry. Let entries
+        // in this map get processed during ELAN update DCN.
+        if (elanTag == null) {
+            ConcurrentLinkedQueue<ElanInterface> elanInterfaces = unProcessedElanInterfaces.get(elanInstanceName);
+            if (elanInterfaces == null) {
+                elanInterfaces = new ConcurrentLinkedQueue<ElanInterface>();
+            }
+            elanInterfaces.add(elanInterfaceAdded);
+            unProcessedElanInterfaces.put(elanInstanceName, elanInterfaces);
+            return;
+        }
+        addElanInterface(elanInterfaceAdded, interfaceInfo, elanInstance);
+    }
+
+    void handleunprocessedElanInterfaces(ElanInstance elanInstance) {
+        Queue<ElanInterface> elanInterfaces = unProcessedElanInterfaces.get(elanInstance.getElanInstanceName());
+        if (elanInterfaces == null || elanInterfaces.isEmpty()) {
+            return;
+        }
+        for (ElanInterface elanInterface: elanInterfaces) {
+            String interfaceName = elanInterface.getName();
+            InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+            addElanInterface(elanInterface, interfaceInfo, elanInstance);
+        }
+    }
+
+    void addElanInterface(ElanInterface elanInterface, InterfaceInfo interfaceInfo, ElanInstance elanInstance) {
+        String interfaceName = elanInterface.getName();
+        String elanInstanceName = elanInterface.getElanInstanceName();
+        List<PhysAddress> staticMacAddresses = elanInterface.getStaticMacEntries();
+        Elan elanInfo = ElanUtils.getElanByName(elanInstanceName);
+        BigInteger dpId = null;
+        if(elanInfo == null) {
+            ElanUtils.UpdateOperationalDataStore(broker, idManager, elanInstance);
+        }
+        if(interfaceInfo != null) {
+            dpId = interfaceInfo.getDpId();
+        }
+        if(dpId != null && !dpId.equals(ElanConstants.INVALID_DPN)) {
+            InstanceIdentifier<DpnInterfaces> elanDpnInterfaces = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
+            Optional<DpnInterfaces> existingElanDpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInterfaces);
+            if (!existingElanDpnInterfaces.isPresent()) {
+                createElanInterfacesList(elanInstanceName, interfaceName, dpId);
+            } else {
+                List<String> elanInterfaces = existingElanDpnInterfaces.get().getInterfaces();
+                elanInterfaces.add(interfaceName);
+                updateElanDpnInterfacesList(elanInstanceName, dpId, elanInterfaces);
+            }
+        }
+
+        // add code to install Local/Remote BC group, unknow DMAC entry, terminating service table flow entry
+        // call bindservice of interfacemanager to create ingress table flow enty.
+        //Add interface to the ElanInterfaceForwardingEntires Container
+        createElanInterfaceTablesList(interfaceName);
+        createElanStateList(elanInstanceName, interfaceName);
+        if(interfaceInfo != null) {
+            installFlowsAndGroups(elanInstance, interfaceInfo);
+        }
+        // add the static mac addresses
+        if(staticMacAddresses != null) {
+            for (PhysAddress physAddress : staticMacAddresses) {
+                InstanceIdentifier<MacEntry> macId = getMacEntryOperationalDataPath(elanInstanceName, physAddress);
+                Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
+                if (existingMacEntry.isPresent()) {
+                    elanForwardingEntriesHandler.updateElanInterfaceForwardingTablesList(elanInstanceName, interfaceName, existingMacEntry.get().getInterface(), existingMacEntry.get());
+                } else {
+                    elanForwardingEntriesHandler.addElanInterfaceForwardingTableList(elanInstance, interfaceName, physAddress);
+                }
+                if(interfaceInfo != null && isOperational(interfaceInfo)) {
+                    logger.debug("Installing Static Mac-Entry on the Elan Interface:{} with MacAddress:{}", interfaceInfo, physAddress.getValue());
+                    ElanUtils.setupMacFlows(elanInstance, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, physAddress.getValue());
+                }
+            }
+        }
+    }
+
+    private Map<BigInteger, List<String>> readFePortsDbForElan(String elanName) {
+        ElanDpnInterfacesList elanDpnInterfacesList = ElanUtils.getElanDpnInterfacesList(elanName);
+        HashMap<BigInteger, List<String>> fePortsDb = Maps.newHashMap();
+        if (elanDpnInterfacesList == null) {
+            return fePortsDb;
+        }
+        List<DpnInterfaces> dpnInterfaces = elanDpnInterfacesList.getDpnInterfaces();
+        if (dpnInterfaces == null) {
+            return fePortsDb;
+        }
+        for (DpnInterfaces dpnInterface : dpnInterfaces) {
+            fePortsDb.put(dpnInterface.getDpId(), dpnInterface.getInterfaces());
+        }
+        return fePortsDb;
+    }
+
+    protected void removeInterfaceStaticMacEntires(String elanInstanceName, String interfaceName, PhysAddress physAddress) {
+        InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+        InstanceIdentifier<MacEntry> macId =  getMacEntryOperationalDataPath(elanInstanceName, physAddress);
+        Optional<MacEntry> existingMacEntry = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, macId);
+
+        if(!existingMacEntry.isPresent()) {
+            return;
+        }
+
+        MacEntry macEntry = new MacEntryBuilder().setMacAddress(physAddress).setInterface(interfaceName).setKey(new MacEntryKey(physAddress)).build();
+        elanForwardingEntriesHandler.deleteElanInterfaceForwardingEntries(ElanUtils.getElanInstanceByName(elanInstanceName), interfaceInfo, macEntry);
+        elanForwardingEntriesHandler.deleteElanInterfaceMacForwardingEntries(interfaceName, physAddress);
+    }
+
+
+    private InstanceIdentifier<MacEntry> getMacEntryOperationalDataPath(String elanName, PhysAddress physAddress) {
+        return InstanceIdentifier.builder(ElanForwardingTables.class).child(MacTable.class,
+                new MacTableKey(elanName)).child(MacEntry.class, new MacEntryKey(physAddress)).build();
+    }
+
+    public void installFlowsAndGroups(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
+        if (isOperational(interfaceInfo)) {
+
+            // LocalBroadcast Group creation with elan-Interfaces
+            setupLocalBroadcastGroups(elanInfo, interfaceInfo);
+
+            //Remote-broadcast group & Terminating Service , UnknownDMAC Table.
+            //setupRemoteBroadcastGroups(elanInfo, interfaceInfo);
+            setupTerminateServiceTable(elanInfo, interfaceInfo);
+            setupUnknownDMacTable(elanInfo, interfaceInfo);
+            setupFilterEqualsTable(elanInfo, interfaceInfo);
+            // bind the Elan service to the Interface
+            bindService(elanInfo, interfaceInfo.getInterfaceName());
+
+            //update the remote-DPNs remoteBC group entry with Tunnels
+            setRemoteBCGrouponOtherDpns(elanInfo, interfaceInfo);
+        }
+    }
+
+    public void setupFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        long elanTag = elanInfo.getElanTag();
+        long ifTag = interfaceInfo.getInterfaceTag();
+        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        MatchBuilder mb = new MatchBuilder();
+        addNxRegMatch(mb, RegMatch.of(NxmNxReg1.class, ifTag));
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
+                9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsReg1LPortTag(ifTag),
+                getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
+
+        mdsalManager.installFlow(flowEntity);
+
+        FlowEntity flowEntity1 = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
+                10, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsLPortTag(ifTag),
+                getInstructionsDrop());
+
+        mdsalManager.installFlow(flowEntity1);
+    }
+
+
+    protected List<ActionInfo> getEgressActionsForInterface(String ifName) {
+        List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
+        try {
+            Future<RpcResult<GetEgressActionsForInterfaceOutput>> result =
+                    interfaceManagerRpcService.getEgressActionsForInterface(
+                            new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName).build());
+            RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
+            System.out.println("Data is populated");
+            if(!rpcResult.isSuccessful()) {
+                logger.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName, rpcResult.getErrors());
+            } else {
+                List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions =
+                        rpcResult.getResult().getAction();
+                for (Action action : actions) {
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action.getAction();
+                    if (actionClass instanceof OutputActionCase) {
+                        System.out.println("Data ");
+                        listActionInfo.add(new ActionInfo(ActionType.output,
+                                new String[] {((OutputActionCase)actionClass).getOutputAction()
+                                        .getOutputNodeConnector().getValue()}));
+                    } else if (actionClass instanceof PushVlanActionCase) {
+                        listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
+                    } else if (actionClass instanceof SetFieldCase) {
+                        if (((SetFieldCase)actionClass).getSetField().getVlanMatch() != null) {
+                            int vlanVid = ((SetFieldCase)actionClass).getSetField().getVlanMatch().getVlanId().getVlanId().getValue();
+                            listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
+                                    new String[] { Long.toString(vlanVid) }));
+                        }
+                    }
+                }
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            logger.warn("Exception when egress actions for interface {}", ifName, e);
+        }
+        return listActionInfo;
+    }
+
+
+    private List<BucketInfo> getRemoteBCGroupBucketInfos(ElanInstance elanInfo,
+            InterfaceInfo interfaceInfo) {
+        BigInteger dpnId = interfaceInfo.getDpId();
+        int elanTag = elanInfo.getElanTag().intValue();
+        List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
+        ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
+        if(elanDpns != null) {
+            List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
+            for(DpnInterfaces dpnInterface : dpnInterfaceses) {
+               if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
+                   try {
+                       //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
+                       //List<ActionInfo> listActionInfo = itmManager.ITMIngressGetActions(dpnId, dpnInterface.getDpId(), (int) elanTag);
+                       //listBucketInfo.add(new BucketInfo(listActionInfo));
+                   } catch (Exception ex) {
+                       logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
+                   }
+               }
+            }
+        }
+        List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
+        listActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanInfo.getElanTag()))}));
+        listBucketInfo.add(new BucketInfo(listActionInfo));
+        return listBucketInfo;
+    }
+
+    public ActionInfo getReg1ActionInfo(int interfaceTag) {
+         return new ActionInfo(ActionType.set_field_reg, new String[] {String.valueOf(interfaceTag)});
+    }
+
+    private void setRemoteBCGrouponOtherDpns(ElanInstance elanInfo,
+                                                         InterfaceInfo interfaceInfo) {
+        BigInteger dpnId = interfaceInfo.getDpId();
+        int elanTag = elanInfo.getElanTag().intValue();
+        long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
+        ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
+        if(elanDpns != null) {
+            List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
+            for(DpnInterfaces dpnInterface : dpnInterfaceses) {
+              List<BucketInfo> remoteListBucketInfo = new ArrayList<BucketInfo>();
+                if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && !dpnInterface.getDpId().equals(dpnId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
+                    for(DpnInterfaces otherFes : dpnInterfaceses) {
+                        if (ElanUtils.isDpnPresent(otherFes.getDpId()) && otherFes.getDpId() != dpnInterface.getDpId()
+                                && otherFes.getInterfaces() != null && ! otherFes.getInterfaces().isEmpty()) {
+                            try {
+                                //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
+                                //List<ActionInfo> remoteListActionInfo = itmManager.ITMIngressGetActions(dpnInterface.getDpId(), otherFes.getDpId(), (int) elanTag);
+                                //remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
+                            } catch (Exception ex) {
+                                logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), otherFes.getDpId() );
+                                return;
+                            }
+                        }
+                    }
+                    List<ActionInfo> remoteListActionInfo = new ArrayList<ActionInfo>();
+                    remoteListActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanTag))}));
+                    remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
+                    GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnInterface.getDpId(), groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, remoteListBucketInfo);
+                    mdsalManager.installGroup(groupEntity);
+                }
+            }
+        }
+    }
+
+    private void updateRemoteBCGrouponDpnTunnelEvent(ElanInstance elanInfo,
+                                               InterfaceInfo interfaceInfo, BigInteger dstDpId) {
+        int elanTag = elanInfo.getElanTag().intValue();
+        long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
+        List<DpnInterfaces> elanDpns = ElanUtils.getInvolvedDpnsInElan(elanInfo.getElanInstanceName());
+        if(elanDpns != null) {
+            for(DpnInterfaces dpnInterface : elanDpns) {
+                List<BucketInfo> remoteListBucketInfo = new ArrayList<BucketInfo>();
+                if(ElanUtils.isDpnPresent(dstDpId) && dpnInterface.getDpId().equals(dstDpId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
+                    try {
+                        //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
+                        //List<ActionInfo> remoteListActionInfo = itmManager.ITMIngressGetActions(interfaceInfo.getDpId(), dstDpId, (int) elanTag);
+                        //remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
+                    } catch (Exception ex) {
+                        logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), dstDpId);
+                        return;
+                    }
+                    List<ActionInfo> remoteListActionInfo = new ArrayList<ActionInfo>();
+                    remoteListActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanTag))}));
+                    remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
+                    GroupEntity groupEntity = MDSALUtil.buildGroupEntity(interfaceInfo.getDpId(), groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, remoteListBucketInfo);
+                    mdsalManager.installGroup(groupEntity);
+                    break;
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Returns the bucket info with the given interface as the only bucket.
+     */
+    private List<BucketInfo> getLocalBCGroupBucketInfo(InterfaceInfo interfaceInfo) {
+        return Lists.newArrayList(new BucketInfo(getInterfacePortActionInfos(interfaceInfo)));
+    }
+
+    private List<MatchInfo> getMatchesForElanTag(Long elanTag) {
+        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        // Matching metadata
+        mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
+                ElanUtils.getElanMetadataLabel(elanTag),
+                MetaDataUtil.METADATA_MASK_SERVICE }));
+        return mkMatches;
+    }
+
+    private List<InstructionInfo> getInstructionsForOutGroup(
+            long groupId) {
+        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+        List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
+        actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(groupId)}));
+        mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+        return mkInstructions;
+    }
+
+    public void removeFlowsAndGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        removeStaticELanFlows(elanInfo, interfaceInfo);
+        unbindService(elanInfo, interfaceInfo.getInterfaceName());
+    }
+
+    public void installMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        String interfaceName = interfaceInfo.getInterfaceName();
+        BigInteger currentDpn = interfaceInfo.getDpId();
+        ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
+        if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
+            List<MacEntry> macEntries =  elanInterfaceMac.getMacEntry();
+            for(MacEntry macEntry : macEntries) {
+                PhysAddress physAddress = macEntry.getMacAddress();
+                ElanUtils.setupMacFlows(elanInfo, interfaceInfo, macEntry.isIsStaticAddress() ? ElanConstants.STATIC_MAC_TIMEOUT : elanInfo.getMacTimeout(), physAddress.getValue());
+            }
+            //Programming the remoteDMACFlows
+            ElanDpnInterfacesList elanDpnInterfacesList =  ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
+            List<DpnInterfaces> dpnInterfaceLists =  elanDpnInterfacesList.getDpnInterfaces();
+            for(DpnInterfaces dpnInterfaces : dpnInterfaceLists){
+                if(dpnInterfaces.getDpId().equals(interfaceInfo.getDpId())) {
+                    continue;
+                }
+                List<String> remoteElanInterfaces = dpnInterfaces.getInterfaces();
+                for(String remoteIf : remoteElanInterfaces) {
+                    ElanInterfaceMac elanIfMac = ElanUtils.getElanInterfaceMacByInterfaceName(remoteIf);
+                    InterfaceInfo remoteInterface = interfaceManager.getInterfaceInfo(remoteIf);
+                    if(elanIfMac == null) {
+                        continue;
+                    }
+                    List<MacEntry> remoteMacEntries = elanIfMac.getMacEntry();
+                    if(remoteMacEntries != null) {
+                        for (MacEntry macEntry : remoteMacEntries) {
+                            PhysAddress physAddress = macEntry.getMacAddress();
+                            ElanUtils.setupRemoteDmacFlow(currentDpn, remoteInterface.getDpId(), remoteInterface.getInterfaceTag(), elanInfo.getElanTag(), physAddress.getValue(), elanInfo.getElanInstanceName());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // Install DMAC entry on dst DPN
+    public void installDMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo, BigInteger dstDpId) {
+        String interfaceName = interfaceInfo.getInterfaceName();
+        ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
+        if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
+            List<MacEntry> macEntries =  elanInterfaceMac.getMacEntry();
+            for(MacEntry macEntry : macEntries) {
+                PhysAddress physAddress = macEntry.getMacAddress();
+                ElanUtils.setupDMacFlowonRemoteDpn(elanInfo, interfaceInfo, dstDpId, physAddress.getValue());
+            }
+        }
+    }
+
+    public void removeMacAddressTables(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceInfo.getInterfaceName());
+        if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
+            List<MacEntry> macEntries =  elanInterfaceMac.getMacEntry();
+            for(MacEntry macEntry : macEntries) {
+                ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
+            }
+        }
+    }
+
+    public void setupLocalBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
+        BigInteger dpnId = interfaceInfo.getDpId();
+        long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
+
+        DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
+        for(String ifName : dpnInterfaces.getInterfaces()) {
+            // In case if there is a InterfacePort in the cache which is not in
+            // operational state, skip processing it
+            InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
+            if (!isOperational(ifInfo)) {
+                continue;
+            }
+
+            listBucketInfo.add(new BucketInfo(getInterfacePortActionInfos(ifInfo)));
+        }
+        GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
+        logger.trace("installing the localBroadCast GroupEntity:{}", groupEntity);
+        mdsalManager.syncInstallGroup(groupEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
+    }
+
+    public void removeLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        BigInteger dpnId = interfaceInfo.getDpId();
+        long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
+
+        GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, getLocalBCGroupBucketInfo(interfaceInfo));
+        logger.trace("deleted the localBroadCast GroupEntity:{}", groupEntity);
+        mdsalManager.syncRemoveGroup(groupEntity);
+    }
+
+    public void setupRemoteBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        List<BucketInfo> listBucketInfo = getRemoteBCGroupBucketInfos(elanInfo, interfaceInfo);
+        BigInteger dpnId = interfaceInfo.getDpId();
+        long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
+        GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
+        mdsalManager.syncInstallGroup(groupEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
+    }
+
+    public void removeRemoteBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        List<BucketInfo> listBucketInfo = getRemoteBCGroupBucketInfos(elanInfo, interfaceInfo);
+        BigInteger dpnId = interfaceInfo.getDpId();
+        long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
+        GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
+        logger.trace("deleting the remoteBroadCast GroupEntity:{}", groupEntity);
+        mdsalManager.syncRemoveGroup(groupEntity);
+    }
+
+    public void setupTerminateServiceTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        long elanTag = elanInfo.getElanTag();
+        //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
+//        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ITMConstants.TERMINATING_SERVICE_TABLE, getFlowRef(ITMConstants.TERMINATING_SERVICE_TABLE, elanTag),
+//                5, elanInfo.getElanInstanceName(), 0,  0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(elanTag)), itmManager.getTunnelMatchesForServiceId(elanTag),
+//                getInstructionsForOutGroup(ElanUtils.getElanLocalBCGID(elanTag)));
+//
+//        mdsalManager.installFlow(flowEntity);
+    }
+
+    public void setupUnknownDMacTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        long elanTag = elanInfo.getElanTag();
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
+                5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)), getMatchesForElanTag(elanTag),
+                getInstructionsForOutGroup(ElanUtils.getElanLocalBCGID(elanTag)));
+
+        mdsalManager.installFlow(flowEntity);
+    }
+
+    private void removeStaticELanFlows(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
+        BigInteger dpId = interfaceInfo.getDpId();
+        long elanTag = elanInfo.getElanTag();
+        /*
+         * If there are not elan ports, remove the unknown smac and default dmac
+         * flows
+         */
+        DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpId);
+        if(dpnInterfaces == null) {
+            return;
+        }
+        List <String> elanInterfaces = dpnInterfaces.getInterfaces();
+        if (elanInterfaces == null || elanInterfaces.isEmpty()) {
+
+            logger.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(), dpId);
+            removeDefaultTermFlow(dpId, elanInfo.getElanTag());
+            removeUnknownDmacFlow(dpId, elanInfo);
+            removeRemoteBroadcastGroup(elanInfo, interfaceInfo);
+            removeLocalBroadcastGroup(elanInfo, interfaceInfo);
+        } else {
+            setupLocalBroadcastGroups(elanInfo, interfaceInfo);
+        }
+    }
+
+    private void removeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo) {
+        FlowEntity flowEntity = getUnknownDmacFlowEntity(dpId, elanInfo);
+        mdsalManager.syncRemoveFlow(flowEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
+    }
+
+    private void removeDefaultTermFlow(BigInteger dpId, long elanTag) {
+        //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
+        //itmManager.removeTerminatingServiceAction(dpId, (int) elanTag);
+    }
+
+    private void bindService(ElanInstance elanInfo, String interfaceName) {
+       // interfaceManager.bindService(interfaceName, ElanUtils.getServiceInfo(elanInfo.getElanInstanceName(), elanInfo.getElanTag(), interfaceName));
+
+        int priority = ElanConstants.ELAN_SERVICE_PRIORITY;
+        int instructionKey = 0;
+        List<Instruction> instructions = new ArrayList<Instruction>();
+        instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanUtils.getElanMetadataLabel(elanInfo.getElanTag()), MetaDataUtil.METADATA_MASK_SERVICE, ++instructionKey));
+        instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(ElanConstants.ELAN_SMAC_TABLE, ++instructionKey));
+        BoundServices
+                serviceInfo =
+                ElanUtils.getBoundServices(String.format("%s.%s.%s", "vpn",elanInfo.getElanInstanceName(), interfaceName),
+                        ElanConstants.ELAN_SERVICE_INDEX, priority,
+                        ElanConstants.COOKIE_ELAN_INGRESS_TABLE, instructions);
+        ElanUtils.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
+                ElanUtils.buildServiceId(interfaceName, ElanConstants.ELAN_SERVICE_INDEX), serviceInfo);
+    }
+
+    private void unbindService(ElanInstance elanInfo, String interfaceName) {
+        ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
+                ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
+                ElanUtils.DEFAULT_CALLBACK);
+    }
+
+    private void unbindService(ElanInstance elanInfo, String interfaceName, int vlanId) {
+        ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION,
+                ElanUtils.buildServiceId(interfaceName,ElanConstants.ELAN_SERVICE_INDEX),
+                ElanUtils.DEFAULT_CALLBACK);
+    }
+
+    private FlowEntity getUnknownDmacFlowEntity(BigInteger dpId, ElanInstance elanInfo) {
+        long elanTag = elanInfo.getElanTag();
+        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        // Matching metadata
+        mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
+                ElanUtils.getElanMetadataLabel(elanTag),
+                MetaDataUtil.METADATA_MASK_SERVICE }));
+
+        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+        List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
+        actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(ElanUtils.getElanRemoteBCGID(elanTag))}));
+        mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
+                5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)),
+                mkMatches, mkInstructions);
+        return flowEntity;
+    }
+
+    private String getFlowRef(long tableId, long elanTag) {
+        return new StringBuffer().append(tableId).append(elanTag).toString();
+    }
+
+    private List<ActionInfo> getInterfacePortActionInfos(InterfaceInfo interfaceInfo) {
+        List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
+        listActionInfo.add(getReg1ActionInfo(interfaceInfo.getInterfaceTag()));
+        listActionInfo.add(new ActionInfo(ActionType.nx_resubmit, new String[]{}));
+        return listActionInfo;
+    }
+
+    private void updateElanDpnInterfacesList(String elanInstanceName, BigInteger dpId, List<String> interfaceNames) {
+        if(!interfaceNames.isEmpty()) {
+            DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
+                    .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
+                    dpnInterface);
+        } else {
+            MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId));
+        }
+        
+    }
+
+    private List<String> createElanInterfacesList(String elanInstanceName, String interfaceName, BigInteger dpId) {
+        List<String> interfaceNames = new ArrayList<String>();
+        interfaceNames.add(interfaceName);
+        DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
+                .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
+        MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
+                dpnInterface);
+        return interfaceNames;
+    }
+
+    private void createElanInterfaceTablesList(String interfaceName) {
+        InstanceIdentifier<ElanInterfaceMac> elanInterfaceMacTables = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
+        Optional<ElanInterfaceMac> interfaceMacTables = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceMacTables);
+        // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
+        if(!interfaceMacTables.isPresent()) {
+            ElanInterfaceMac elanInterfaceMacTable = new ElanInterfaceMacBuilder().setElanInterface(interfaceName).setKey(new ElanInterfaceMacKey(interfaceName)).build();
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName),
+                    elanInterfaceMacTable);
+        }
+    }
+
+    private void createElanStateList(String elanInstanceName, String interfaceName) {
+        InstanceIdentifier<Elan> elanInstance = ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName);
+        Optional<Elan> elanInterfaceLists = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInstance);
+        // Adding new Elan Interface Port to the operational DataStore without Static-Mac Entries..
+        if(elanInterfaceLists.isPresent()) {
+            List<String> interfaceLists = elanInterfaceLists.get().getElanInterfaces();
+            if(interfaceLists == null) {
+                interfaceLists = new ArrayList<>();
+            }
+            interfaceLists.add(interfaceName);
+            Elan elanState = new ElanBuilder().setName(elanInstanceName).setElanInterfaces(interfaceLists).setKey(new ElanKey(elanInstanceName)).build();
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName), elanState);
+        }
+    }
+
+    private boolean isOperational(InterfaceInfo interfaceInfo) {
+        return ((interfaceInfo.getOpState() == InterfaceInfo.InterfaceOpState.UP) && (interfaceInfo.getAdminState() == InterfaceInfo.InterfaceAdminState.ENABLED));
+    }
+
+    protected void updatedIfPrimaryAttributeChanged(ElanInterface elanInterface, boolean isUpdated) {
+        String interfaceName = elanInterface.getName();
+        InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+        BigInteger dpId = interfaceInfo.getDpId();
+        InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = ElanUtils.getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
+        Optional<ElanInterfaceMac> existingElanInterface = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
+        ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanInterface.getElanInstanceName());
+
+        if(!existingElanInterface.isPresent()) {
+            return;
+        }
+
+        List<MacEntry> macEntries = existingElanInterface.get().getMacEntry();
+        if(macEntries != null && !macEntries.isEmpty()) {
+            for (MacEntry macEntry : macEntries) {
+                if(isUpdated) {
+                    ElanUtils.setupMacFlows(elanInfo, interfaceInfo, ElanConstants.STATIC_MAC_TIMEOUT, macEntry.getMacAddress().getValue());
+                } else {
+                    ElanUtils.deleteMacFlows(elanInfo, interfaceInfo, macEntry);
+                }
+            }
+        }
+
+        InstanceIdentifier<DpnInterfaces> dpnInterfaceId = ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInterface.getElanInstanceName(), interfaceInfo.getDpId());
+        Optional<DpnInterfaces> dpnInterfaces =  ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId);
+        List<String> interfaceLists = dpnInterfaces.get().getInterfaces();
+
+        if(isUpdated) {
+            interfaceLists.add(elanInterface.getName());
+        } else {
+            interfaceLists.remove(elanInterface.getName());
+        }
+
+        DpnInterfaces  updateDpnInterfaces = new DpnInterfacesBuilder().setInterfaces(interfaceLists).setDpId(dpId).setKey(new DpnInterfacesKey(dpId)).build();
+        MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, dpnInterfaceId, updateDpnInterfaces);
+
+        if(isUpdated) {
+            installFlowsAndGroups(elanInfo, interfaceInfo);
+        } else {
+            removeStaticELanFlows(elanInfo, interfaceInfo);
+            unbindService(elanInfo, interfaceName);
+        }
+    }
+
+    public void handleTunnelStateEvent(BigInteger srcDpId, BigInteger dstDpId) {
+        ElanDpnInterfaces dpnInterfaceLists =  ElanUtils.getElanDpnInterfacesList();
+        Set<String> elanInstancesMap = new HashSet<>();
+        if(dpnInterfaceLists == null) {
+            return;
+        }
+        List<ElanDpnInterfacesList> elanDpnIf = dpnInterfaceLists.getElanDpnInterfacesList();
+        for(ElanDpnInterfacesList elanDpns: elanDpnIf) {
+            int cnt = 0;
+            String elanName = elanDpns.getElanInstanceName();
+            List<DpnInterfaces> dpnInterfaces = elanDpns.getDpnInterfaces();
+            if(dpnInterfaces == null) {
+               continue;
+            }
+            for (DpnInterfaces dpnIf : dpnInterfaces) {
+               if(dpnIf.getDpId().equals(srcDpId) || dpnIf.getDpId().equals(dstDpId)) {
+                   cnt++;
+                }
+            }
+            if(cnt == 2) {
+                logger.debug("Elan instance:{} is present b/w srcDpn:{} and dstDpn:{}", elanName, srcDpId, dstDpId);
+                DpnInterfaces dpnInterface = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, srcDpId);
+                Set<String> interfaceLists = new HashSet<>();
+                ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanName);
+                interfaceLists.addAll(dpnInterface.getInterfaces());
+                for(String ifName : interfaceLists) {
+                    InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(ifName);
+                    if (isOperational(interfaceInfo)) {
+                        if (interfaceInfo.getDpId().equals(srcDpId) && !elanInstancesMap.contains(elanDpns.getElanInstanceName())) {
+                            elanInstancesMap.add(elanDpns.getElanInstanceName());
+                            elanInterfaceManager.updateRemoteBCGrouponDpnTunnelEvent(elanInfo, interfaceInfo, dstDpId);
+                        }
+                        elanInterfaceManager.installDMacAddressTables(elanInfo, interfaceInfo, dstDpId);
+                    }
+                }
+            }
+
+        }
+    }
+
+    public void handleInterfaceUpated(InterfaceInfo interfaceInfo, ElanInstance elanInstance, boolean isStateUp) {
+        BigInteger dpId = interfaceInfo.getDpId();
+        String elanName = elanInstance.getElanInstanceName();
+        String ifName = interfaceInfo.getInterfaceName();
+        logger.trace("Handling interface update event for interface with info {} , state {}", interfaceInfo, isStateUp);
+        if(isStateUp) {
+
+            DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
+            if(dpnInterfaces == null) {
+                createElanInterfacesList(elanName, interfaceInfo.getInterfaceName(), dpId);
+            } else {
+              List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
+                dpnElanInterfaces.add(interfaceInfo.getInterfaceName());
+                DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
+                        .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
+                MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
+            }
+
+            logger.trace("ElanInterface Service is installed for interface:{}", ifName);
+            elanInterfaceManager.installFlowsAndGroups(elanInstance, interfaceInfo);
+            elanInterfaceManager.installMacAddressTables(elanInstance, interfaceInfo);
+        } else {
+
+            DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanName, dpId);
+            if(dpnInterfaces != null) {
+                List<String> dpnElanInterfaces = dpnInterfaces.getInterfaces();
+                dpnElanInterfaces.remove(interfaceInfo.getInterfaceName());
+                DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
+                        .setInterfaces(dpnElanInterfaces).setKey(new DpnInterfacesKey(dpId)).build();
+                MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanName, interfaceInfo.getDpId()), dpnInterface);
+            }
+            logger.trace("ElanInterface Service is removed for the interface:{}", ifName);
+            elanInterfaceManager.removeMacAddressTables(elanInstance, interfaceInfo);
+            elanInterfaceManager.removeFlowsAndGroups(elanInstance, interfaceInfo);
+        }
+    }
+
+    private List<MatchInfo> getMatchesForFilterEqualsLPortTag(Long LportTag) {
+        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        // Matching metadata
+        mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
+                ElanUtils.getElanMetadataLabel(LportTag),
+                MetaDataUtil.METADATA_MASK_SERVICE }));
+        mkMatches.add(new MatchInfo(MatchFieldType.reg1, new long[] {LportTag.longValue()}));
+        return mkMatches;
+    }
+
+
+    private List<MatchInfo> getMatchesForFilterEqualsReg1LPortTag(Long LportTag) {
+        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        // Matching metadata
+        mkMatches.add(new MatchInfo(MatchFieldType.reg1, new long[] {
+                (LportTag.longValue())}));
+        return mkMatches;
+
+
+    }
+
+    public static class RegMatch {
+
+        final Class<? extends NxmNxReg> reg;
+        final Long value;
+
+        public RegMatch(Class<? extends NxmNxReg> reg, Long value) {
+            super();
+            this.reg = reg;
+            this.value = value;
+        }
+
+        public static RegMatch of(Class<? extends NxmNxReg> reg, Long value) {
+            return new RegMatch(reg, value);
+        }
+    }
+
+    public static void addNxRegMatch(MatchBuilder match, RegMatch... matches) {
+        ArrayList<ExtensionList> extensions = new ArrayList<>();
+        for (RegMatch rm : matches) {
+            Class<? extends ExtensionKey> key;
+            if (NxmNxReg0.class.equals(rm.reg)) {
+                key = NxmNxReg0Key.class;
+            } else if (NxmNxReg1.class.equals(rm.reg)) {
+                key = NxmNxReg1Key.class;
+            } else if (NxmNxReg2.class.equals(rm.reg)) {
+                key = NxmNxReg2Key.class;
+            } else if (NxmNxReg3.class.equals(rm.reg)) {
+                key = NxmNxReg3Key.class;
+            } else if (NxmNxReg4.class.equals(rm.reg)) {
+                key = NxmNxReg4Key.class;
+            } else if (NxmNxReg5.class.equals(rm.reg)) {
+                key = NxmNxReg5Key.class;
+            } else if (NxmNxReg6.class.equals(rm.reg)) {
+                key = NxmNxReg6Key.class;
+            } else {
+                key = NxmNxReg7Key.class;
+            }
+            NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder().setNxmNxReg(
+                    new NxmNxRegBuilder().setReg(rm.reg).setValue(rm.value).build()).build();
+            extensions.add(new ExtensionListBuilder().setExtensionKey(key)
+                    .setExtension(new ExtensionBuilder().addAugmentation(NxAugMatchNodesNodeTableFlow.class, am).build())
+                    .build());
+        }
+        GeneralAugMatchNodesNodeTableFlow m = new GeneralAugMatchNodesNodeTableFlowBuilder().setExtensionList(
+                extensions).build();
+        match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
+
+    }
+
+
+    private List<InstructionInfo> getInstructionsInPortForOutGroup(
+            long GroupId) {
+        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+        List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
+        actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[]{ "123"}));
+        actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(GroupId)}));
+        mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+        return mkInstructions;
+    }
+
+    private List<InstructionInfo> getInstructionsInPortForOutGroup(
+            String ifName) {
+        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+        List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
+        //TODO: modify in-port action
+        //actionsInfos.add(new ActionInfo(ActionType.set_source_port_field, new String[]{ "255"}));
+        actionsInfos.addAll(getEgressActionsForInterface(ifName));
+        mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+        return mkInstructions;
+    }
+
+
+
+    private List<InstructionInfo> getInstructionsDrop() {
+        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+        List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
+        actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[]{}));
+        mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+        return mkInstructions;
+    }
+
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanItmEventListener.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanItmEventListener.java
new file mode 100755 (executable)
index 0000000..2f8394c
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+//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.controller.md.sal.common.api.data.LogicalDatastoreType;
+//import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.TunnelsState;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels_state.StateTunnelList;
+//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.math.BigInteger;
+
+public class ElanItmEventListener{
+
+}
+//public class ElanItmEventListener extends AbstractDataChangeListener<DataObject> implements AutoCloseable {
+//FIXME: This class is to be made functional once ITM is added
+//    private static final Logger logger = LoggerFactory.getLogger(ElanItmEventListener.class);
+//    private final DataBroker broker;
+//    private ListenerRegistration<DataChangeListener> listenerRegistration;
+//    private ElanInterfaceManager elanInterfaceManager;
+//
+//    public ElanItmEventListener(final DataBroker db, final ElanInterfaceManager ifManager) {
+//        super(StateTunnelList.class);
+//        broker = db;
+//        elanInterfaceManager = ifManager;
+//        registerListener(db);
+//    }
+//
+//    private void registerListener(final DataBroker db) {
+//        try {
+//            listenerRegistration = broker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+//                    getWildCardPath(), ElanItmEventListener.this, AsyncDataBroker.DataChangeScope.SUBTREE);
+//        } catch (final Exception e) {
+//            logger.error("ITM Monitor Interfaces DataChange listener registration fail!", e);
+//            throw new IllegalStateException("ITM Monitor registration Listener failed.", e);
+//        }
+//    }
+//
+//    private InstanceIdentifier<StateTunnelList> getWildCardPath() {
+//        return InstanceIdentifier.create(TunnelsState.class).child(StateTunnelList.class);
+//    }
+//
+//    @Override
+//    public void close() throws Exception {
+//        if (listenerRegistration != null) {
+//            try {
+//                listenerRegistration.close();
+//            } catch (final Exception e) {
+//                logger.error("Error when cleaning up DataChangeListener.", e);
+//            }
+//            listenerRegistration = null;
+//        }
+//    }
+//
+//    @Override
+//    protected void remove(InstanceIdentifier<StateTunnelList> identifier, StateTunnelList del) {
+//
+//    }
+//
+//    @Override
+//    protected void update(InstanceIdentifier<StateTunnelList> identifier, StateTunnelList original, StateTunnelList update) {
+//        BigInteger srcDpId = update.getSourceDPN();
+//        BigInteger dstDpId = update.getDestinationDPN();
+//        logger.trace("ITM Tunnel state event changed from :{} to :{} for transportZone:{}",original.isLogicalTunnelState(), update.isLogicalTunnelState(), update.getLogicalTunnelGroupName());
+//
+//        if(update.isLogicalTunnelState()) {
+//            logger.trace("ITM Tunnel State is Up b/w srcDpn: {} and dstDpn: {}", srcDpId, dstDpId);
+//            elanInterfaceManager.handleTunnelStateEvent(srcDpId, dstDpId);
+//        }
+//    }
+//
+//    @Override
+//    protected void add(InstanceIdentifier<StateTunnelList> identifier, StateTunnelList add) {
+//        BigInteger srcDpId =  add.getSourceDPN();
+//        BigInteger dstDpId = add.getDestinationDPN();
+//        logger.trace("ITM Tunnel state event:{} for transportZone:{} of {}", add.isLogicalTunnelState(), add.getLogicalTunnelGroupName());
+//
+//        if(add.isLogicalTunnelState()) {
+//            logger.trace("ITM Tunnel State is Up b/w srcDpn: {} and dstDpn: {}", srcDpId, dstDpId);
+//            elanInterfaceManager.handleTunnelStateEvent(srcDpId, dstDpId);
+//        }
+//    }
+//}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanNodeListener.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanNodeListener.java
new file mode 100644 (file)
index 0000000..05a808c
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+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.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.mdsalutil.AbstractDataChangeListener;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.mdsalutil.*;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+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.yangtools.concepts.ListenerRegistration;
+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 ElanNodeListener extends AbstractDataChangeListener<Node> {
+
+    private static final Logger logger = LoggerFactory.getLogger(ElanNodeListener.class);
+
+    private IMdsalApiManager mdsalManager;
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+    private final DataBroker broker;
+
+    public ElanNodeListener(final DataBroker db, IMdsalApiManager mdsalManager) {
+        super(Node.class);
+        broker = db;
+        this.mdsalManager = mdsalManager;
+        registerListener(db);
+    }
+
+    private void registerListener(final DataBroker db) {
+        try {
+            listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+                    getWildCardPath(), ElanNodeListener.this, AsyncDataBroker.DataChangeScope.SUBTREE);
+        } catch (final Exception e) {
+            logger.error("IfmNodeConnectorListener: DataChange listener registration fail!", e);
+            throw new IllegalStateException("IfmNodeConnectorListener: registration Listener failed.", e);
+        }
+    }
+
+    private InstanceIdentifier<Node> getWildCardPath() {
+        return InstanceIdentifier.create(Nodes.class).child(Node.class);
+    }
+
+
+    @Override
+    protected void remove(InstanceIdentifier<Node> identifier, Node del) {
+
+    }
+
+    @Override
+    protected void update(InstanceIdentifier<Node> identifier, Node original, Node update) {
+
+    }
+
+    @Override
+    protected void add(InstanceIdentifier<Node> identifier, Node add) {
+        NodeId nodeId = add.getId();
+        String[] node =  nodeId.getValue().split(":");
+        BigInteger dpId = new BigInteger(node[1]);
+        createTableMissEntry(dpId);
+    }
+
+    public void createTableMissEntry(BigInteger dpnId) {
+        setupTableMissSmacFlow(dpnId);
+        setupTableMissDmacFlow(dpnId);
+    }
+
+    private void setupTableMissSmacFlow(BigInteger dpId) {
+        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+        List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
+        actionsInfos.add(new ActionInfo(ActionType.punt_to_controller, new String[] {}));
+        mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
+        mkInstructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { ElanConstants.ELAN_DMAC_TABLE }));
+
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, ElanConstants.ELAN_SMAC_TABLE, getTableMissFlowRef(ElanConstants.ELAN_SMAC_TABLE),
+                0, "ELAN sMac Table Miss Flow", 0, 0, ElanConstants.COOKIE_ELAN_KNOWN_SMAC,
+                mkMatches, mkInstructions);
+        mdsalManager.installFlow(flowEntity);
+    }
+
+    private void setupTableMissDmacFlow(BigInteger dpId) {
+        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+
+        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+        mkInstructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { ElanConstants.ELAN_UNKNOWN_DMAC_TABLE }));
+
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, ElanConstants.ELAN_DMAC_TABLE, getTableMissFlowRef(ElanConstants.ELAN_DMAC_TABLE),
+                0, "ELAN dMac Table Miss Flow", 0, 0, ElanConstants.COOKIE_ELAN_KNOWN_DMAC,
+                mkMatches, mkInstructions);
+        mdsalManager.installFlow(flowEntity);
+    }
+
+    private String getTableMissFlowRef(long tableId) {
+        return new StringBuffer().append(tableId).toString();
+    }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanPacketInHandler.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanPacketInHandler.java
new file mode 100755 (executable)
index 0000000..04de7e3
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.elan.utils.ElanUtils;
+//import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
+import org.opendaylight.vpnservice.mdsalutil.NWUtil;
+import org.opendaylight.controller.liblldp.NetUtils;
+import org.opendaylight.vpnservice.mdsalutil.packet.Ethernet;
+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.packet.service.rev130709.NoMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketInReason;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.Elan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.tag.name.map.ElanTagName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._if.indexes._interface.map.IfIndexInterface;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+
+public class ElanPacketInHandler implements PacketProcessingListener {
+
+    private final DataBroker broker;
+    private IInterfaceManager interfaceManager;
+
+    private static final Logger logger = LoggerFactory.getLogger(ElanPacketInHandler.class);
+
+    public ElanPacketInHandler(DataBroker dataBroker) {
+        broker = dataBroker;
+    }
+
+    public void setInterfaceManager(IInterfaceManager interfaceManager) {
+        this.interfaceManager = interfaceManager;
+    }
+
+    @Override
+    public void onPacketReceived(PacketReceived notification) {
+        Class<? extends PacketInReason>  pktInReason =  notification.getPacketInReason();
+        short tableId = notification.getTableId().getValue();
+        if(pktInReason == NoMatch.class && tableId == ElanConstants.ELAN_SMAC_TABLE) {
+            try {
+                byte[] data = notification.getPayload();
+                Ethernet res = new Ethernet();
+
+                res.deserialize(data, 0, data.length * NetUtils.NumBitsInAByte);
+
+                byte[] srcMac = res.getSourceMACAddress();
+                String macAddress = NWUtil.toStringMacAddress(srcMac);
+                PhysAddress physAddress = new PhysAddress(macAddress);
+                BigInteger metadata = notification.getMatch().getMetadata().getMetadata();
+                long elanTag = MetaDataUtil.getElanTagFromMetadata(metadata);
+
+                long portTag = MetaDataUtil.getLportFromMetadata(metadata).intValue();
+
+                IfIndexInterface interfaceInfo = ElanUtils.getInterfaceInfoByInterfaceTag(portTag);
+                if (interfaceInfo == null) {
+                    logger.warn("There is no interface for given portTag {}", portTag);
+                    return;
+                }
+                String interfaceName = interfaceInfo.getInterfaceName();
+                ElanTagName elanTagName = ElanUtils.getElanInfoByElanTag(elanTag);
+                String elanName = elanTagName.getName();
+                Elan elanInfo = ElanUtils.getElanByName(elanName);
+                MacEntry macEntry = ElanUtils.getInterfaceMacEntriesOperationalDataPath(interfaceName, physAddress);
+                if(macEntry != null && macEntry.getInterface() == interfaceName) {
+                    BigInteger macTimeStamp = macEntry.getControllerLearnedForwardingEntryTimestamp();
+                    if (System.currentTimeMillis() > macTimeStamp.longValue()+2000) {
+                        /*
+                         * Protection time expired. Even though the MAC has been learnt (it is in the cache)
+                         * the packets are punted to controller. Which means, the the flows were not successfully
+                         * created in the DPN, but the MAC entry has been added successfully in the cache.
+                         *
+                         * So, the cache has to be cleared and the flows and cache should be recreated (clearing
+                         * of cache is required so that the timestamp is updated).
+                         */
+                        InstanceIdentifier<MacEntry> macEntryId =  ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
+                        ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+                    } else {
+                        // Protection time running. Ignore packets for 2 seconds
+                        return;
+                    }
+                } else if(macEntry != null) {
+                    // MAC address has moved. Overwrite the mapping and replace MAC flows
+                    long macTimeStamp = macEntry.getControllerLearnedForwardingEntryTimestamp().longValue();
+                    if (System.currentTimeMillis() > macTimeStamp+1000) {
+
+                        InstanceIdentifier<MacEntry> macEntryId =  ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
+                        ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+                        tryAndRemoveInvalidMacEntry(elanName, macEntry);
+                    } else {
+                        // New FEs flood their packets on all interfaces. This can lead
+                        // to many contradicting packet_ins. Ignore all packets received
+                        // within 1s after the first packet_in
+                        return;
+                    }
+                }
+                BigInteger timeStamp = new BigInteger(String.valueOf((long)System.currentTimeMillis()));
+                macEntry = new MacEntryBuilder().setInterface(interfaceName).setMacAddress(physAddress).setKey(new MacEntryKey(physAddress)).setControllerLearnedForwardingEntryTimestamp(timeStamp).setIsStaticAddress(false).build();
+                InstanceIdentifier<MacEntry> macEntryId = ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
+                MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, macEntryId, macEntry);
+                InstanceIdentifier<MacEntry> elanMacEntryId = ElanUtils.getMacEntryOperationalDataPath(elanName, physAddress);
+                MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, elanMacEntryId, macEntry);
+                ElanInstance elanInstance = ElanUtils.getElanInstanceByName(elanName);
+                ElanUtils.setupMacFlows(elanInstance, interfaceManager.getInterfaceInfo(interfaceName), elanInstance.getMacTimeout(), macAddress);
+            } catch (Exception e) {
+                logger.trace("Failed to decode packet: {}", e);
+            }
+        }
+
+    }
+
+
+    /*
+ * Though this method is a little costlier because it uses try-catch construct, it is used
+ * only in rare scenarios like MAC movement or invalid Static MAC having been added on a
+ * wrong ELAN.
+ */
+    private void tryAndRemoveInvalidMacEntry(String elanName, MacEntry macEntry) {
+        ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanName);
+        if (elanInfo == null) {
+            logger.warn(String.format("MAC %s is been added (either statically or dynamically) for an invalid Elan %s. "
+                    + "Manual cleanup may be necessary", macEntry.getMacAddress(), elanName));
+            return;
+        }
+
+        InterfaceInfo oldInterfaceLport = interfaceManager.getInterfaceInfo(macEntry.getInterface());
+        if (oldInterfaceLport == null) {
+            logger.warn(String.format("MAC %s is been added (either statically or dynamically) on an invalid Logical Port %s. "
+                    + "Manual cleanup may be necessary", macEntry.getMacAddress(), macEntry.getInterface()));
+            return;
+        }
+        ElanUtils.deleteMacFlows(elanInfo, oldInterfaceLport, macEntry);
+    }
+
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanServiceProvider.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanServiceProvider.java
new file mode 100644 (file)
index 0000000..9b8eb44
--- /dev/null
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.NotificationService;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+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.elanmanager.api.IElanService;
+import org.opendaylight.vpnservice.elan.statisitcs.ElanStatisticsImpl;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.elan.utils.ElanUtils;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+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.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInstances;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.Elan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.statistics.rev150824.ElanStatisticsService;
+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.idmanager.rev150403.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.elanmanager.exceptions.MacNotFoundException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Future;
+
+public class ElanServiceProvider implements BindingAwareProvider, IElanService, AutoCloseable {
+
+    private IdManagerService idManager;
+    private IMdsalApiManager mdsalManager;
+    private IInterfaceManager interfaceManager;
+    private OdlInterfaceRpcService interfaceManagerRpcService;
+    private ElanInstanceManager elanInstanceManager;
+    private ElanForwardingEntriesHandler elanForwardingEntriesHandler;
+    private ElanInterfaceManager elanInterfaceManager;
+    private ElanPacketInHandler elanPacketInHandler;
+    private ElanSmacFlowEventListener elanSmacFlowEventListener;
+    private ElanNodeListener elanNodeListener;
+    private NotificationService notificationService;
+    private RpcProviderRegistry rpcProviderRegistry;
+
+    public ElanServiceProvider(RpcProviderRegistry rpcRegistry) {
+        rpcProviderRegistry = rpcRegistry;
+    }
+
+    //private ElanInterfaceEventListener elanInterfaceEventListener;
+    private ElanItmEventListener elanItmEventListener;
+    private IITMProvider itmManager;
+    private DataBroker broker;
+
+    private static final Logger logger = LoggerFactory.getLogger(ElanServiceProvider.class);
+
+    @Override
+    public void onSessionInitiated(ProviderContext session) {
+        createIdPool();
+        broker = session.getSALService(DataBroker.class);
+
+        elanForwardingEntriesHandler = new ElanForwardingEntriesHandler(broker, mdsalManager);
+        elanForwardingEntriesHandler.setIITMManager(itmManager);
+
+        elanInterfaceManager = ElanInterfaceManager.getElanInterfaceManager();
+        elanInterfaceManager.setInterfaceManager(interfaceManager);
+        elanInterfaceManager.setIdManager(idManager);
+        elanInterfaceManager.setMdSalApiManager(mdsalManager);
+        elanInterfaceManager.setDataBroker(broker);
+        elanInterfaceManager.setIITMManager(itmManager);
+        elanInterfaceManager.registerListener();
+        elanInterfaceManager.setInterfaceManagerRpcService(interfaceManagerRpcService);
+        elanInterfaceManager.setElanForwardingEntriesHandler(elanForwardingEntriesHandler);
+
+        elanInstanceManager = ElanInstanceManager.getElanInstanceManager();
+        elanInstanceManager.setDataBroker(broker);
+        elanInstanceManager.setIdManager(idManager);
+        elanInstanceManager.setElanInterfaceManager(elanInterfaceManager);
+        elanInstanceManager.registerListener();
+
+        elanNodeListener = new ElanNodeListener(broker, mdsalManager);
+
+        elanPacketInHandler = new ElanPacketInHandler(broker);
+        elanPacketInHandler.setInterfaceManager(interfaceManager);
+        notificationService.registerNotificationListener(elanPacketInHandler);
+
+        elanSmacFlowEventListener = new ElanSmacFlowEventListener(broker);
+        elanSmacFlowEventListener.setMdSalApiManager(mdsalManager);
+        elanSmacFlowEventListener.setInterfaceManager(interfaceManager);
+        elanSmacFlowEventListener.setIITMManager(itmManager);
+        elanSmacFlowEventListener.setSalFlowService(session.getRpcService(SalFlowService.class));
+        notificationService.registerNotificationListener(elanSmacFlowEventListener);
+
+        // Initialize statistics rpc provider for elan
+        ElanStatisticsService interfaceStatsService = new ElanStatisticsImpl(broker, interfaceManager, mdsalManager);
+        rpcProviderRegistry.addRpcImplementation(ElanStatisticsService.class, interfaceStatsService);
+
+        ElanUtils.setElanServiceProvider(this);
+    }
+
+    public void setIdManager(IdManagerService idManager) {
+        this.idManager = idManager;
+    }
+
+    public void setMdsalManager(IMdsalApiManager mdsalManager) {
+        this.mdsalManager = mdsalManager;
+    }
+
+    public void setInterfaceManager(IInterfaceManager interfaceManager) {
+        this.interfaceManager = interfaceManager;
+    }
+
+    public IMdsalApiManager getMdsalManager() {
+        return mdsalManager;
+    }
+
+    public IITMProvider getItmManager() {
+        return itmManager;
+    }
+
+    public DataBroker getBroker() {
+        return broker;
+    }
+
+    public void setNotificationService(NotificationService notificationService) {
+        this.notificationService = notificationService;
+    }
+
+    public void setInterfaceManagerRpcService(OdlInterfaceRpcService interfaceManager) {
+        this.interfaceManagerRpcService = interfaceManager;
+    }
+
+    public OdlInterfaceRpcService getInterfaceManagerRpcService() {
+        return interfaceManagerRpcService;
+    }
+
+    public void setItmManager(IITMProvider itmManager) {
+        this.itmManager = itmManager;
+    }
+
+    private void createIdPool() {
+        CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
+            .setPoolName(ElanConstants.ELAN_ID_POOL_NAME).setLow(ElanConstants.ELAN_ID_LOW_VALUE).setHigh(ElanConstants.ELAN_ID_HIGH_VALUE)
+            .build();
+        try {
+           Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
+           if ((result != null) && (result.get().isSuccessful())) {
+               logger.debug("ELAN Id Pool is created successfully");
+            }
+        } catch (Exception e) {
+            logger.error("Failed to create ELAN Id pool {}", e);
+        }
+    }
+
+    @Override
+    public boolean createElanInstance(String elanInstanceName, long macTimeout, String description) {
+        ElanInstance existingElanInstance = elanInstanceManager.getElanInstanceByName(elanInstanceName);
+        boolean isSuccess = true;
+        if(existingElanInstance != null) {
+           if(compareWithExistingElanInstance(existingElanInstance, macTimeout, description)) {
+               logger.debug("Elan Instance is already present in the Operational DS {}", existingElanInstance);
+               return true;
+           } else {
+               ElanInstance updateElanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setDescription(description).setMacTimeout(macTimeout).setKey(new ElanInstanceKey(elanInstanceName)).build();
+               MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceConfigurationDataPath(elanInstanceName), updateElanInstance);
+               logger.debug("Updating the Elan Instance {} with MAC TIME-OUT %l and Description %s ", updateElanInstance, macTimeout, description);
+           }
+        } else {
+            ElanInstance elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setMacTimeout(macTimeout).setDescription(description).setKey(new ElanInstanceKey(elanInstanceName)).build();
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceIdentifier(elanInstanceName), elanInstance);
+            logger.debug("Creating the new Elan Instance {}", elanInstance);
+        }
+        return isSuccess;
+    }
+
+    public static boolean compareWithExistingElanInstance(ElanInstance existingElanInstance, long macTimeOut, String description) {
+        boolean isEqual = false;
+        if(existingElanInstance.getMacTimeout() == macTimeOut && existingElanInstance.getDescription().equals(description)) {
+            isEqual = true;
+        }
+        return isEqual;
+    }
+    @Override
+    public void updateElanInstance(String elanInstanceName, long newMacTimout, String newDescription) {
+        createElanInstance(elanInstanceName, newMacTimout, newDescription);
+    }
+
+    @Override
+    public boolean deleteElanInstance(String elanInstanceName) {
+        boolean isSuccess = false;
+        ElanInstance existingElanInstance = elanInstanceManager.getElanInstanceByName(elanInstanceName);
+        if(existingElanInstance == null) {
+            logger.debug("Elan Instance is not present {}" , existingElanInstance);
+            return isSuccess;
+        }
+        logger.debug("Deletion of the existing Elan Instance {}", existingElanInstance);
+        ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInstanceIdentifier(elanInstanceName));
+        isSuccess = true;
+        return isSuccess;
+    }
+
+    @Override
+    public void addElanInterface(String elanInstanceName, String interfaceName, List<String> staticMacAddresses, String description) {
+          ElanInstance existingElanInstance = elanInstanceManager.getElanInstanceByName(elanInstanceName);
+          if(existingElanInstance != null) {
+              ElanInterface elanInterface;
+              if(staticMacAddresses == null) {
+                  elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName).setDescription(description).setName(interfaceName).setKey(new ElanInterfaceKey(interfaceName)).build();
+              } else {
+                  elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName).setDescription(description).setName(interfaceName).setStaticMacEntries(getPhysAddress(staticMacAddresses)).setKey(new ElanInterfaceKey(interfaceName)).build();
+              }
+              MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface);
+              logger.debug("Creating the new ELan Interface {}", elanInterface);
+          }
+
+    }
+
+    @Override
+    public void updateElanInterface(String elanInstanceName, String interfaceName, List<String> updatedStaticMacAddresses, String newDescription) {
+        ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(interfaceName);
+        if (existingElanInterface == null) {
+            return;
+        }
+        List<PhysAddress> existingMacAddress = existingElanInterface.getStaticMacEntries();
+        List<PhysAddress> updatedMacAddresses = getPhysAddress(updatedStaticMacAddresses);
+        List<PhysAddress> updatedPhysAddress = getUpdatedPhyAddress(existingMacAddress, updatedMacAddresses);
+        if(updatedPhysAddress.size() > 0) {
+            logger.debug("updating the ElanInterface with new Mac Entries {}", updatedStaticMacAddresses);
+            ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName).setName(interfaceName).setDescription(newDescription).setStaticMacEntries(updatedPhysAddress).setKey(new ElanInterfaceKey(interfaceName)).build();
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface);
+        }
+    }
+
+    @Override
+    public void deleteElanInterface(String elanInstanceName, String interfaceName) {
+        ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(interfaceName);
+        if(existingElanInterface != null) {
+            ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName));
+            logger.debug("deleting the Elan Interface {}", existingElanInterface);
+        }
+    }
+
+    @Override
+    public void addStaticMacAddress(String elanInstanceName, String interfaceName, String macAddress) {
+        ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(interfaceName);
+        PhysAddress updateStaticMacAddress = new PhysAddress(macAddress);
+        if (existingElanInterface != null) {
+            List<PhysAddress> existingMacAddress = existingElanInterface.getStaticMacEntries();
+            if(existingMacAddress.contains(updateStaticMacAddress)) {
+                return;
+            }
+            existingMacAddress.add(updateStaticMacAddress);
+            ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName).setName(interfaceName).setStaticMacEntries(existingMacAddress).setDescription(existingElanInterface.getDescription()).setKey(new ElanInterfaceKey(interfaceName)).build();
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface);
+        }
+    }
+
+    @Override
+    public void deleteStaticMacAddress(String elanInstanceName, String interfaceName, String macAddress) throws MacNotFoundException {
+           ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(interfaceName);
+        PhysAddress physAddress = new PhysAddress(macAddress);
+        if(existingElanInterface == null) {
+            return;
+        }
+        List<PhysAddress> existingMacAddress = existingElanInterface.getStaticMacEntries();
+        if(existingMacAddress.contains(physAddress)) {
+            existingMacAddress.remove(physAddress);
+            ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName).setName(interfaceName).setStaticMacEntries(existingMacAddress).setDescription(existingElanInterface.getDescription()).setKey(new ElanInterfaceKey(interfaceName)).build();
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface);
+        } else {
+            throw new MacNotFoundException("Mac Not Found Exception");
+        }
+    }
+
+    @Override
+    public Collection<MacEntry> getElanMacTable(String elanInstanceName) {
+        Elan elanInfo = ElanUtils.getElanByName(elanInstanceName);
+        List<MacEntry> macAddress = new ArrayList<>();
+        if(elanInfo == null) {
+            return macAddress;
+        }
+       List<String> elanInterfaces =  elanInfo.getElanInterfaces();
+        if(elanInterfaces != null && elanInterfaces.size() > 0) {
+            for(String elanInterface : elanInterfaces) {
+                ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(elanInterface);
+                if(elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null && elanInterfaceMac.getMacEntry().size() > 0){
+                    macAddress.addAll(elanInterfaceMac.getMacEntry());
+                }
+            }
+        }
+       return macAddress;
+    }
+
+    @Override
+    public void flushMACTable(String elanInstanceName) {
+        Elan elanInfo = ElanUtils.getElanByName(elanInstanceName);
+        if(elanInfo == null) {
+            return;
+        }
+        List<String> elanInterfaces = elanInfo.getElanInterfaces();
+        if (elanInterfaces == null || elanInterfaces.isEmpty()) {
+            return;
+        }
+        for (String elanInterface : elanInterfaces) {
+            ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(elanInterface);
+            if (elanInterfaceMac.getMacEntry() != null && elanInterfaceMac.getMacEntry().size() > 0) {
+                List<MacEntry> macEntries =  elanInterfaceMac.getMacEntry();
+                for(MacEntry macEntry : macEntries) {
+                    try {
+                        deleteStaticMacAddress(elanInstanceName, elanInterface, macEntry.getMacAddress().getValue());
+                    } catch (MacNotFoundException e) {
+                        logger.error("Mac Not Found Exception {}", e);
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+
+    }
+
+    @Override
+    public void close() throws Exception {
+        elanInstanceManager.close();
+    }
+
+    public static List<PhysAddress> getPhysAddress(List<String> macAddress) {
+        List<PhysAddress> physAddresses = new ArrayList<>();
+        for(String mac : macAddress) {
+            physAddresses.add(new PhysAddress(mac));
+        }
+        return physAddresses;
+    }
+
+
+    public List<PhysAddress> getUpdatedPhyAddress(List<PhysAddress> originalAddresses, List<PhysAddress> updatePhyAddresses) {
+        if(updatePhyAddresses != null && !updatePhyAddresses.isEmpty()) {
+            List<PhysAddress> existingClonedPhyAddress = new ArrayList<>();
+            if (originalAddresses != null && !originalAddresses.isEmpty()) {
+                existingClonedPhyAddress.addAll(0, originalAddresses);
+                originalAddresses.removeAll(updatePhyAddresses);
+                updatePhyAddresses.removeAll(existingClonedPhyAddress);
+            }
+        }
+        return updatePhyAddresses;
+    }
+
+    @Override
+    public ElanInstance getElanInstance(String elanName) {
+        return ElanUtils.getElanInstanceByName(elanName);
+    }
+
+    @Override
+    public List<ElanInstance> getElanInstances() {
+        List<ElanInstance> elanList = new ArrayList<ElanInstance>();
+        InstanceIdentifier<ElanInstances> elanInstancesIdentifier =  InstanceIdentifier.builder(ElanInstances.class).build();
+        Optional<ElanInstances> elansOptional  = ElanUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanInstancesIdentifier);
+        if(elansOptional.isPresent()) {
+            elanList.addAll(elansOptional.get().getElanInstance());
+        }
+        return elanList;
+    }
+
+    @Override
+    public List<String> getElanInterfaces(String elanInstanceName) {
+        List<String> elanInterfaces = new ArrayList<>();
+        InstanceIdentifier<ElanInterfaces> elanInterfacesIdentifier =  InstanceIdentifier.builder(ElanInterfaces.class).build();
+        Optional<ElanInterfaces> elanInterfacesOptional  = ElanUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanInterfacesIdentifier);
+        if(!elanInterfacesOptional.isPresent()) {
+             return elanInterfaces;
+        }
+        List<ElanInterface> elanInterfaceList = elanInterfacesOptional.get().getElanInterface();
+        for(ElanInterface elanInterface : elanInterfaceList) {
+            if(elanInterface.getElanInstanceName().equals(elanInstanceName)) {
+                elanInterfaces.add(elanInterface.getName());
+            }
+        }
+        return elanInterfaces;
+    }
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanSmacFlowEventListener.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/internal/ElanSmacFlowEventListener.java
new file mode 100644 (file)
index 0000000..e2cb47b
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.internal;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.elan.utils.ElanUtils;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+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.service.rev130819.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.tag.name.map.ElanTagName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._if.indexes._interface.map.IfIndexInterface;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331._if.indexes._interface.map.IfIndexInterface;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+
+public class ElanSmacFlowEventListener implements SalFlowListener {
+    private final DataBroker broker;
+    private IMdsalApiManager mdsalManager;
+    private IInterfaceManager interfaceManager;
+    private IITMProvider itmManager;
+    private static final Logger logger = LoggerFactory.getLogger(ElanSmacFlowEventListener.class);
+
+    public ElanSmacFlowEventListener(DataBroker dataBroker) {
+        broker = dataBroker;
+    }
+    private SalFlowService salFlowService;
+
+    public SalFlowService getSalFlowService() {
+        return this.salFlowService;
+    }
+
+    public void setSalFlowService(final SalFlowService salFlowService) {
+        this.salFlowService = salFlowService;
+    }
+    public void setInterfaceManager(IInterfaceManager interfaceManager) {
+        this.interfaceManager = interfaceManager;
+    }
+
+
+    public void setIITMManager(IITMProvider itmManager) {
+        this.itmManager = itmManager;
+    }
+    public void setMdSalApiManager(IMdsalApiManager mdsalManager) {
+        this.mdsalManager = mdsalManager;
+    }
+    @Override
+    public void onFlowAdded(FlowAdded arg0) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void onFlowRemoved(FlowRemoved arg0) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void onFlowUpdated(FlowUpdated arg0) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void onNodeErrorNotification(NodeErrorNotification arg0) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void onNodeExperimenterErrorNotification(NodeExperimenterErrorNotification arg0) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void onSwitchFlowRemoved(SwitchFlowRemoved switchFlowRemoved) {
+        short tableId = switchFlowRemoved.getTableId();
+        if (tableId == ElanConstants.ELAN_SMAC_TABLE) {
+            BigInteger metadata = switchFlowRemoved.getMatch().getMetadata().getMetadata();
+            long elanTag = MetaDataUtil.getElanTagFromMetadata(metadata);
+            ElanTagName elanTagInfo = ElanUtils.getElanInfoByElanTag(elanTag);
+            if (elanTagInfo == null) {
+                return;
+            }
+            String srcMacAddress = switchFlowRemoved.getMatch().getEthernetMatch()
+                    .getEthernetSource().getAddress().getValue().toUpperCase();
+            int portTag = MetaDataUtil.getLportFromMetadata(metadata).intValue();
+            if (portTag == 0) {
+                logger.debug(String.format("Flow removed event on SMAC flow entry. But having port Tag as 0 "));
+                return;
+            }
+            IfIndexInterface existingInterfaceInfo = ElanUtils.getInterfaceInfoByInterfaceTag(portTag);
+            String interfaceName = existingInterfaceInfo.getInterfaceName();
+            PhysAddress physAddress = new PhysAddress(srcMacAddress);
+            if (interfaceName == null) {
+                logger.error(String.format("LPort record not found for tag %d", portTag));
+                return;
+            }
+            MacEntry macEntry = ElanUtils.getInterfaceMacEntriesOperationalDataPath(interfaceName, physAddress);
+            InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+            if(macEntry != null && interfaceInfo != null) {
+                ElanUtils.deleteMacFlows(ElanUtils.getElanInstanceByName(elanTagInfo.getName()), interfaceInfo, macEntry);
+            }
+            InstanceIdentifier<MacEntry> macEntryId =  ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
+            ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, macEntryId);
+        }
+    }
+
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/statisitcs/ElanStatisticsImpl.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/statisitcs/ElanStatisticsImpl.java
new file mode 100755 (executable)
index 0000000..7f927dd
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.statisitcs;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.vpnservice.elan.utils.ElanConstants;
+import org.opendaylight.vpnservice.elan.utils.ElanUtils;
+//import org.opendaylight.vpnservice.ericsson.mdsalutil.statistics.StatValue;
+//import org.opendaylight.vpnservice.ericsson.mdsalutil.statistics.StatisticsInfo;
+import org.opendaylight.vpnservice.interfacemgr.exceptions.InterfaceNotFoundException;
+import org.opendaylight.vpnservice.interfacemgr.exceptions.InterfaceServiceNotFoundException;
+import org.opendaylight.vpnservice.interfacemgr.globals.IfmConstants;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceServiceUtil;
+import org.opendaylight.vpnservice.interfacemgr.globals.VlanInterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice._interface.service.rev150602._interface.service.info.ServiceInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice._interface.statistics.rev150824.ResultCode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.statistics.rev150824.ElanStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.statistics.rev150824.GetElanInterfaceStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.statistics.rev150824.GetElanInterfaceStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.statistics.rev150824.GetElanInterfaceStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.statistics.rev150824.get.elan._interface.statistics.output.StatResultBuilder;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.ServicesInfo;
+
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+public class ElanStatisticsImpl implements ElanStatisticsService {
+    private DataBroker dataBroker;
+    private IInterfaceManager interfaceManager;
+    private IMdsalApiManager mdsalMgr;
+    private static final Logger logger = LoggerFactory.getLogger(ElanStatisticsImpl.class);
+
+    public ElanStatisticsImpl(DataBroker dataBroker, IInterfaceManager interfaceManager,
+            IMdsalApiManager mdsalMgr) {
+        this.interfaceManager = interfaceManager;
+        this.dataBroker = dataBroker;
+        this.mdsalMgr = mdsalMgr;
+    }
+
+    @Override
+    public Future<RpcResult<GetElanInterfaceStatisticsOutput>> getElanInterfaceStatistics(
+            GetElanInterfaceStatisticsInput input) {
+        String interfaceName = input.getInterfaceName();
+        logger.debug("getElanInterfaceStatistics is called for elan interface {}", interfaceName);
+        RpcResultBuilder<GetElanInterfaceStatisticsOutput> rpcResultBuilder = null;
+        if (interfaceName == null) {
+            rpcResultBuilder = RpcResultBuilder.failed();
+            return getFutureWithAppErrorMessage(rpcResultBuilder, "Interface name is not provided");
+        }
+        ElanInterface elanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(interfaceName);
+        if (elanInterface == null) {
+            rpcResultBuilder = RpcResultBuilder.failed();
+            return getFutureWithAppErrorMessage(rpcResultBuilder, String.format("Interface %s is not a ELAN interface", interfaceName));
+        }
+        String elanInstanceName = elanInterface.getElanInstanceName();
+        ElanInstance elanInfo = ElanUtils.getElanInstanceByName(elanInstanceName);
+        long elanTag = elanInfo.getElanTag();
+        InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+        ServicesInfo serviceInfo = ElanUtils.getServiceInfo(elanInstanceName, elanTag, interfaceName);
+        //FIXME [ELANBE] Get this API Later
+        short tableId = 0;
+//        try {
+//
+//            //tableId = interfaceManager.getTableIdForService(interfaceName, serviceInfo);
+//        } catch (InterfaceNotFoundException | InterfaceServiceNotFoundException e) {
+//            rpcResultBuilder = RpcResultBuilder.failed();
+//            return getFutureWithAppErrorMessage(rpcResultBuilder, String.format("Interface %s or Service %s doesn't exist", interfaceName, serviceInfo));
+//        }
+        if (!interfaceInfo.isOperational()) {
+            logger.debug("interface {} is down and returning with no statistics", interfaceName);
+            rpcResultBuilder = RpcResultBuilder.success();
+            return Futures.immediateFuture(rpcResultBuilder.withResult(new GetElanInterfaceStatisticsOutputBuilder().setStatResult(new StatResultBuilder()
+            .setStatResultCode(ResultCode.NotFound).setByteRxCount(0L).setByteTxCount(0L).setPacketRxCount(0L)
+            .setPacketTxCount(0L).build()).build()).build());
+        }
+        rpcResultBuilder = RpcResultBuilder.success();
+        return Futures.immediateFuture(rpcResultBuilder.withResult(queryforElanInterfaceStatistics(tableId, elanInstanceName, interfaceInfo)).build());
+    }
+
+    private GetElanInterfaceStatisticsOutput queryforElanInterfaceStatistics(short tableId, String elanInstanceName, InterfaceInfo interfaceInfo) {
+        BigInteger dpId = interfaceInfo.getDpId();
+        List<MatchInfo> matches = null;
+        String interfaceName = interfaceInfo.getInterfaceName();
+        if (tableId == IfmConstants.VLAN_INTERFACE_INGRESS_TABLE) {
+            VlanInterfaceInfo vlanInterfaceInfo = (VlanInterfaceInfo)interfaceInfo;
+            matches = InterfaceServiceUtil.getMatchInfoForVlanLPort(dpId, interfaceInfo.getPortNo(),
+                    InterfaceServiceUtil.getVlanId(interfaceName, dataBroker), vlanInterfaceInfo.isVlanTransparent());
+        } else {
+            matches = InterfaceServiceUtil.getLPortDispatcherMatches(ElanConstants.ELAN_SERVICE_INDEX, interfaceInfo.getInterfaceTag());
+        }
+        long groupId = interfaceInfo.getGroupId();
+        Set<Object> statRequestKeys = InterfaceServiceUtil.getStatRequestKeys(dpId, tableId, matches, String.format("%s.%s", elanInstanceName, interfaceName), groupId);
+       // StatisticsInfo statsInfo = new StatisticsInfo(statRequestKeys);
+//        org.opendaylight.vpnservice.ericsson.mdsalutil.statistics.StatResult statResult = mdsalMgr.queryForStatistics(interfaceName, statsInfo);
+//        ResultCode resultCode = ResultCode.Success;
+//        if (!statResult.isComplete()) {
+//            resultCode = ResultCode.Incomplete;
+//        }
+
+        //StatValue ingressFlowStats = statResult.getStatResult(InterfaceServiceUtil.getFlowStatisticsKey(dpId, tableId, matches, elanInstanceName));
+        //StatValue groupStats = statResult.getStatResult(InterfaceServiceUtil.getGroupStatisticsKey(dpId, groupId));
+//        return new GetElanInterfaceStatisticsOutputBuilder().setStatResult(new StatResultBuilder().setStatResultCode(resultCode)
+//                .setByteRxCount(ingressFlowStats.getByteCount()).setPacketRxCount(ingressFlowStats.getPacketCount())
+//                .setByteTxCount(groupStats.getByteCount()).setPacketTxCount(groupStats.getPacketCount()).build()).build();
+        return null;
+    }
+
+    private Future<RpcResult<GetElanInterfaceStatisticsOutput>> getFutureWithAppErrorMessage(
+            RpcResultBuilder<GetElanInterfaceStatisticsOutput> rpcResultBuilder, String message) {
+        rpcResultBuilder.withError(ErrorType.APPLICATION, message);
+        return Futures.immediateFuture(rpcResultBuilder.build());
+    }
+
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/utils/ElanCLIUtils.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/utils/ElanCLIUtils.java
new file mode 100644 (file)
index 0000000..0add303
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.utils;
+
+public class ElanCLIUtils {
+    public static final String HEADER_UNDERLINE = "----------------------------------------------------------------------------------------------";
+    public static final String MAC_TABLE_CLI_FORMAT = "%-35s %-20s %-20s %-20s";
+    public static final String ELAN_CLI_FORMAT = "%-35s %-20s %-20s ";
+    public static final String ELAN_INTERFACE_CLI_FORMAT = "%-35s %-25s %-15s %-15s ";
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/utils/ElanConstants.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/utils/ElanConstants.java
new file mode 100755 (executable)
index 0000000..a4afd5b
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.utils;
+
+import java.math.BigInteger;
+
+public class ElanConstants {
+
+    public static final String ELAN_ID_POOL_NAME = "elan.ids.pool";
+    public static final long ELAN_ID_LOW_VALUE = 5000L;
+    public static final long ELAN_ID_HIGH_VALUE = 10000L;
+    public static final int ELAN_GID_MIN = 200000;
+    public static final short ELAN_SMAC_TABLE = 50;
+    public static final short ELAN_DMAC_TABLE = 51;
+    public static final short ELAN_UNKNOWN_DMAC_TABLE = 52;
+    public static final short ELAN_SERVICE_INDEX = 3;
+    public static final int ELAN_SERVICE_PRIORITY = 5;
+    public static final int STATIC_MAC_TIMEOUT = 0;
+    public static final long DELAY_TIME_IN_MILLISECOND = 10000;
+    public static final BigInteger INVALID_DPN = BigInteger.valueOf(-1);
+    public static final BigInteger COOKIE_ELAN_UNKNOWN_DMAC = new BigInteger("8700000", 16);
+    public static final BigInteger COOKIE_ELAN_KNOWN_SMAC = new BigInteger("8050000", 16);
+    public static final BigInteger COOKIE_ELAN_KNOWN_DMAC = new BigInteger("8030000", 16);
+    public static final BigInteger COOKIE_ELAN_INGRESS_TABLE = new BigInteger("8040000", 16);
+       public static final long DEFAULT_MAC_TIME_OUT = 30;
+    public static final short ELAN_FILTER_EQUALS_TABLE = 55;
+    public static final BigInteger COOKIE_ELAN_FILTER_EQUALS = new BigInteger("8800000", 16);
+
+
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/utils/ElanUtils.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/vpnservice/elan/utils/ElanUtils.java
new file mode 100644 (file)
index 0000000..0ffbf63
--- /dev/null
@@ -0,0 +1,795 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.elan.utils;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.elan.internal.ElanInstanceManager;
+import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.vpnservice.elan.internal.ElanServiceProvider;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceServiceUtil;
+import org.opendaylight.vpnservice.itm.api.IITMProvider;
+import org.opendaylight.vpnservice.mdsalutil.*;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+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.action.types.rev131112.action.action.OutputActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
+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.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+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._interface.service.rev150602._interface.service.info.ServiceInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMacKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstanceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.interfaces.ElanInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.Elan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.state.ElanKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.tag.name.map.ElanTagName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.tag.name.map.ElanTagNameBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.tag.name.map.ElanTagNameKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.*;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfIndexesInterfaceMap;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331._if.indexes._interface.map.IfIndexInterface;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331._if.indexes._interface.map.IfIndexInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceOutput;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007.IfIndexesInterfaceMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._if.indexes._interface.map.IfIndexInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.meta.rev151007._if.indexes._interface.map.IfIndexInterfaceKey;
+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.ServiceBindings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.ServiceTypeFlowBased;
+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.StypeOpenflowBuilder;
+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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServicesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServicesKey;
+
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+public class ElanUtils {
+
+    private static ElanServiceProvider elanServiceProvider;
+    private static final Logger logger = LoggerFactory.getLogger(ElanUtils.class);
+
+    public static final FutureCallback<Void> DEFAULT_CALLBACK =
+            new FutureCallback<Void>() {
+                public void onSuccess(Void result) {
+                    logger.debug("Success in Datastore operation");
+                }
+
+                public void onFailure(Throwable error) {
+                    logger.error("Error in Datastore operation", error);
+                };
+            };
+
+    public static Integer getUniqueId(IdManagerService idManager, String poolName, String idKey) {
+        AllocateIdInput getIdInput = new AllocateIdInputBuilder()
+                                           .setPoolName(poolName)
+                                           .setIdKey(idKey).build();
+
+        try {
+            Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
+            RpcResult<AllocateIdOutput> rpcResult = result.get();
+            if(rpcResult.isSuccessful()) {
+                return rpcResult.getResult().getIdValue().intValue();
+            } else {
+                logger.warn("RPC Call to Allocate Id returned with Errors {}", rpcResult.getErrors());
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            logger.warn("Exception when Allocating Id",e);
+        }
+        return 0;
+    }
+
+    public static void setElanServiceProvider(ElanServiceProvider elanService) {
+        elanServiceProvider = elanService;
+    }
+    public static void releaseId(IdManagerService idManager, String poolName, String idKey) {
+        ReleaseIdInput releaseIdInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
+        Future<RpcResult<Void>> result = idManager.releaseId(releaseIdInput);
+    }
+
+    public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
+            InstanceIdentifier<T> path) {
+
+        ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
+
+        Optional<T> result = Optional.absent();
+        try {
+            result = tx.read(datastoreType, path).get();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        return result;
+    }
+
+
+    public static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.delete(datastoreType, path);
+        Futures.addCallback(tx.submit(), DEFAULT_CALLBACK);
+    }
+
+    public static InstanceIdentifier<ElanInstance> getElanInstanceIdentifier(String elanName) {
+        return InstanceIdentifier.builder(ElanInstances.class)
+                .child(ElanInstance.class, new ElanInstanceKey(elanName)).build();
+    }
+
+    public static InstanceIdentifier<ElanInstance> getElanInstanceIdentifier() {
+        return InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class).build();
+    }
+
+    //elan-instances config container
+    public static ElanInstance getElanInstanceByName(String elanInstanceName) {
+        DataBroker broker = elanServiceProvider.getBroker();
+        InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
+        Optional<ElanInstance> elanInstance = read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId);
+        if(elanInstance.isPresent()) {
+            return elanInstance.get();
+        }
+        return null;
+    }
+
+    public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
+        return InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
+    }
+
+    //elan-interfaces Config Container
+    public static ElanInterface getElanInterfaceByElanInterfaceName(String elanInterfaceName) {
+        DataBroker broker = elanServiceProvider.getBroker();
+        InstanceIdentifier<ElanInterface> elanInterfaceId = getElanInterfaceConfigurationDataPathId(elanInterfaceName);
+        Optional<ElanInterface> existingElanInterface = read(broker, LogicalDatastoreType.CONFIGURATION, elanInterfaceId);
+        if(existingElanInterface.isPresent()) {
+            return existingElanInterface.get();
+        }
+        return null;
+    }
+
+    public static class RegMatch {
+
+        final Class<? extends NxmNxReg> reg;
+        final Long value;
+
+        public RegMatch(Class<? extends NxmNxReg> reg, Long value) {
+            super();
+            this.reg = reg;
+            this.value = value;
+        }
+
+        public static RegMatch of(Class<? extends NxmNxReg> reg, Long value) {
+            return new RegMatch(reg, value);
+        }
+    }
+
+    public static void addNxRegMatch(MatchBuilder match, RegMatch... matches) {
+        ArrayList<ExtensionList> extensions = new ArrayList<>();
+        for (RegMatch rm : matches) {
+            Class<? extends ExtensionKey> key;
+            if (NxmNxReg0.class.equals(rm.reg)) {
+                key = NxmNxReg0Key.class;
+            } else if (NxmNxReg1.class.equals(rm.reg)) {
+                key = NxmNxReg1Key.class;
+            } else if (NxmNxReg2.class.equals(rm.reg)) {
+                key = NxmNxReg2Key.class;
+            } else if (NxmNxReg3.class.equals(rm.reg)) {
+                key = NxmNxReg3Key.class;
+            } else if (NxmNxReg4.class.equals(rm.reg)) {
+                key = NxmNxReg4Key.class;
+            } else if (NxmNxReg5.class.equals(rm.reg)) {
+                key = NxmNxReg5Key.class;
+            } else if (NxmNxReg6.class.equals(rm.reg)) {
+                key = NxmNxReg6Key.class;
+            } else {
+                key = NxmNxReg7Key.class;
+            }
+            NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder().setNxmNxReg(
+                    new NxmNxRegBuilder().setReg(rm.reg).setValue(rm.value).build()).build();
+            extensions.add(new ExtensionListBuilder().setExtensionKey(key)
+                    .setExtension(new ExtensionBuilder().addAugmentation(NxAugMatchNodesNodeTableFlow.class, am).build())
+                    .build());
+        }
+        GeneralAugMatchNodesNodeTableFlow m = new GeneralAugMatchNodesNodeTableFlowBuilder().setExtensionList(
+                extensions).build();
+        match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
+    }
+
+    public static InstanceIdentifier<ElanInterface> getElanInterfaceConfigurationDataPathId(String interfaceName) {
+        return InstanceIdentifier.builder(ElanInterfaces.class).child(ElanInterface.class,
+                new ElanInterfaceKey(interfaceName)).build();
+    }
+
+    //elan-state Operational container
+    public static Elan getElanByName(String elanInstanceName) {
+        DataBroker broker = elanServiceProvider.getBroker();
+        InstanceIdentifier<Elan> elanIdentifier = getElanInstanceOperationalDataPath(elanInstanceName);
+        Optional<Elan> elanInstance = read(broker, LogicalDatastoreType.OPERATIONAL, elanIdentifier);
+        if(elanInstance.isPresent()) {
+            return elanInstance.get();
+        }
+        return null;
+    }
+
+    public static InstanceIdentifier<Elan> getElanInstanceOperationalDataPath(String elanInstanceName) {
+        return InstanceIdentifier.builder(ElanState.class).child(Elan.class, new ElanKey(elanInstanceName)).build();
+    }
+
+    // grouping of forwarding-entries
+    public static MacEntry getInterfaceMacEntriesOperationalDataPath(String interfaceName, PhysAddress physAddress) {
+        DataBroker broker = elanServiceProvider.getBroker();
+        InstanceIdentifier<MacEntry> existingMacEntryId = getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
+        Optional<MacEntry> existingInterfaceMacEntry = read(broker, LogicalDatastoreType.OPERATIONAL, existingMacEntryId);
+        if(existingInterfaceMacEntry.isPresent()) {
+            return existingInterfaceMacEntry.get();
+        }
+        return null;
+    }
+
+    public static MacEntry getInterfaceMacEntriesOperationalDataPathFromId(InstanceIdentifier identifier) {
+        DataBroker broker = elanServiceProvider.getBroker();
+        Optional<MacEntry> existingInterfaceMacEntry = read(broker, LogicalDatastoreType.OPERATIONAL, identifier);
+        if(existingInterfaceMacEntry.isPresent()) {
+            return existingInterfaceMacEntry.get();
+        }
+        return null;
+    }
+
+    public static InstanceIdentifier<MacEntry> getInterfaceMacEntriesIdentifierOperationalDataPath(String interfaceName, PhysAddress physAddress) {
+        return InstanceIdentifier.builder(ElanInterfaceForwardingEntries.class).child(ElanInterfaceMac.class,
+                new ElanInterfaceMacKey(interfaceName)).child(MacEntry.class, new MacEntryKey(physAddress)).build();
+
+    }
+
+    //elan-forwarding-tables Operational container
+    public static MacEntry getMacTableByElanName(String elanName, PhysAddress physAddress) {
+        DataBroker broker = elanServiceProvider.getBroker();
+        InstanceIdentifier<MacEntry> macId =  getMacEntryOperationalDataPath(elanName, physAddress);
+        Optional<MacEntry> existingElanMacEntry = read(broker, LogicalDatastoreType.OPERATIONAL, macId);
+        if(existingElanMacEntry.isPresent()) {
+            return existingElanMacEntry.get();
+        }
+        return null;
+    }
+
+
+    public static MacEntry getMacEntryFromElanMacId(InstanceIdentifier identifier) {
+        DataBroker broker = elanServiceProvider.getBroker();
+        Optional<MacEntry> existingInterfaceMacEntry = read(broker, LogicalDatastoreType.OPERATIONAL, identifier);
+        if(existingInterfaceMacEntry.isPresent()) {
+            return existingInterfaceMacEntry.get();
+        }
+        return null;
+    }
+
+    public static InstanceIdentifier<MacEntry> getMacEntryOperationalDataPath(String elanName, PhysAddress physAddress) {
+        return InstanceIdentifier.builder(ElanForwardingTables.class).child(MacTable.class,
+                new MacTableKey(elanName)).child(MacEntry.class, new MacEntryKey(physAddress)).build();
+    }
+
+    public static InstanceIdentifier<MacTable> getElanMacTableOperationalDataPath(String elanName) {
+        return InstanceIdentifier.builder(ElanForwardingTables.class).child(MacTable.class,
+                new MacTableKey(elanName)).build();
+    }
+
+    //elan-interface-forwarding-entries Operational container
+    public static ElanInterfaceMac getElanInterfaceMacByInterfaceName(String interfaceName) {
+        DataBroker broker = elanServiceProvider.getBroker();
+        InstanceIdentifier<ElanInterfaceMac> elanInterfaceId = getElanInterfaceMacEntriesOperationalDataPath(interfaceName);
+        Optional<ElanInterfaceMac> existingElanInterface = read(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
+        if(existingElanInterface.isPresent()) {
+            return existingElanInterface.get();
+        }
+        return null;
+    }
+
+    public static InstanceIdentifier<ElanInterfaceMac> getElanInterfaceMacEntriesOperationalDataPath(String interfaceName) {
+        return InstanceIdentifier.builder(ElanInterfaceForwardingEntries.class).child(ElanInterfaceMac.class,
+                new ElanInterfaceMacKey(interfaceName)).build();
+    }
+
+    //elan-dpn-interfaces Operational Container
+    public static DpnInterfaces getElanInterfaceInfoByElanDpn(String elanInstanceName, BigInteger dpId) {
+        DataBroker broker = elanServiceProvider.getBroker();
+        InstanceIdentifier<DpnInterfaces> elanDpnInterfacesId = getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
+        Optional<DpnInterfaces> elanDpnInterfaces = read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInterfacesId);
+        if(elanDpnInterfaces.isPresent()) {
+            return elanDpnInterfaces.get();
+        }
+        return null;
+    }
+
+    public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName, BigInteger dpId) {
+        return InstanceIdentifier.builder(ElanDpnInterfaces.class).child(ElanDpnInterfacesList.class,
+                new ElanDpnInterfacesListKey(elanInstanceName)).child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
+    }
+
+    //elan-tag-name-map Operational Container
+    public static ElanTagName getElanInfoByElanTag(long elanTag) {
+        DataBroker broker = elanServiceProvider.getBroker();
+        InstanceIdentifier<ElanTagName> elanId = getElanInfoEntriesOperationalDataPath(elanTag);
+        Optional<ElanTagName> existingElanInfo = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanId);
+        if(existingElanInfo.isPresent()) {
+            return existingElanInfo.get();
+        }
+        return null;
+    }
+
+    public static InstanceIdentifier<ElanTagName> getElanInfoEntriesOperationalDataPath(long elanTag) {
+        return InstanceIdentifier.builder(ElanTagNameMap.class).child(ElanTagName.class,
+                new ElanTagNameKey(elanTag)).build();
+    }
+
+    // interface-index-tag operational container
+    public static IfIndexInterface getInterfaceInfoByInterfaceTag(long interfaceTag) {
+        DataBroker broker = elanServiceProvider.getBroker();
+        InstanceIdentifier<IfIndexInterface> interfaceId = getInterfaceInfoEntriesOperationalDataPath(interfaceTag);
+        Optional<IfIndexInterface> existingInterfaceInfo = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, interfaceId);
+        if(existingInterfaceInfo.isPresent()) {
+            return existingInterfaceInfo.get();
+        }
+        return null;
+    }
+
+    public static InstanceIdentifier<IfIndexInterface> getInterfaceInfoEntriesOperationalDataPath(long interfaceTag) {
+        return InstanceIdentifier.builder(IfIndexesInterfaceMap.class).child(IfIndexInterface.class,
+                new IfIndexInterfaceKey((int) interfaceTag)).build();
+    }
+
+
+
+    public static InstanceIdentifier<ElanDpnInterfacesList> getElanDpnOperationDataPath(String elanInstanceName) {
+        return InstanceIdentifier.builder(ElanDpnInterfaces.class).child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName)).build();
+    }
+
+    public static  ElanDpnInterfacesList getElanDpnInterfacesList(String elanName) {
+        DataBroker broker = elanServiceProvider.getBroker();
+        InstanceIdentifier<ElanDpnInterfacesList> elanDpnInterfaceId = getElanDpnOperationDataPath(elanName);
+        Optional<ElanDpnInterfacesList> existingElanDpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
+        if(existingElanDpnInterfaces.isPresent()) {
+            return existingElanDpnInterfaces.get();
+        }
+        return null;
+    }
+
+    public static  ElanDpnInterfaces getElanDpnInterfacesList() {
+        DataBroker broker = elanServiceProvider.getBroker();
+        InstanceIdentifier<ElanDpnInterfaces> elanDpnInterfaceId = InstanceIdentifier.builder(ElanDpnInterfaces.class).build();
+        Optional<ElanDpnInterfaces> existingElanDpnInterfaces = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
+        if(existingElanDpnInterfaces.isPresent()) {
+            return existingElanDpnInterfaces.get();
+        }
+        return null;
+    }
+
+    public static ElanForwardingTables getElanForwardingList() {
+        DataBroker broker = elanServiceProvider.getBroker();
+        InstanceIdentifier<ElanForwardingTables> elanForwardingTableId = InstanceIdentifier.builder(ElanForwardingTables.class).build();
+        Optional<ElanForwardingTables> existingElanForwardingList = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL, elanForwardingTableId);
+        if(existingElanForwardingList.isPresent()) {
+            return existingElanForwardingList.get();
+        }
+        return null;
+    }
+
+
+    public static long getElanLocalBCGID(long elanTag) {
+        return ElanConstants.ELAN_GID_MIN + (((elanTag % ElanConstants.ELAN_GID_MIN) *2) - 1);
+    }
+
+    public static long getElanRemoteBCGID(long elanTag) {
+        return ElanConstants.ELAN_GID_MIN + (((elanTag % ElanConstants.ELAN_GID_MIN) *2));
+    }
+
+    public static BigInteger getElanMetadataLabel(long elanTag) {
+        return (BigInteger.valueOf(elanTag)).shiftLeft(24);
+    }
+
+    public static BigInteger getElanMetadataLabel(long elanTag, int lportTag) {
+        return getElanMetadataLabel(elanTag).or(MetaDataUtil.getLportTagMetaData(lportTag));
+    }
+
+    public static BigInteger getElanMetadataMask() {
+        return MetaDataUtil.METADATA_MASK_SERVICE.or(MetaDataUtil.METADATA_MASK_LPORT_TAG);
+    }
+
+    public static void setupMacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo, long macTimeout,
+                                     String macAddress) {
+        IMdsalApiManager mdsalApiManager = elanServiceProvider.getMdsalManager();
+        DataBroker broker = elanServiceProvider.getBroker();
+        IITMProvider itmManager = elanServiceProvider.getItmManager();
+        synchronized (macAddress) {
+            logger.info("Acquired lock for mac : " + macAddress + "Proceeding with install operation.");
+            setupKnownSmacFlow(elanInfo, interfaceInfo, macTimeout, macAddress, mdsalApiManager);
+            setupTermDmacFlows(interfaceInfo, itmManager);
+            setupOrigDmacFlows(elanInfo, interfaceInfo, macAddress, mdsalApiManager, broker);
+        }
+    }
+
+    public static void setupDMacFlowonRemoteDpn(ElanInstance elanInfo, InterfaceInfo interfaceInfo, BigInteger dstDpId,
+                                     String macAddress) {
+        synchronized (macAddress) {
+            logger.info("Acquired lock for mac : " + macAddress + "Proceeding with install operation.");
+            setupOrigDmacFlowsonRemoteDpn(elanInfo, interfaceInfo, dstDpId, macAddress);
+        }
+    }
+
+
+    private static void setupKnownSmacFlow(ElanInstance elanInfo, InterfaceInfo interfaceInfo, long macTimeout,
+                                           String macAddress, IMdsalApiManager mdsalApiManager) {
+        FlowEntity flowEntity = getKnownSmacFlowEntity(elanInfo, interfaceInfo, macTimeout, macAddress);
+        mdsalApiManager.installFlow(flowEntity);
+        if (logger.isDebugEnabled()) {
+            logger.debug("Known Smac flow entry created for elan Name:{}, logical Interface port:{} and mac address:{}", elanInfo.getElanInstanceName(), elanInfo.getDescription(), macAddress);
+        }
+    }
+
+    private static FlowEntity getKnownSmacFlowEntity(ElanInstance elanInfo, InterfaceInfo interfaceInfo, long macTimeout, String macAddress) {
+        BigInteger dpId = interfaceInfo.getDpId();
+        int lportTag = interfaceInfo.getInterfaceTag();
+        long elanTag = elanInfo.getElanTag();
+        // Matching metadata and eth_src fields
+        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
+                ElanUtils.getElanMetadataLabel(elanInfo.getElanTag(), lportTag),
+                ElanUtils.getElanMetadataMask() }));
+        mkMatches.add(new MatchInfo(MatchFieldType.eth_src, new String[] { macAddress }));
+        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+        mkInstructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { ElanConstants.ELAN_DMAC_TABLE }));
+
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, ElanConstants.ELAN_SMAC_TABLE,
+                getKnownDynamicmacFlowRef(ElanConstants.ELAN_SMAC_TABLE, dpId, lportTag, macAddress, elanTag),
+                20, elanInfo.getDescription(), (int)macTimeout, 0, ElanConstants.COOKIE_ELAN_KNOWN_SMAC.add(BigInteger.valueOf(elanTag)),
+                mkMatches, mkInstructions);
+        flowEntity.setStrictFlag(true);
+        flowEntity.setSendFlowRemFlag(macTimeout != 0); //If Mac timeout is 0, the flow wont be deleted automatically, so no need to get notified
+        return flowEntity;
+    }
+
+    private static void setupTermDmacFlows(InterfaceInfo interfaceInfo, IITMProvider itmManager) {
+        BigInteger dpId = interfaceInfo.getDpId();
+        long lportGroupId = interfaceInfo.getGroupId();
+        int lportTag = interfaceInfo.getInterfaceTag();
+        List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
+        actionsInfos = getEgressActionsForInterface(interfaceInfo.getInterfaceName());
+
+        //FIXME [ELANBE] ITM Service API to invoke Terminating Service
+        //itmManager.createTerminatingServiceActions(dpId, lportTag, actionsInfos);
+        if (logger.isDebugEnabled()) {
+            logger.debug("Terminating service table flow entry created on dpn:{} for logical Interface port:{}", dpId, interfaceInfo.getPortName());
+        }
+    }
+
+    public static List<ActionInfo> getEgressActionsForInterface(String ifName) {
+        List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
+        try {
+            Future<RpcResult<GetEgressActionsForInterfaceOutput>> result =
+                    elanServiceProvider.getInterfaceManagerRpcService().getEgressActionsForInterface(
+                            new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName).build());
+            RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
+            System.out.println("Data is populated");
+            if(!rpcResult.isSuccessful()) {
+                logger.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName, rpcResult.getErrors());
+            } else {
+                List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions =
+                        rpcResult.getResult().getAction();
+                for (Action action : actions) {
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action.getAction();
+                    if (actionClass instanceof OutputActionCase) {
+                        System.out.println("Data ");
+                        listActionInfo.add(new ActionInfo(ActionType.output,
+                                new String[] {((OutputActionCase)actionClass).getOutputAction()
+                                        .getOutputNodeConnector().getValue()}));
+                    } else if (actionClass instanceof PushVlanActionCase) {
+                        listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
+                    } else if (actionClass instanceof SetFieldCase) {
+                        if (((SetFieldCase)actionClass).getSetField().getVlanMatch() != null) {
+                            int vlanVid = ((SetFieldCase)actionClass).getSetField().getVlanMatch().getVlanId().getVlanId().getValue();
+                            listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
+                                    new String[] { Long.toString(vlanVid) }));
+                        }
+                    }
+                }
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            logger.warn("Exception when egress actions for interface {}", ifName, e);
+        }
+        return listActionInfo;
+    }
+
+    private static void setupOrigDmacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo, String macAddress,
+                                           IMdsalApiManager mdsalApiManager, DataBroker broker) {
+        BigInteger dpId = interfaceInfo.getDpId();
+        String ifName = interfaceInfo.getInterfaceName();
+        long ifTag = interfaceInfo.getInterfaceTag();
+        long groupId = interfaceInfo.getGroupId();
+        String elanInstanceName = elanInfo.getElanInstanceName();
+        List<DpnInterfaces> remoteFEs = getInvolvedDpnsInElan(elanInstanceName);
+        if(remoteFEs != null) {
+            for (DpnInterfaces remoteFE : remoteFEs) {
+                Long elanTag = elanInfo.getElanTag();
+                if (remoteFE.getDpId().equals(dpId)) {
+                    // On the local FE set up a direct output flow
+                    setupLocalDmacFlow(elanTag, dpId, ifName, macAddress, elanInstanceName, mdsalApiManager, ifTag);
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("Dmac flow entry created for elan Name:{}, logical port Name:{} and mac address:{} on dpn:{}", elanInstanceName, interfaceInfo.getPortName(), macAddress, dpId);
+                    }
+                } else {
+                    if (isDpnPresent(remoteFE.getDpId())) {
+                        // Check for the Remote DPN present in Inventory Manager
+                        setupRemoteDmacFlow(remoteFE.getDpId(), dpId, interfaceInfo.getInterfaceTag(), elanTag, macAddress, elanInstanceName);
+                        if (logger.isDebugEnabled()) {
+                            logger.debug("Dmac flow entry created for elan Name:{}, logical port Name:{} and mac address:{} on dpn:{}", elanInstanceName, interfaceInfo.getPortName(), macAddress, remoteFE.getDpId());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private static void setupOrigDmacFlowsonRemoteDpn(ElanInstance elanInfo, InterfaceInfo interfaceInfo, BigInteger dstDpId, String macAddress) {
+        BigInteger dpId = interfaceInfo.getDpId();
+        String elanInstanceName = elanInfo.getElanInstanceName();
+        List<DpnInterfaces> remoteFEs = getInvolvedDpnsInElan(elanInstanceName);
+        for(DpnInterfaces remoteFE: remoteFEs) {
+            Long elanTag = elanInfo.getElanTag();
+            if (remoteFE.getDpId().equals(dstDpId)) {
+                // Check for the Remote DPN present in Inventory Manager
+                setupRemoteDmacFlow(dstDpId, dpId, interfaceInfo.getInterfaceTag(), elanTag, macAddress, elanInstanceName);
+                if (logger.isDebugEnabled()) {
+                    logger.debug("Dmac flow entry created for elan Name:{}, logical port Name:{} and mac address {} on dpn:{}", elanInstanceName, interfaceInfo.getPortName(), macAddress, remoteFE.getDpId());
+                }
+                break;
+            }
+        }
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static List<DpnInterfaces> getInvolvedDpnsInElan(String elanName) {
+        List<DpnInterfaces> dpns = ElanInstanceManager.getElanInstanceManager().getElanDPNByName(elanName);
+        return dpns;
+    }
+
+    private static void setupLocalDmacFlow(long elanTag, BigInteger dpId, String ifName, String macAddress,
+                                           String displayName, IMdsalApiManager mdsalApiManager, long ifTag) {
+        FlowEntity flowEntity = getLocalDmacFlowEntry(elanTag, dpId, ifName, macAddress, displayName, ifTag);
+        mdsalApiManager.installFlow(flowEntity);
+
+    }
+
+    public static String getKnownDynamicmacFlowRef(short tableId, BigInteger dpId, long lporTag, String macAddress, long elanTag) {
+        return new StringBuffer().append(tableId).append(elanTag).append(dpId).append(lporTag).append(macAddress).toString();
+    }
+
+    public static String getKnownDynamicmacFlowRef(short tableId, BigInteger dpId, BigInteger remoteDpId, String macAddress, long elanTag) {
+        return new StringBuffer().append(tableId).append(elanTag).append(dpId).append(remoteDpId).append(macAddress).toString();
+    }
+
+    public static FlowEntity getLocalDmacFlowEntry(long elanTag, BigInteger dpId, String ifName, String macAddress,
+                                                   String displayName, long ifTag) {
+        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
+                ElanUtils.getElanMetadataLabel(elanTag),
+                MetaDataUtil.METADATA_MASK_SERVICE }));
+        mkMatches.add(new MatchInfo(MatchFieldType.eth_dst, new String[] { macAddress }));
+
+        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+        List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
+        actionsInfos.addAll(getEgressActionsForInterface(ifName));
+        mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, ElanConstants.ELAN_DMAC_TABLE,
+                getKnownDynamicmacFlowRef(ElanConstants.ELAN_DMAC_TABLE, dpId, ifTag, macAddress, elanTag),
+                20, displayName, 0, 0, ElanConstants.COOKIE_ELAN_KNOWN_DMAC.add(BigInteger.valueOf(elanTag)),
+                mkMatches, mkInstructions);
+        return flowEntity;
+    }
+
+    public static void setupRemoteDmacFlow(BigInteger srcDpId, BigInteger destDpId, int lportTag, long elanTag, String macAddress,
+                                           String displayName) {
+        IMdsalApiManager mdsalApiManager = elanServiceProvider.getMdsalManager();
+        FlowEntity flowEntity = getRemoteDmacFlowEntry(srcDpId, destDpId, lportTag, elanTag, macAddress, displayName);
+        mdsalApiManager.installFlow(flowEntity);
+    }
+
+    public static FlowEntity getRemoteDmacFlowEntry(BigInteger srcDpId, BigInteger destDpId, int lportTag, long elanTag,
+                                                    String macAddress, String displayName) {
+        IITMProvider itmManager = elanServiceProvider.getItmManager();
+        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[]{
+                ElanUtils.getElanMetadataLabel(elanTag),
+                MetaDataUtil.METADATA_MASK_SERVICE }));
+        mkMatches.add(new MatchInfo(MatchFieldType.eth_dst, new String[] { macAddress }));
+
+        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+        //List of ActionInfo for the provided Source and Destination DPIDs
+        try {
+            //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
+            //List<ActionInfo> actionsInfos = itmManager.ITMIngressGetActions(srcDpId, destDpId, lportTag);
+            //mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+        } catch (Exception e) {
+            logger.error("Interface Not Found exception");
+        }
+
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(srcDpId, ElanConstants.ELAN_DMAC_TABLE,
+                getKnownDynamicmacFlowRef(ElanConstants.ELAN_DMAC_TABLE, srcDpId, destDpId, macAddress, elanTag),
+                20, displayName, 0, 0, ElanConstants.COOKIE_ELAN_KNOWN_DMAC.add(BigInteger.valueOf(elanTag)),
+                mkMatches, mkInstructions);
+        return flowEntity;
+    }
+
+    public static void deleteMacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo, MacEntry macEntry) {
+        if (elanInfo == null || interfaceInfo == null) {
+            return;
+        }
+        String macAddress = macEntry.getMacAddress().getValue();
+        synchronized (macAddress) {
+            logger.info("Acquired lock for mac : " + macAddress + "Proceeding with remove operation.");
+            deleteMacFlows(elanInfo, interfaceInfo,  macAddress, true);
+        }
+    }
+
+    public static void deleteMacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo, String macAddress, boolean deleteSmac) {
+        String elanInstanceName = elanInfo.getElanInstanceName();
+        String ifName = interfaceInfo.getInterfaceName();
+        long ifTag = interfaceInfo.getInterfaceTag();
+        List<DpnInterfaces> remoteFEs = getInvolvedDpnsInElan(elanInstanceName);
+        IMdsalApiManager mdsalApiManager = elanServiceProvider.getMdsalManager();
+        IITMProvider itmManager = elanServiceProvider.getItmManager();
+        BigInteger srcdpId = interfaceInfo.getDpId();
+        String displayName = elanInstanceName;
+        long groupId = interfaceInfo.getGroupId();
+        for (DpnInterfaces dpnInterface: remoteFEs) {
+            Long elanTag = elanInfo.getElanTag();
+            if (dpnInterface.getDpId().equals(srcdpId)) {
+                if(deleteSmac) {
+                    mdsalApiManager.removeFlow(getKnownSmacFlowEntity(elanInfo, interfaceInfo, 0, macAddress));
+                }
+                mdsalApiManager.removeFlow(getLocalDmacFlowEntry(elanTag, dpnInterface.getDpId(), ifName, macAddress, displayName, ifTag));
+
+                //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
+                //itmManager.removeTerminatingServiceAction(dpnInterface.getDpId(), interfaceInfo.getInterfaceTag());
+                  if (logger.isDebugEnabled()) {
+                    logger.debug("All the required flows deleted for elan:{}, logical Interface port:{} and mac address:{} on dpn:{}", elanInstanceName, interfaceInfo.getPortName(), macAddress, dpnInterface.getDpId());
+                }
+            } else if (isDpnPresent(dpnInterface.getDpId())) {
+                mdsalApiManager.removeFlow(
+                        getRemoteDmacFlowEntry(dpnInterface.getDpId(), srcdpId, interfaceInfo.getInterfaceTag(), elanTag, macAddress,
+                                displayName));
+                if (logger.isDebugEnabled()) {
+                    logger.debug("Dmac flow entry deleted for elan:{}, logical interface port:{} and mac address:{} on dpn:{}", elanInstanceName, interfaceInfo.getPortName(), macAddress, dpnInterface.getDpId());
+                }
+            }
+        }
+    }
+
+    public static void UpdateOperationalDataStore(DataBroker broker, IdManagerService idManager, ElanInstance elanInstanceAdded) {
+        String elanInstanceName = elanInstanceAdded.getElanInstanceName();
+        long elanTag = ElanUtils.getUniqueId(idManager, ElanConstants.ELAN_ID_POOL_NAME, elanInstanceName);
+        Elan elanInfo = new ElanBuilder().setName(elanInstanceName).setKey(new ElanKey(elanInstanceName)).build();
+        //Add the ElanState in the elan-state operational data-store
+        MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanInstanceName), elanInfo);
+        //Add the ElanMacTable in the elan-mac-table operational data-store
+        MacTable elanMacTable = new MacTableBuilder().setKey(new MacTableKey(elanInstanceName)).build();
+        MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanMacTableOperationalDataPath(elanInstanceName), elanMacTable);
+        ElanTagName elanTagName = new ElanTagNameBuilder().setElanTag(elanTag).setKey(new ElanTagNameKey(elanTag)).setName(elanInstanceName).build();
+        //Add the ElanTag to ElanName in the elan-tag-name Operational data-store
+        MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInfoEntriesOperationalDataPath(elanTag), elanTagName);
+        ElanInstance elanInstanceWithTag = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName).setDescription(elanInstanceAdded.getDescription()).setMacTimeout(elanInstanceAdded
+                .getMacTimeout() == null ? ElanConstants.DEFAULT_MAC_TIME_OUT : elanInstanceAdded.getMacTimeout()).setKey(elanInstanceAdded.getKey()).setElanTag(elanTag).build();
+        MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, getElanInstanceIdentifier(elanInstanceName), elanInstanceWithTag);
+    }
+
+    public static boolean isDpnPresent(BigInteger dpnId) {
+        DataBroker broker = elanServiceProvider.getBroker();
+        boolean isPresent = false;
+        String dpn = String.format("%s:%s", "openflow",dpnId);
+        NodeId nodeId = new NodeId(dpn);
+        InstanceIdentifier<Node> node = InstanceIdentifier.builder(Nodes.class).child(Node.class, new NodeKey(nodeId)).build();
+        Optional<Node> nodePresent = read(broker, LogicalDatastoreType.OPERATIONAL, node);
+        if(nodePresent.isPresent()) {
+            isPresent = true;
+        }
+        return isPresent;
+    }
+
+    public static ServicesInfo getServiceInfo(String elanInstanceName, long elanTag, String interfaceName) {
+        int priority = ElanConstants.ELAN_SERVICE_PRIORITY;
+        int instructionKey = 0;
+        List<Instruction> instructions = new ArrayList<Instruction>();
+        instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(ElanUtils.getElanMetadataLabel(elanTag), MetaDataUtil.METADATA_MASK_SERVICE, ++instructionKey));
+        instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(ElanConstants.ELAN_SMAC_TABLE, ++instructionKey));
+
+        ServicesInfo serviceInfo = InterfaceServiceUtil.buildServiceInfo(String.format("%s.%s", elanInstanceName, interfaceName), ElanConstants.ELAN_SERVICE_INDEX,
+                priority, ElanConstants.COOKIE_ELAN_INGRESS_TABLE, instructions);
+        return serviceInfo;
+    }
+
+    public static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
+                                              InstanceIdentifier<T> path, FutureCallback<Void> callback) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.delete(datastoreType, path);
+        Futures.addCallback(tx.submit(), callback);
+    }
+
+    public static <T extends DataObject> void syncWrite(DataBroker broker, LogicalDatastoreType datastoreType,
+                                                        InstanceIdentifier<T> path, T data) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.put(datastoreType, path, data, true);
+        CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
+        try {
+            futures.get();
+        } catch (InterruptedException | ExecutionException e) {
+            logger.error("Error writing to datastore (path, data) : ({}, {})", path, data);
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+
+    public static BoundServices getBoundServices(String serviceName, short servicePriority, int flowPriority,
+                                                 BigInteger cookie, List<Instruction> instructions) {
+        StypeOpenflowBuilder augBuilder = new StypeOpenflowBuilder().setFlowCookie(cookie).setFlowPriority(flowPriority).setInstruction(instructions);
+        return new BoundServicesBuilder().setKey(new BoundServicesKey(servicePriority))
+                .setServiceName(serviceName).setServicePriority(servicePriority)
+                .setServiceType(ServiceTypeFlowBased.class).addAugmentation(StypeOpenflow.class, augBuilder.build()).build();
+    }
+
+    public static InstanceIdentifier<BoundServices> buildServiceId(String vpnInterfaceName, short serviceIndex) {
+        return InstanceIdentifier.builder(ServiceBindings.class).child(ServicesInfo.class, new ServicesInfoKey(vpnInterfaceName))
+                .child(BoundServices.class, new BoundServicesKey(serviceIndex)).build();
+    }
+
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/elanservice/impl/rev150216/ElanServiceImplModule.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/elanservice/impl/rev150216/ElanServiceImplModule.java
new file mode 100644 (file)
index 0000000..ed10b25
--- /dev/null
@@ -0,0 +1,37 @@
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.elanservice.impl.rev150216;
+
+import org.opendaylight.vpnservice.elan.internal.ElanServiceProvider;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
+
+public class ElanServiceImplModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.elanservice.impl.rev150216.AbstractElanServiceImplModule {
+    public ElanServiceImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public ElanServiceImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.elanservice.impl.rev150216.ElanServiceImplModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        RpcProviderRegistry rpcregistryDependency = getRpcregistryDependency();
+        IdManagerService idManager = rpcregistryDependency.getRpcService(IdManagerService.class);
+        ElanServiceProvider provider = new ElanServiceProvider(rpcregistryDependency);
+        provider.setNotificationService(getNotificationServiceDependency());
+        provider.setMdsalManager(getMdsalutilDependency());
+        provider.setInterfaceManager(getOdlinterfaceDependency());
+        provider.setInterfaceManagerRpcService(rpcregistryDependency.getRpcService(OdlInterfaceRpcService.class));
+        provider.setItmManager(getItmmanagerDependency());
+        provider.setIdManager(idManager);
+        getBrokerDependency().registerProvider(provider);
+        return provider;
+    }
+
+}
diff --git a/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/elanservice/impl/rev150216/ElanServiceImplModuleFactory.java b/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/elanservice/impl/rev150216/ElanServiceImplModuleFactory.java
new file mode 100644 (file)
index 0000000..618f8c0
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: elanservice-impl yang module local name: elanservice-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Fri Dec 04 18:32:00 IST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.elanservice.impl.rev150216;
+public class ElanServiceImplModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.elanservice.impl.rev150216.AbstractElanServiceImplModuleFactory {
+
+}
diff --git a/elanmanager/elanmanager-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/elanmanager/elanmanager-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644 (file)
index 0000000..20a3ed2
--- /dev/null
@@ -0,0 +1,67 @@
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+    <reference id="elanProviderRef" interface="org.opendaylight.elanmanager.api.IElanService"  availability="optional" />
+    <reference id="interfaceManagerRef" interface="org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager"  availability="optional" />
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.opendaylight.vpnservice.elan.cli.ElanAdd">
+                <property name="elanProvider" ref="elanProviderRef" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.vpnservice.elan.cli.ElanDelete">
+                <property name="elanProvider" ref="elanProviderRef" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.vpnservice.elan.cli.ElanUpdate">
+                <property name="elanProvider" ref="elanProviderRef" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.vpnservice.elan.cli.ElanInterfaceAdd">
+                <property name="elanProvider" ref="elanProviderRef" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.vpnservice.elan.cli.ElanInterfaceDelete">
+                <property name="elanProvider" ref="elanProviderRef" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.vpnservice.elan.cli.ElanInterfaceUpdate">
+                <property name="elanProvider" ref="elanProviderRef" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.vpnservice.elan.cli.StaticMacAdd">
+                <property name="elanProvider" ref="elanProviderRef" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.vpnservice.elan.cli.StaticMacDelete">
+                <property name="elanProvider" ref="elanProviderRef" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.vpnservice.elan.cli.ElanMacTableGet">
+                <property name="elanProvider" ref="elanProviderRef" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.vpnservice.elan.cli.ElanMacTableFlush">
+                <property name="elanProvider" ref="elanProviderRef" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.vpnservice.elan.cli.ElanGet">
+                <property name="elanProvider" ref="elanProviderRef" />
+            </action>
+        </command>
+        <command>
+            <action class="org.opendaylight.vpnservice.elan.cli.ElanInterfaceGet">
+                <property name="elanProvider" ref="elanProviderRef" />
+                <property name="interfaceManager" ref="interfaceManagerRef" />
+            </action>
+        </command>
+    </command-bundle>
+</blueprint>
\ No newline at end of file
diff --git a/elanmanager/elanmanager-impl/src/main/yang/elanservice-impl.yang b/elanmanager/elanmanager-impl/src/main/yang/elanservice-impl.yang
new file mode 100644 (file)
index 0000000..6af446e
--- /dev/null
@@ -0,0 +1,81 @@
+module elanservice-impl {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:elanservice:impl";
+    prefix "elanservice-impl";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
+    import opendaylight-sal-binding-broker-impl { prefix md-sal-binding-impl; revision-date 2013-10-28;}
+    import elanmanager-api { prefix elanmgr-api; revision-date 2015-07-07;}
+    import odl-mdsalutil { prefix odl-mdsal; revision-date 2015-04-10;}
+    import odl-interface {prefix odlif; revision-date 2015-03-31;}
+    import itm {prefix itm; revision-date 2015-07-01;}
+
+    description
+        "Service definition for elanservice project";
+
+    revision "2015-02-16" {
+        description
+            "Initial revision";
+    }
+
+    identity elanservice-impl {
+        base config:module-type;
+        config:provided-service elanmgr-api:elanmanager-api;
+        config:java-name-prefix elanServiceImpl;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case elanservice-impl {
+            when "/config:modules/config:module/config:type = 'elanservice-impl'";
+            container broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity md-sal-binding:binding-broker-osgi-registry;
+                    }
+                }
+            }
+            container rpcregistry {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity md-sal-binding:binding-rpc-registry;
+                    }
+                }
+            }
+            container mdsalutil {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity odl-mdsal:odl-mdsalutil;
+                    }
+                }
+            }
+            container odlinterface {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity odlif:odl-interface;
+                    }
+                }
+            }
+            container itmmanager {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity itm:itm;
+                    }
+                }
+            }
+            container notification-service {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity md-sal-binding-impl:binding-new-notification-service;
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/elanmanager/pom.xml b/elanmanager/pom.xml
new file mode 100644 (file)
index 0000000..a34c56a
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <parent>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odlparent</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>org.opendaylight.vpnservice</groupId>
+  <artifactId>elanmanager</artifactId>
+  <version>0.2.0-SNAPSHOT</version>
+  <name>elanmanager</name>
+  <packaging>pom</packaging>
+  <modelVersion>4.0.0</modelVersion>
+  <prerequisites>
+    <maven>3.1.1</maven>
+  </prerequisites>
+  <modules>
+    <module>elanmanager-api</module>
+    <module>elanmanager-impl</module>
+  </modules>
+  <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-install-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
index 87365a7907435c622ca844a5bd4658ac4d1a5505..a543c2deb5a0530850f693040c36819046096d04 100644 (file)
@@ -34,6 +34,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <mdsalutil.version>${vpnservices.version}</mdsalutil.version>
     <vpnmanager.version>${vpnservices.version}</vpnmanager.version>
     <interfacemgr.version>${vpnservices.version}</interfacemgr.version>
+    <elanmgr.version>${vpnservices.version}</elanmgr.version>
     <nexthopmgr.version>${vpnservices.version}</nexthopmgr.version>
     <fibmanager.version>${vpnservices.version}</fibmanager.version>
     <lockmanager.version>${vpnservices.version}</lockmanager.version>
@@ -185,6 +186,23 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <artifactId>interfacemgr-api</artifactId>
       <version>${interfacemgr.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>elanmanager-impl</artifactId>
+      <version>${elanmgr.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>elanmanager-impl</artifactId>
+      <version>${elanmgr.version}</version>
+      <classifier>config</classifier>
+      <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>elanmanager-api</artifactId>
+      <version>${elanmgr.version}</version>
+    </dependency>
     <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>liblldp</artifactId>
@@ -346,6 +364,14 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <artifactId>libthrift</artifactId>
       <version>0.9.1</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>features-openflowplugin-extension</artifactId>
+      <classifier>features</classifier>
+      <version>${openflowplugin.version}</version>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
     <dependency>
       <groupId>commons-net</groupId>
       <artifactId>commons-net</artifactId>
index 92e6865b56673467c8accefd5fbe563f04f3cc6c..17f531cb0e69ebc7af67801c5dab3d746b588e23 100644 (file)
@@ -14,6 +14,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/${mdsal.model.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin/${openflowplugin.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.openflowplugin/features-openflowplugin-extension/${openflowplugin.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.netconf/features-restconf/${restconf.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.ovsdb/features-ovsdb/${ovsdb.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.neutron/features-neutron/${neutron.version}/xml/features</repository>
@@ -21,6 +22,7 @@ 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="${openflowplugin.version}">odl-openflowplugin-nxm-extensions</feature>
     <feature version="${ovsdb.version}">odl-ovsdb-southbound-impl-rest</feature>
     <bundle>mvn:org.opendaylight.controller/liblldp/${liblldp.version}</bundle>
     <bundle>mvn:org.opendaylight.neutron/model/${neutron.version}</bundle>
@@ -60,6 +62,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <bundle>mvn:org.opendaylight.vpnservice/neutronvpn-impl/${neutronvpn.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/neutronvpn-shell/${neutronvpn.version}</bundle>
     <bundle>mvn:org.opendaylight.vpnservice/dhcpservice-impl/${vpnservices.version}</bundle>
+    <bundle>mvn:org.opendaylight.vpnservice/elanmanager-api/${elanmgr.version}</bundle>
+    <bundle>mvn:org.opendaylight.vpnservice/elanmanager-impl/${elanmgr.version}</bundle>
 
     <!--<bundle>mvn:org.opendaylight.vpnservice.third-party/org.apache.thriftlib/1.0.1-SNAPSHOT</bundle>-->
     <bundle>wrap:mvn:org.apache.thrift/libthrift/0.9.1$overwrite=merge&amp;Bundle-Version=0.9.1&amp;Export-Package=*;-noimport:=true;version="0.9.1"</bundle>
@@ -77,6 +81,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <configfile finalname="itm-impl-default-config.xml">mvn:org.opendaylight.vpnservice/itm-impl/${itm.version}/xml/config</configfile>
     <configfile finalname="neutronvpn-impl-default-config.xml">mvn:org.opendaylight.vpnservice/neutronvpn-impl/${neutronvpn.version}/xml/config</configfile>
     <configfile finalname="dhcpservice-impl-default-config.xml">mvn:org.opendaylight.vpnservice/dhcpservice-impl/${vpnservices.version}/xml/config</configfile>
+    <configfile finalname="elanmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/elanmanager-impl/${elanmgr.version}/xml/config</configfile>
+
   </feature>
   <feature name='odl-vpnservice-impl-rest' version='${project.version}' description='OpenDaylight :: vpnservice :: impl :: REST '>
     <feature version="${project.version}">odl-vpnservice-impl</feature>
diff --git a/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/exceptions/InterfaceAlreadyExistsException.java b/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/exceptions/InterfaceAlreadyExistsException.java
new file mode 100644 (file)
index 0000000..16dda48
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.exceptions;
+
+public class InterfaceAlreadyExistsException extends Exception {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+    
+    public InterfaceAlreadyExistsException() {
+
+    }
+
+    public InterfaceAlreadyExistsException(String message) {
+        super(message);
+    }
+
+}
diff --git a/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/exceptions/InterfaceNotFoundException.java b/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/exceptions/InterfaceNotFoundException.java
new file mode 100644 (file)
index 0000000..ed46212
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.exceptions;
+
+public class InterfaceNotFoundException extends Exception {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+    public InterfaceNotFoundException() {
+
+    }
+
+    public InterfaceNotFoundException(String message) {
+        super(message);
+    }
+
+}
diff --git a/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/exceptions/InterfaceServiceNotFoundException.java b/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/exceptions/InterfaceServiceNotFoundException.java
new file mode 100644 (file)
index 0000000..13cdeb8
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.exceptions;
+
+public class InterfaceServiceNotFoundException extends Exception {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+    public InterfaceServiceNotFoundException() {
+    }
+
+    public InterfaceServiceNotFoundException(String message) {
+        super(message);
+    }
+}
diff --git a/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/IfmConstants.java b/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/IfmConstants.java
new file mode 100644 (file)
index 0000000..85d1afc
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.globals;
+
+import java.math.BigInteger;
+
+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 int FLOW_HIGH_PRIORITY = 10;
+    public static final int FLOW_PRIORITY_FOR_UNTAGGED_VLAN = 4;
+    public static final int FLOW_TABLE_MISS_PRIORITY = 0;
+    public static final int DEFAULT_ARP_FLOW_PRIORITY = 100;
+    public static final int INVALID_PORT_NO = -1;
+    public static final BigInteger INVALID_DPID = new BigInteger("-1");
+    //Id pool
+    public static final String IFM_IDPOOL_NAME = "interfaces";
+    public static final long IFM_ID_POOL_START = 1L;
+    public static final long IFM_ID_POOL_END = 65535;
+    //Group Prefix
+    public static final long VLAN_GROUP_START = 1000;
+    public static final long TRUNK_GROUP_START = 20000;
+    public static final long LOGICAL_GROUP_START = 100000;
+    //Table
+    public static final short VLAN_INTERFACE_INGRESS_TABLE = 0;
+    public static final short VXLAN_TRUNK_INTERFACE_TABLE = 10;
+    public static final short TRUNK_L2_TABLE = 11;
+    public static final short GRE_TRUNK_INTERFACE_TABLE = 12;
+    public static final short LPORT_DISPATCHER_TABLE = 30;
+    public static final short L3_INTERFACE_TABLE = 80;
+    public static final long DELAY_TIME_IN_MILLISECOND = 10000;
+    //Cookies
+    public static final BigInteger COOKIE_VXLAN_TRUNK_L2_TABLE = new BigInteger("1200000", 16);
+    public static final BigInteger COOKIE_GRE_TRUNK_L2_TABLE = new BigInteger("1400000", 16);
+    public static final BigInteger COOKIE_L3_BASE = new BigInteger("8000000", 16);
+    //Tunnel Monitoring
+    public static final int DEFAULT_MONITOR_INTERVAL = 10000;
+}
diff --git a/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/InterfaceInfo.java b/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/InterfaceInfo.java
new file mode 100644 (file)
index 0000000..0118fbf
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.globals;
+
+import java.io.Serializable;
+import java.math.BigInteger;
+
+public class InterfaceInfo implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
+    public enum InterfaceType  {
+        VLAN_INTERFACE,
+        VXLAN_TRUNK_INTERFACE,
+        GRE_TRUNK_INTERFACE,
+        VXLAN_VNI_INTERFACE,
+        LOGICAL_GROUP_INTERFACE,
+        UNKNOWN_INTERFACE;
+    }
+
+    public enum InterfaceAdminState {
+        ENABLED,
+        DISABLED
+    }
+
+    public enum InterfaceOpState {
+        UP,
+        DOWN
+    }
+
+    protected InterfaceType interfaceType;
+    protected int interfaceTag;
+    protected BigInteger dpId = IfmConstants.INVALID_DPID;
+    protected InterfaceAdminState adminState = InterfaceAdminState.ENABLED;
+    protected InterfaceOpState opState;
+    protected long groupId;
+    protected long l2domainGroupId;
+    protected int portNo = IfmConstants.INVALID_PORT_NO;
+    protected String portName;
+    protected String interfaceName;
+    protected boolean isUntaggedVlan;
+
+    public String getInterfaceName() {
+        return interfaceName;
+    }
+
+    public void setInterfaceName(String interfaceName) {
+        this.interfaceName = interfaceName;
+    }
+
+    public InterfaceInfo(BigInteger dpId, String portName) {
+        this.dpId = dpId;
+        this.portName = portName;
+    }
+
+    public InterfaceInfo(String portName) {
+        this.portName = portName;
+    }
+
+    public boolean isOperational() {
+        return adminState == InterfaceAdminState.ENABLED && opState == InterfaceOpState.UP;
+    }
+
+    public InterfaceType getInterfaceType() {
+        return interfaceType;
+    }
+    public void setInterfaceType(InterfaceType lportType) {
+        this.interfaceType = lportType;
+    }
+    public int getInterfaceTag() {
+        return interfaceTag;
+    }
+    public void setInterfaceTag(int interfaceTag) {
+        this.interfaceTag = interfaceTag;
+    }
+    public void setUntaggedVlan(boolean isUntaggedVlan) {
+        this.isUntaggedVlan = isUntaggedVlan;
+    }
+    public boolean isUntaggedVlan() {
+        return  isUntaggedVlan;
+    }
+    public BigInteger getDpId() {
+        return dpId;
+    }
+    public void setDpId(BigInteger dpId) {
+        this.dpId = dpId;
+    }
+    public InterfaceAdminState getAdminState() {
+        return adminState;
+    }
+    public void setAdminState(InterfaceAdminState adminState) {
+        this.adminState = adminState;
+    }
+    public InterfaceOpState getOpState() {
+        return opState;
+    }
+    public void setOpState(InterfaceOpState opState) {
+        this.opState = opState;
+    }
+    public long getGroupId() {
+        return groupId;
+    }
+    public void setGroupId(long groupId) {
+        this.groupId = groupId;
+    }
+    public long getL2domainGroupId() {
+        return l2domainGroupId;
+    }
+    public void setL2domainGroupId(long l2domainGroupId) {
+        this.l2domainGroupId = l2domainGroupId;
+    }
+
+    public int getPortNo() {
+        return portNo;
+    }
+
+    public void setPortNo(int portNo) {
+        this.portNo = portNo;
+    }
+
+    public void setPortName(String portName) {
+        this.portName = portName;
+    }
+    public String getPortName(){
+        return this.portName;
+    }
+}
diff --git a/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/InterfaceServiceUtil.java b/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/InterfaceServiceUtil.java
new file mode 100644 (file)
index 0000000..36f1898
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vpnservice.interfacemgr.globals;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.mdsalutil.FlowInfoKey;
+import org.opendaylight.vpnservice.mdsalutil.GroupInfoKey;
+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;
+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.list.Instruction;
+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.ServicesInfoBuilder;
+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.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+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.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServicesBuilder;
+
+import com.google.common.base.Optional;
+
+public class InterfaceServiceUtil {
+
+    public static ServicesInfo buildServiceInfo(String serviceName, short serviceIndex, int servicePriority,
+            BigInteger cookie, List<Instruction> instructions) {
+        List<BoundServices>  boundService = new ArrayList<BoundServices>();
+        boundService.add(new BoundServicesBuilder().setServicePriority((short)servicePriority).setServiceName(serviceName).build());
+        return new ServicesInfoBuilder().setBoundServices(boundService).setKey(new ServicesInfoKey(serviceName)).build();
+    }
+
+    public static ServicesInfo buildServiceInfo(String serviceName, short serviceIndex, int servicePriority,
+            BigInteger cookie) {
+        List<BoundServices>  boundService = new ArrayList<BoundServices>();
+        boundService.add(new BoundServicesBuilder().setServicePriority((short)servicePriority).setServiceName(serviceName).build());
+        return new ServicesInfoBuilder().setBoundServices(boundService).setKey(new ServicesInfoKey(serviceName)).build();
+    }
+
+    public static List<MatchInfo> getMatchInfoForVlanLPort(BigInteger dpId, long portNo, long vlanId, boolean isVlanTransparent) {
+        List<MatchInfo> matches = new ArrayList<MatchInfo>();
+        matches.add(new MatchInfo(MatchFieldType.in_port, new BigInteger[] {dpId, BigInteger.valueOf(portNo)}));
+        if (vlanId != 0 && !isVlanTransparent) {
+            matches.add(new MatchInfo(MatchFieldType.vlan_vid, new long[] { vlanId }));
+        }
+        return matches;
+    }
+
+    public static short getVlanId(String interfaceName, DataBroker broker) {
+        InstanceIdentifier<Interface> id = InstanceIdentifier.builder(Interfaces.class)
+                .child(Interface.class, new InterfaceKey(interfaceName)).build();
+        Optional<Interface> ifInstance = MDSALUtil.read(LogicalDatastoreType.CONFIGURATION, id, broker);
+        if (ifInstance.isPresent()) {
+            IfL2vlan vlanIface =ifInstance.get().getAugmentation(IfL2vlan.class);
+            short vlanId = vlanIface.getVlanId() == null ? 0 : vlanIface.getVlanId().getValue().shortValue();
+            return vlanId;
+        }
+        return -1;
+    }
+
+    public static Set<Object> getStatRequestKeys(BigInteger dpId, short tableId, List<MatchInfo> matches, String flowId, long groupId) {
+        Set<Object> statRequestKeys = new HashSet<Object>();
+        statRequestKeys.add(getFlowStatisticsKey(dpId, tableId, matches, flowId));
+        statRequestKeys.add(getGroupStatisticsKey(dpId, groupId));
+        return statRequestKeys;
+    }
+
+    public static GroupInfoKey getGroupStatisticsKey(BigInteger dpId, long groupId) {
+        return new GroupInfoKey(dpId, groupId);
+    }
+
+    public static FlowInfoKey getFlowStatisticsKey(BigInteger dpId, short tableId, List<MatchInfo> matches, String flowId) {
+        return new FlowInfoKey(dpId, tableId, MDSALUtil.buildMatches(matches), flowId);
+    }
+
+    public static List<MatchInfo> getLPortDispatcherMatches(short serviceIndex, int interfaceTag) {
+        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
+                 MetaDataUtil.getMetaDataForLPortDispatcher(interfaceTag, serviceIndex),
+                 MetaDataUtil.getMetaDataMaskForLPortDispatcher() }));
+        return mkMatches;
+    }
+
+}
diff --git a/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/LogicalGroupInterfaceInfo.java b/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/LogicalGroupInterfaceInfo.java
new file mode 100644 (file)
index 0000000..c8206d0
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.globals;
+
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.util.*;
+
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+
+public class LogicalGroupInterfaceInfo extends InterfaceInfo {
+
+    /*
+         List of vxlan/GRE physical tunnel interfaces makes a logical tunnel interface
+         between a pair of DPNs
+
+     */
+
+    private List<String> parentInterfaceNames;
+
+    public LogicalGroupInterfaceInfo(String portName, BigInteger srcDpId,List<String> pInterfaces) {
+        super(srcDpId,portName);
+
+        parentInterfaceNames = new ArrayList(pInterfaces);
+    }
+
+    public List<String> getParentInterfaceNames() {
+        return parentInterfaceNames;
+    }
+
+    public void addParentInterfaceName(String parentIfname) {
+        parentInterfaceNames.add(parentIfname);
+    }
+
+    public int getTotalParentInterfaces() {
+        return parentInterfaceNames.size();
+    }
+
+    public void deleteParentInterfaceName(String parentIfname) {
+        parentInterfaceNames.remove(parentIfname);
+    }
+
+}
+
+/*--------------------------------*/
+
diff --git a/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/VlanInterfaceInfo.java b/interfacemgr/interfacemgr-api/src/main/java/org/opendaylight/vpnservice/interfacemgr/globals/VlanInterfaceInfo.java
new file mode 100644 (file)
index 0000000..77ad4c8
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.globals;
+
+import java.math.BigInteger;
+
+public class VlanInterfaceInfo extends InterfaceInfo {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+    private short vlanId;
+    private boolean isVlanTransparent;
+
+    public VlanInterfaceInfo(BigInteger dpId,
+            String portName, short vlanId) {
+        super(dpId, portName);
+        this.vlanId = vlanId;
+    }
+
+    public VlanInterfaceInfo(String portName, short vlanId) {
+        super(portName);
+        this.vlanId = vlanId;
+    }
+
+    public short getVlanId() {
+        return vlanId;
+    }
+
+    public void setVlanId(short vlanId) {
+        this.vlanId = vlanId;
+    }
+
+    public boolean isVlanTransparent() {
+        return isVlanTransparent;
+    }
+
+    public void setVlanTransparent(boolean isVlanTransparent) {
+        this.isVlanTransparent = isVlanTransparent;
+    }
+}
index f3ba03d3cfd0723b270433ea26f431f47cfa4b0d..c79b1d25593c2bc1537e95b1d7205af0f48f1a55 100644 (file)
@@ -8,12 +8,12 @@
 
 package org.opendaylight.vpnservice.interfacemgr.interfaces;
 
-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 org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
 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.interfaces.rev140508.interfaces.Interface;
 
 @Deprecated
 public interface IInterfaceManager {
@@ -34,4 +34,8 @@ public interface IInterfaceManager {
 
     @Deprecated
     public Long getPortForInterface(Interface intf);
+
+    public InterfaceInfo getInterfaceInfo(String intInfo);
+
+    public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName, InterfaceInfo.InterfaceType interfaceType);
 }
\ No newline at end of file
diff --git a/interfacemgr/interfacemgr-api/src/main/yang/interface-statistics.yang b/interfacemgr/interfacemgr-api/src/main/yang/interface-statistics.yang
new file mode 100644 (file)
index 0000000..9b4c856
--- /dev/null
@@ -0,0 +1,58 @@
+module interface-statistics {
+    namespace "urn:opendaylight:vpnservice:interface:statistics";
+    prefix if-stats;
+
+    import ietf-interfaces {
+        prefix if;
+    }
+
+    revision "2015-08-24" {
+        description "YANG model describes rpc to retrieve the different ingress/egress statistics ie. packet/byte counts";
+    }
+
+     typedef result-code {
+        type enumeration {
+             enum not-found;
+             enum success;
+             enum incomplete;
+         }
+    }
+
+    grouping service-enitity-statistics {
+        leaf packet-tx-count {
+            type uint32;
+        }
+        leaf packet-rx-count {
+            type uint32;
+        }
+        leaf byte-tx-count {
+            type uint32;
+        }
+        leaf byte-rx-count {
+            type uint32;
+        }
+    }
+
+    grouping stat-reply {
+        leaf stat-result-code {
+            type result-code;
+        }
+        uses service-enitity-statistics;
+    }
+
+    rpc get-interface-statistics {
+        input {
+            leaf interface-name {
+                type leafref {
+                    path "/if:interfaces/if:interface/if:name";
+                }
+            }
+        }
+        output {
+            container stat-result {
+                uses stat-reply;
+            }
+        }
+    }
+
+}
index 2e573bef4ce95aa8b6c43339ca1732c18c9fbec3..927f8aebbce2436462e9c96575c2e585f387dda4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -20,7 +20,15 @@ public class IfmConstants {
     public static final int DEFAULT_IFINDEX = 65536;
     public static final int DEFAULT_FLOW_PRIORITY = 5;
     public static final String IFM_LPORT_TAG_IDPOOL_NAME = "vlaninterfaces.lporttag";
-    public static final BigInteger COOKIE_VM_LFIB_TABLE = new BigInteger("8000002", 16);;
+    public static final short VLAN_INTERFACE_INGRESS_TABLE = 0;
+    //Group Prefix
+    public static final long VLAN_GROUP_START = 1000;
+    public static final long TRUNK_GROUP_START = 20000;
+    public static final long LOGICAL_GROUP_START = 100000;
+    public static final short INTERNAL_TUNNEL_TABLE = 22;
+    public static final short EXTERNAL_TUNNEL_TABLE = 23;
+    public static final short LFIB_TABLE = 20;
+    public static final BigInteger COOKIE_VM_LFIB_TABLE = new BigInteger("8000002", 16);
     public static final String TUNNEL_TABLE_FLOWID_PREFIX = "TUNNEL.";
     public static final BigInteger TUNNEL_TABLE_COOKIE = new BigInteger("9000000", 16);
 }
index 44f754e86fa54b0f30f14a558384ae91afa4f5d3..adebb5fa07010351bc0468af30fdd7de3a93e17f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -14,9 +14,15 @@ 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.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.globals.VlanInterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
+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;
 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;
@@ -26,6 +32,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru
 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.params.xml.ns.yang.overlay.rev150105.TunnelTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInputBuilder;
@@ -36,6 +45,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.ReleaseIdInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPool;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.id.pools.IdPoolKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan.L2vlanMode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
@@ -105,6 +117,17 @@ public class IfmUtil {
         return strList;
     }
 
+    public static long getGroupId(long ifIndex, InterfaceInfo.InterfaceType infType) {
+        if (infType == InterfaceInfo.InterfaceType.LOGICAL_GROUP_INTERFACE) {
+            return ifIndex + IfmConstants.LOGICAL_GROUP_START;
+        }
+        else if (infType == InterfaceInfo.InterfaceType.VLAN_INTERFACE) {
+            return ifIndex + IfmConstants.VLAN_GROUP_START;
+        } else {
+            return ifIndex + IfmConstants.TRUNK_GROUP_START;
+        }
+    }
+
     public static List<String> getDpIdPortNameAndSuffixFromInterfaceName(String intfName) {
         List<String> strList = new ArrayList<>(3);
         int index1 = intfName.indexOf(":");
@@ -200,4 +223,57 @@ public class IfmUtil {
         }
         return null;
     }
+
+    public static NodeConnectorId getNodeConnectorIdFromInterface(Interface iface, DataBroker dataBroker) {
+        return FlowBasedServicesUtils.getNodeConnectorIdFromInterface(iface, dataBroker);
+    }
+
+    public static InterfaceInfo.InterfaceType getInterfaceType(Interface iface) {
+        InterfaceInfo.InterfaceType interfaceType =
+                org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceType.UNKNOWN_INTERFACE;
+        Class<? extends org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType> ifType = iface.getType();
+
+        if (ifType.isAssignableFrom(L2vlan.class)) {
+            interfaceType =  org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceType.VLAN_INTERFACE;
+        } else if (ifType.isAssignableFrom(Tunnel.class)) {
+            IfTunnel ifTunnel = iface.getAugmentation(IfTunnel.class);
+            Class<? extends  org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase> tunnelType = ifTunnel.getTunnelInterfaceType();
+            if (tunnelType.isAssignableFrom(TunnelTypeVxlan.class)) {
+                interfaceType = InterfaceInfo.InterfaceType.VXLAN_TRUNK_INTERFACE;
+            } else if (tunnelType.isAssignableFrom(TunnelTypeGre.class)) {
+                interfaceType = InterfaceInfo.InterfaceType.GRE_TRUNK_INTERFACE;
+            }
+        }
+        // TODO: Check if the below condition is still needed/valid
+        //else if (ifType.isAssignableFrom(InterfaceGroup.class)) {
+        //    interfaceType =  org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceType.LOGICAL_GROUP_INTERFACE;
+        //}
+        return interfaceType;
+    }
+
+    public static VlanInterfaceInfo getVlanInterfaceInfo(String interfaceName, Interface iface, BigInteger dpId){
+        IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class);
+
+        short vlanId = 0;
+        //FIXME :Use this below thing properly
+        VlanInterfaceInfo vlanInterfaceInfo = new VlanInterfaceInfo(dpId, "someString", vlanId);
+
+        if (vlanIface != null) {
+            vlanId = vlanIface.getVlanId() == null ? 0 : vlanIface.getVlanId().getValue().shortValue();
+            L2vlanMode l2VlanMode = vlanIface.getL2vlanMode();
+
+            if (l2VlanMode == L2vlanMode.Transparent) {
+                vlanInterfaceInfo.setVlanTransparent(true);
+            }
+            if (l2VlanMode == L2vlanMode.NativeUntagged) {
+                vlanInterfaceInfo.setUntaggedVlan(true);
+            }
+            vlanInterfaceInfo.setVlanId(vlanId);
+
+        }
+        return vlanInterfaceInfo;
+    }
+
+
+
 }
index 46fccb119f7f0a14ce73c271b655fc2e4ade8baa..f1a9c84963399a5f4974a42c3dd7ad6f75c591d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -7,38 +7,52 @@
  */
 package org.opendaylight.vpnservice.interfacemgr;
 
+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.vpnservice.interfacemgr.commons.InterfaceManagerCommonUtils;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
+import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceAdminState;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
 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.listeners.VlanMemberConfigListener;
 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.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.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.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.idmanager.rev150403.IdManagerService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetDpidFromInterfaceInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetDpidFromInterfaceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetDpidFromInterfaceOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEndpointIpForDpnInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEndpointIpForDpnInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEndpointIpForDpnOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetPortFromInterfaceInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetPortFromInterfaceInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetPortFromInterfaceOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
 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);
@@ -52,7 +66,7 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
     private FlowBasedServicesInterfaceStateListener flowBasedServicesInterfaceStateListener;
     private FlowBasedServicesConfigListener flowBasedServicesConfigListener;
     private VlanMemberConfigListener vlanMemberConfigListener;
-
+    private DataBroker dataBroker;
     private InterfaceManagerRpcService interfaceManagerRpcService;
     private BindingAwareBroker.RpcRegistration<OdlInterfaceRpcService> rpcRegistration;
 
@@ -68,7 +82,7 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
     public void onSessionInitiated(ProviderContext session) {
         LOG.info("InterfacemgrProvider Session Initiated");
         try {
-            final  DataBroker dataBroker = session.getSALService(DataBroker.class);
+            dataBroker = session.getSALService(DataBroker.class);
             idManager = rpcProviderRegistry.getRpcService(IdManagerService.class);
             createIdPool();
 
@@ -158,6 +172,89 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable
         return null;
     }
 
+    @Override
+    public InterfaceInfo getInterfaceInfo(String interfaceName) {
+        //FIXME [ELANBE] This is not working yet, fix this
+
+        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){
+            LOG.error("Interface {} is not present", interfaceName);
+            return null;
+        }
+
+        Integer lportTag = ifState.getIfIndex();
+        Interface intf = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
+
+        NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(intf, dataBroker);
+        InterfaceInfo.InterfaceType interfaceType = IfmUtil.getInterfaceType(intf);
+        InterfaceInfo interfaceInfo = null;
+        BigInteger dpId = org.opendaylight.vpnservice.interfacemgr.globals.IfmConstants.INVALID_DPID;
+        Integer portNo = org.opendaylight.vpnservice.interfacemgr.globals.IfmConstants.INVALID_PORT_NO;
+        if (ncId !=null ) {
+            dpId = new BigInteger(IfmUtil.getDpnFromNodeConnectorId(ncId));
+            portNo = Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId));
+        }
+
+        if(interfaceType == InterfaceInfo.InterfaceType.VLAN_INTERFACE){
+               interfaceInfo = IfmUtil.getVlanInterfaceInfo(interfaceName, intf, dpId);
+        } else if (interfaceType == InterfaceInfo.InterfaceType.VXLAN_TRUNK_INTERFACE || interfaceType == InterfaceInfo.InterfaceType.GRE_TRUNK_INTERFACE) {/*
+            trunkInterfaceInfo trunkInterfaceInfo = (TrunkInterfaceInfo) ConfigIfmUtil.getTrunkInterfaceInfo(ifName, ConfigIfmUtil.getInterfaceByIfName(dataBroker, ifName));
+            String higherLayerIf = inf.getHigherLayerIf().get(0);
+            Interface vlanInterface = ConfigIfmUtil.getInterfaceByIfName(dataBroker, higherLayerIf);
+            trunkInterfaceInfo.setPortName(vlanInterface.getAugmentation(BaseConfig.class).getParentInterface());
+            trunkInterfaceManager.updateTargetMacAddressInInterfaceInfo(trunkInterfaceInfo, trunkInterface);
+            if (trunkInterface.getPhysAddress() != null) {
+                trunkInterfaceInfo.setLocalMacAddress(trunkInterface.getPhysAddress().getValue());
+            }
+            interfaceInfo = trunkInterfaceInfo;
+            interfaceInfo.setL2domainGroupId(IfmUtil.getGroupId(OperationalIfmUtil.getInterfaceStateByIfName(dataBroker, higherLayerIf).getIfIndex(), InterfaceType.VLAN_INTERFACE));
+        */} else {
+            LOG.error("Type of Interface {} is unknown", interfaceName);
+            return null;
+        }
+        interfaceInfo.setDpId(dpId);
+        interfaceInfo.setPortNo(portNo);
+        interfaceInfo.setAdminState((intf.isEnabled() == true) ? InterfaceAdminState.ENABLED : InterfaceAdminState.DISABLED);
+        interfaceInfo.setInterfaceName(interfaceName);
+        interfaceInfo.setInterfaceTag(lportTag);
+        interfaceInfo.setInterfaceType(interfaceType);
+        interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
+        interfaceInfo.setOpState((ifState.getOperStatus() == OperStatus.Up) ? InterfaceInfo.InterfaceOpState.UP : InterfaceInfo.InterfaceOpState.DOWN);
+
+
+        return interfaceInfo;
+
+    }
+
+    @Override
+       public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName, InterfaceInfo.InterfaceType interfaceType) {
+               InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
+               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) {
+                       LOG.error("Interface {} is not present", interfaceName);
+                       return null;
+               }
+        Integer lportTag = ifState.getIfIndex();
+               Interface intf = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
+               NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(intf, dataBroker);
+               if (ncId != null) {
+                       interfaceInfo.setDpId(new BigInteger(IfmUtil.getDpnFromNodeConnectorId(ncId)));
+                       interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
+               }
+        interfaceInfo.setAdminState((intf.isEnabled() == true) ? InterfaceAdminState.ENABLED : InterfaceAdminState.DISABLED);
+        interfaceInfo.setInterfaceName(interfaceName);
+        interfaceInfo.setInterfaceTag(lportTag);
+        interfaceInfo.setInterfaceType(interfaceType);
+        interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
+        interfaceInfo.setOpState((ifState.getOperStatus() == OperStatus.Up) ? InterfaceInfo.InterfaceOpState.UP : InterfaceInfo.InterfaceOpState.DOWN);
+
+
+        return interfaceInfo;
+               }
+
     @Override
     public BigInteger getDpnForInterface(String ifName) {
         GetDpidFromInterfaceInput input = new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
index 88cf81df95746e26542271b9e45661be9c0fc347..eddaeb4fed7e2f74cd9dd5ab915c3c8664c05612 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -10,11 +10,16 @@ package org.opendaylight.vpnservice.itm.globals;
 import java.math.BigInteger;
 
 
+
 public class ITMConstants{
   public static final BigInteger COOKIE_ITM = new BigInteger("9000000", 16);
   public static final String ITM_IDPOOL_NAME = "Itmservices";
   public static final long ITM_IDPOOL_START = 1L;
   public static final String ITM_IDPOOL_SIZE = "100000";
                 
+    public static final short INTERNAL_TUNNEL_TABLE = 22;
+
+
 
+    public static final short TERMINATING_SERVICE_TABLE = 36;
 }
index 424319fa3e83def673e440e1936a4b8c8fa24cf5..a32f3cde21d6db2cdac45fb499a50eb500b33a54 100644 (file)
             <artifactId>liblldp</artifactId>
             <version>${liblldp.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin</groupId>
+            <artifactId>openflowplugin-extension-nicira</artifactId>
+            <version>${openflowplugin.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin</groupId>
+            <artifactId>openflowjava-extension-nicira</artifactId>
+            <version>${openflowplugin.version}</version>
+        </dependency>
+
     </dependencies>
 </project>
old mode 100644 (file)
new mode 100755 (executable)
index 847284f..19ec9da
@@ -10,11 +10,6 @@ package org.opendaylight.vpnservice.mdsalutil;
 import java.math.BigInteger;
 import java.net.InetAddress;
 
-//import org.opendaylight.yang.gen.v1.urn.ericsson.experimenter.action.types.rev140228.EricFilterTypes;
-//import org.opendaylight.yang.gen.v1.urn.ericsson.experimenter.action.types.rev140228.action.types.action.action.ExperimenterActionTypeBuilder;
-//import org.opendaylight.yang.gen.v1.urn.ericsson.experimenter.action.types.rev140228.action.types.action.action.experimenter.action.type.action.type.FilterTypesActionBuilder;
-//import org.opendaylight.yang.gen.v1.urn.ericsson.experimenter.action.types.rev140228.filter.types.group.Metadata;
-//import org.opendaylight.yang.gen.v1.urn.ericsson.experimenter.action.types.rev140228.filter.types.group.MetadataBuilder;
 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.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCaseBuilder;
@@ -34,12 +29,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.mpls.action._case.PushMplsActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.pbb.action._case.PushPbbActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetField;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
 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.OutputPortValues;
-//import org.opendaylight.yang.gen.v1.urn.ericsson.experimenter.flow.types.rev140422.EricssonPortTypes;
+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.apply.actions._case.ApplyActions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
@@ -62,15 +59,24 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
-//import org.opendaylight.yang.gen.v1.urn.ericsson.experimenter.action.types.rev140228.action.types.action.action.ExperimenterActionTypeBuilder;
-//import org.opendaylight.yang.gen.v1.urn.ericsson.experimenter.action.types.rev140228.action.types.action.action.experimenter.action.type.action.type.VxlanPopActionBuilder;
-//import org.opendaylight.yang.gen.v1.urn.ericsson.experimenter.action.types.rev140228.action.types.action.action.experimenter.action.type.action.type.VxlanPushActionBuilder;
-//import org.opendaylight.yang.gen.v1.urn.ericsson.experimenter.action.types.rev140228.action.types.action.action.experimenter.action.type.action.type.GrePopActionBuilder;
-//import org.opendaylight.yang.gen.v1.urn.ericsson.experimenter.action.types.rev140228.action.types.action.action.experimenter.action.type.action.type.GrePushActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder;
-
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.field._case.SetFieldActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.OfjNxActionOutputRegGrouping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionOutputRegBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionOutputRegRpcAddGroupCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionOutputRegRpcAddGroupCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionOutputRegNodesNodeGroupBucketsBucketActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionOutputRegNodesNodeGroupBucketsBucketActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegLoadNodesNodeGroupBucketsBucketActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionOutputRegNodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.NxOutputReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.NxOutputRegBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmitBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxRegCaseBuilder;
 public enum ActionType {
     group {
         @Override
@@ -372,6 +378,7 @@ public enum ActionType {
 
         }
     },
+
     drop_action {
 
         @Override
@@ -380,9 +387,44 @@ public enum ActionType {
             DropAction dropAction = dab.build();
             ActionBuilder ab = new ActionBuilder();
             ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
+            ab.setKey(new ActionKey(actionInfo.getActionKey())).build();
+            return ab.build();
+        }
+    },
+    set_field_reg {
+
+        @Override
+        public Action buildAction(ActionInfo actionInfo) {
+            ActionBuilder ab = new ActionBuilder();
+            String[] actionValues = actionInfo.getActionValues();
+            NxOutputReg r = new NxOutputRegBuilder().setSrc(
+                    new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.nx.output.reg.SrcBuilder().setSrcChoice(
+                            new SrcNxRegCaseBuilder().setNxReg(NxmNxReg1.class).build())
+                            .setOfsNbits(Integer.valueOf(Integer.parseInt(actionValues[0])))
+                            .build())
+                    .setMaxLen(Integer.valueOf(0xffff))
+                    .build();
+            ab.setAction(new NxActionOutputRegNodesNodeGroupBucketsBucketActionsCaseBuilder().setNxOutputReg(r).build());
+            ab.setKey(new ActionKey(actionInfo.getActionKey()));
             return ab.build();
         }
     },
+
+
+
+    nx_resubmit {
+
+        @Override
+        public Action buildAction(ActionInfo actionInfo) {
+            NxResubmitBuilder nxarsb = new NxResubmitBuilder();
+            nxarsb.setTable((short) 55);
+            ActionBuilder ab = new ActionBuilder();
+            ab.setAction(new NxActionResubmitRpcAddGroupCaseBuilder().setNxResubmit(nxarsb.build()).build());
+            ab.setKey(new ActionKey(actionInfo.getActionKey()));
+            return ab.build();
+        }
+    },
+
     goto_table {
 
         @Override
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/FlowInfoKey.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/FlowInfoKey.java
new file mode 100644 (file)
index 0000000..b622980
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.mdsalutil;
+
+import java.math.BigInteger;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+
+public final class FlowInfoKey {
+
+    private final BigInteger dpId;
+    private final short tableId;
+    private final Match matches;
+    private final String flowId;
+
+    public FlowInfoKey(BigInteger dpId, short tableId, Match matches, String flowId) {
+        this.dpId = dpId;
+        this.tableId = tableId;
+        this.matches = matches;
+        this.flowId = flowId;
+    }
+
+    public short getTableId() {
+        return tableId;
+    }
+
+    public Match getMatches() {
+        return matches;
+    }
+
+    public BigInteger getDpId() {
+        return dpId;
+    }
+
+    public String getFlowId() {
+        return flowId;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((dpId == null) ? 0 : dpId.hashCode());
+        result = prime * result + ((matches == null) ? 0 : matches.hashCode());
+        result = prime * result + tableId;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        FlowInfoKey other = (FlowInfoKey) obj;
+        if (dpId == null) {
+            if (other.dpId != null)
+                return false;
+        } else if (!dpId.equals(other.dpId))
+            return false;
+        if (matches == null) {
+            if (other.matches != null)
+                return false;
+        } else if (!matches.equals(other.matches))
+            return false;
+        if (tableId != other.tableId)
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "FlowStatisticsKey [dpId=" + dpId + ", tableId=" + tableId + ", matches=" + matches + "]";
+    }
+
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/GroupInfoKey.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/vpnservice/mdsalutil/GroupInfoKey.java
new file mode 100644 (file)
index 0000000..e31ff5f
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.mdsalutil;
+
+import java.math.BigInteger;
+
+public final class GroupInfoKey {
+
+    private final BigInteger dpId;
+    private final long groupId;
+
+    public GroupInfoKey(BigInteger dpId, long groupId) {
+        this.dpId = dpId;
+        this.groupId = groupId;
+    }
+
+    public long getGroupId() {
+        return groupId;
+    }
+
+    public BigInteger getDpId() {
+        return dpId;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((dpId == null) ? 0 : dpId.hashCode());
+        result = prime * result + (int) (groupId ^ (groupId >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        GroupInfoKey other = (GroupInfoKey) obj;
+        if (dpId == null) {
+            if (other.dpId != null)
+                return false;
+        } else if (!dpId.equals(other.dpId))
+            return false;
+        if (groupId != other.groupId)
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "GroupStatisticsKey [dpId=" + dpId + ", groupId=" + groupId + "]";
+    }
+
+}
index 41e66bfce3ff7266d21d7df1be9495e30ab1bc67..27afd5c35c72ff6987db65c35aa625dd207fa231 100644 (file)
@@ -246,7 +246,7 @@ public class MDSALUtil {
         return EMPTY_Instructions;
     }
 
-    protected static Match buildMatches(List<MatchInfo> listMatchInfo) {
+    public static Match buildMatches(List<MatchInfo> listMatchInfo) {
         if (listMatchInfo != null) {
             MatchBuilder matchBuilder = new MatchBuilder();
             Map<Class<?>, Object> mapMatchBuilder = new HashMap<Class<?>, Object>();
old mode 100644 (file)
new mode 100755 (executable)
index 57a7f38..e514e3e
@@ -8,6 +8,8 @@
 package org.opendaylight.vpnservice.mdsalutil;
 
 import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
@@ -31,6 +33,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.protocol.match.fields.PbbBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg1Key;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.ArpOp;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.ArpSpa;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.ArpTpa;
@@ -576,6 +588,39 @@ public enum MatchFieldType {
 
     },
 
+    reg1 {
+        @Override
+        protected Class<? extends MatchField> getMatchType() {
+            return MatchField.class;
+        }
+
+        @Override
+        public void createInnerMatchBuilder(MatchInfo matchInfo, Map<Class<?>, Object> mapMatchBuilder) {
+            NxmNxRegBuilder regdataBuilder = (NxmNxRegBuilder) mapMatchBuilder.get(NxmNxRegBuilder.class);
+             if (regdataBuilder == null) {
+                regdataBuilder = new NxmNxRegBuilder();
+                mapMatchBuilder.put(NxmNxRegBuilder.class, regdataBuilder);
+            }
+            long[] metadataValues = matchInfo.getMatchValues();
+            regdataBuilder.setValue(metadataValues[0]).build();
+            ArrayList<ExtensionList> extensions = new ArrayList<>();
+            NxAugMatchNodesNodeTableFlow am =  new NxAugMatchNodesNodeTableFlowBuilder().setNxmNxReg(new NxmNxRegBuilder().setReg(NxmNxReg1.class).setValue(metadataValues[0]).build()).build();
+            extensions.add(new ExtensionListBuilder().setExtensionKey(NxmNxReg1Key.class).setExtension(new ExtensionBuilder().addAugmentation(NxAugMatchNodesNodeTableFlow.class, am).build()).build());
+            GeneralAugMatchNodesNodeTableFlow m = new GeneralAugMatchNodesNodeTableFlowBuilder().setExtensionList(extensions).build();
+        }
+
+        @Override
+        public void setMatch(MatchBuilder matchBuilderInOut, MatchInfo matchInfo, Map<Class<?>, Object> mapMatchBuilder) {
+            List<ExtensionList> extensions = new ArrayList<>();
+            long[] matchvalues = matchInfo.getMatchValues();
+            NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder().setNxmNxReg(new NxmNxRegBuilder().setReg(NxmNxReg1.class).setValue(matchvalues[0]).build()).build();
+            extensions.add(new ExtensionListBuilder().setExtensionKey(NxmNxReg1Key.class).setExtension(new ExtensionBuilder().addAugmentation(NxAugMatchNodesNodeTableFlow.class, am).build()).build());
+            GeneralAugMatchNodesNodeTableFlow m = new GeneralAugMatchNodesNodeTableFlowBuilder().setExtensionList(extensions).build();
+            matchBuilderInOut.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
+
+        }
+    },
+
     vlan_vid {
         @Override
         protected Class<? extends MatchField> getMatchType() {
index defa0f596c77693c5e09eb41cba746d046caddeb..3535c435e9c0297c2fde7e5fe7006efecfc88739 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -16,6 +16,7 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFaile
 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
 import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
 import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
+import org.opendaylight.vpnservice.mdsalutil.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 
 public interface IMdsalApiManager {
@@ -44,4 +45,29 @@ public interface IMdsalApiManager {
 
     public void sendARPPacketOutWithActions(BigInteger dpnId, byte[] payload, List<ActionInfo> action_info);
 
+    /**
+     * API to remove the flow on Data Plane Node synchronously. It internally waits for
+     * Flow Change Notification to confirm flow delete request is being sent with-in delayTime.
+     *
+     * @param flowEntity
+     * @param delayTime
+     */
+    public void syncRemoveFlow(FlowEntity flowEntity, long delayTime);
+
+    /**
+     * API to install the Group on Data Plane Node synchronously. It internally waits for
+     * Group Change Notification to confirm group mod request is being sent with-in delayTime
+     *
+     * @param groupEntity
+     * @param delayTime
+     */
+    public void syncInstallGroup(GroupEntity groupEntity, long delayTime);
+
+    /**
+     * API to remove the Group on Data Plane Node synchronously. It internally waits for
+     * Group Change Notification to confirm group delete request is being sent.
+     *
+     * @param groupEntity
+     */
+    public void syncRemoveGroup(GroupEntity groupEntity);
 }
index defe02268714373f2fe6701768f3304a6cee5791..9c2915a0740932e78c5a2087ad628684219fa0a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -11,11 +11,15 @@ package org.opendaylight.vpnservice.mdsalutil.internal;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
 import org.opendaylight.vpnservice.mdsalutil.ActionType;
 import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
 import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
 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;
@@ -40,6 +44,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.opendaylight.vpnservice.mdsalutil.*;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException;
@@ -57,6 +62,8 @@ public class MDSALManager implements AutoCloseable {
     private DataBroker m_dataBroker;
 
     private PacketProcessingService m_packetProcessingService;
+    private ConcurrentMap<FlowInfoKey, Runnable> flowMap = new ConcurrentHashMap<FlowInfoKey, Runnable>();
+    private ConcurrentMap<GroupInfoKey, Runnable> groupMap = new ConcurrentHashMap<GroupInfoKey, Runnable> ();
 
     /**
      * Writes the flows and Groups to the MD SAL DataStore
@@ -324,4 +331,64 @@ public class MDSALManager implements AutoCloseable {
         return nodeDpn;
     }
 
+    public void syncSetUpFlow(FlowEntity flowEntity, long delay, boolean isRemove) {
+        s_logger.trace("syncSetUpFlow for flowEntity {} ", flowEntity);
+        if (flowEntity.getCookie() == null) {
+            flowEntity.setCookie(new BigInteger("0110000", 16));
+        }
+        Flow flow = flowEntity.getFlowBuilder().build();
+        String flowId = flowEntity.getFlowId();
+        BigInteger dpId = flowEntity.getDpnId();
+        short tableId = flowEntity.getTableId();
+        Match matches = flow.getMatch();
+        FlowKey flowKey = new FlowKey( new FlowId(flowId));
+        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();
+        Runnable notifyTask = new NotifyTask();
+        FlowInfoKey flowInfoKey = new FlowInfoKey(dpId, tableId, matches, flowId);
+        synchronized (flowInfoKey.toString().intern()) {
+            flowMap.put(flowInfoKey, notifyTask);
+            if (isRemove) {
+                MDSALUtil.syncDelete(m_dataBroker, LogicalDatastoreType.CONFIGURATION, flowInstanceId);
+            } else {
+                MDSALUtil.syncWrite(m_dataBroker, LogicalDatastoreType.CONFIGURATION, flowInstanceId, flow);
+            }
+            synchronized (notifyTask) {
+                try {
+                    notifyTask.wait(delay);
+                } catch (InterruptedException e){}
+            }
+        }
+    }
+
+    public void syncSetUpGroup(GroupEntity groupEntity, long delayTime, boolean isRemove) {
+        s_logger.trace("syncSetUpGroup for groupEntity {} ", groupEntity);
+        Group group = groupEntity.getGroupBuilder().build();
+        BigInteger dpId = groupEntity.getDpnId();
+        Node nodeDpn = buildDpnNode(dpId);
+        long groupId = groupEntity.getGroupId();
+        GroupKey groupKey = new GroupKey(new GroupId(groupId));
+        InstanceIdentifier<Group> groupInstanceId = InstanceIdentifier.builder(Nodes.class)
+                .child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
+                .child(Group.class, groupKey).build();
+        Runnable notifyTask = new NotifyTask();
+        GroupInfoKey groupInfoKey = new GroupInfoKey(dpId, groupId);
+        synchronized (groupInfoKey.toString().intern()) {
+            s_logger.trace("syncsetupGroupKey groupKey {}", groupInfoKey);
+            groupMap.put(groupInfoKey, notifyTask);
+            if (isRemove) {
+                MDSALUtil.syncDelete(m_dataBroker, LogicalDatastoreType.CONFIGURATION, groupInstanceId);
+            } else {
+                MDSALUtil.syncWrite(m_dataBroker, LogicalDatastoreType.CONFIGURATION, groupInstanceId, group);
+            }
+            synchronized (notifyTask) {
+                try {
+                    notifyTask.wait(delayTime);
+                } catch (InterruptedException e){}
+            }
+        }
+    }
+
 }
index b75bd4c4047b67403bf8ac1f682e381305080869..c617cfcda7feb7b1fc7318e11261e9acfe34be63 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -25,11 +25,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
+import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
 
 public class MDSALUtilProvider implements BindingAwareConsumer, IMdsalApiManager, AutoCloseable {
 
     private static final Logger s_logger = LoggerFactory.getLogger(MDSALUtilProvider.class);
     private MDSALManager mdSalMgr;
+    private static final long FIXED_DELAY_IN_MILLISECONDS = 5000;
 
     @Override
     public void onSessionInitialized(ConsumerContext session) {
@@ -122,4 +125,19 @@ public class MDSALUtilProvider implements BindingAwareConsumer, IMdsalApiManager
         mdSalMgr.sendARPPacketOutWithActions(dpnId, payload, action_info);
     }
 
+    @Override
+    public void syncRemoveFlow(FlowEntity flowEntity, long delayTime) {
+        mdSalMgr.syncSetUpFlow(flowEntity,  delayTime, true);
+    }
+
+    @Override
+    public void syncInstallGroup(GroupEntity groupEntity, long delayTime) {
+        mdSalMgr.syncSetUpGroup(groupEntity, delayTime, false);
+    }
+
+    @Override
+    public void syncRemoveGroup(GroupEntity groupEntity) {
+        mdSalMgr.syncSetUpGroup(groupEntity, FIXED_DELAY_IN_MILLISECONDS, true);
+    }
+
 }
diff --git a/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/NotifyTask.java b/mdsalutil/mdsalutil-impl/src/main/java/org/opendaylight/vpnservice/mdsalutil/internal/NotifyTask.java
new file mode 100644 (file)
index 0000000..d233baf
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.mdsalutil.internal;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class NotifyTask implements Runnable {
+    private static final Logger logger = LoggerFactory.getLogger(NotifyTask.class);
+
+    @Override
+    public void run() {
+        logger.debug("Notify Task is running for the task {}", this);
+        synchronized (this) {
+            notifyAll();
+        }
+    }
+
+}
old mode 100644 (file)
new mode 100755 (executable)
index 4f38447..cb1447f
@@ -34,7 +34,7 @@ import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev14081
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstance1;
+//import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstance1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdOutput;
@@ -124,15 +124,18 @@ public class NexthopManager implements L3nexthopService, AutoCloseable {
                 .child(VpnInstance.class, new VpnInstanceKey(vpnName));
 
         InstanceIdentifier<VpnInstance> id = idBuilder.build();
-        InstanceIdentifier<VpnInstance1> idx = id.augmentation(VpnInstance1.class);
-        Optional<VpnInstance1> vpn = read(LogicalDatastoreType.OPERATIONAL, idx);
-
-        if (vpn.isPresent()) {
-            LOG.debug("VPN id returned: {}", vpn.get().getVpnId());
-            return vpn.get().getVpnId();
-        } else {
-            return -1;
-        }
+        //FIXME [ELAnBE] Commenting out below 2 lines
+        //InstanceIdentifier<VpnInstance1> idx = id.augmentation(VpnInstance1.class);
+        //Optional<VpnInstance1> vpn = read(LogicalDatastoreType.OPERATIONAL, idx);
+
+
+//        if (vpn.isPresent()) {
+//            LOG.debug("VPN id returned: {}", vpn.get().getVpnId());
+//            return vpn.get().getVpnId();
+//        } else {
+//            return -1;
+//        }
+        return -1;
     }
 
     private BigInteger getDpnId(String ofPortId) {
diff --git a/pom.xml b/pom.xml
index 0fdc1a45cb08a2e199452941579035c2e701f770..eb4c800f53040767f47075141bcf9cbf22e818e0 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -26,6 +26,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <module>vpnmanager</module>
     <module>interfacemgr</module>
     <module>alivenessmonitor</module>
+    <module>elanmanager</module>
     <module>fibmanager</module>
     <module>bgpmanager</module>
     <module>neutronvpn</module>