Add netvirt bundle 44/40844/13
authorYakir Dorani <yakir.dorani@hpe.com>
Sun, 26 Jun 2016 12:17:07 +0000 (15:17 +0300)
committerYakir Dorani <yakir.dorani@hpe.com>
Thu, 14 Jul 2016 08:50:26 +0000 (08:50 +0000)
Change-Id: I3cf6a9220af214989474f78e525d42794139b2da
Signed-off-by: Yakir Dorani <yakir.dorani@hpe.com>
features/pom.xml
features/src/main/features/features.xml
impl/pom.xml
netvirt/pom.xml [new file with mode: 0644]
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/EvcListener.java [new file with mode: 0644]
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/MdsalUtils.java [new file with mode: 0644]
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/NetvirtUtils.java [new file with mode: 0644]
netvirt/src/main/resources/org/opendaylight/blueprint/netvirt-driver.xml [new file with mode: 0644]
pom.xml

index f7330e53334a0f8cdbe620a09adfc4d30ab06ede..fc9351e0ae93cb081143693e09869877abbbb921 100644 (file)
@@ -1,17 +1,15 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (c) 2015 Cable Television Laboratories, Inc. 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">
+<!-- Copyright (c) 2015 Cable Television Laboratories, Inc. 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>features-parent</artifactId>
     <version>1.7.0-SNAPSHOT</version>
-    <relativePath/>
+    <relativePath />
   </parent>
   <groupId>org.opendaylight.unimgr</groupId>
   <artifactId>unimgr-features</artifactId>
@@ -27,8 +25,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
     <yangtools.version>1.0.0-SNAPSHOT</yangtools.version>
     <dlux.version>0.4.0-SNAPSHOT</dlux.version>
     <ovsdb.version>1.3.0-SNAPSHOT</ovsdb.version>
+    <netvirt.version>1.3.0-SNAPSHOT</netvirt.version>
+    <vpnservice.version>0.3.0-SNAPSHOT</vpnservice.version>
     <mdsal.model.version>0.9.0-SNAPSHOT</mdsal.model.version>
     <netconf.version>1.1.0-SNAPSHOT</netconf.version>
+    <genius.version>0.1.0-SNAPSHOT</genius.version>
     <configfile.directory>etc/opendaylight/karaf</configfile.directory>
   </properties>
   <dependencyManagement>
@@ -115,6 +116,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <type>xml</type>
       <classifier>features</classifier>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>unimgr-netvirt</artifactId>
+      <version>${project.version}</version>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>unimgr-impl</artifactId>
@@ -157,6 +163,25 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <artifactId>edgeassure-1000</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.netvirt</groupId>
+      <artifactId>vpnservice-features</artifactId>
+      <version>${vpnservice.version}</version>
+      <type>xml</type>
+      <classifier>features</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.genius</groupId>
+      <artifactId>genius-features</artifactId>
+      <version>${genius.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>unimgr-legato-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
-
 </project>
index dc82aa72a3f96a0d67ee2bdb78a93bb1a9690a3a..8ad8b0b2ddbba60236d99cbca07df2f31e407223 100755 (executable)
@@ -1,12 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
-Copyright (c) 2015 CableLabs
-
-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
--->
+<!-- Copyright (c) 2015 CableLabs 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 -->
 <features name="odl-unimgr-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
@@ -17,24 +13,31 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <repository>mvn:org.opendaylight.dlux/features-dlux/{{VERSION}}/xml/features</repository>
   <repository>mvn:org.opendaylight.netconf/features-netconf/{{VERSION}}/xml/features</repository>
   <repository>mvn:org.opendaylight.netconf/features-netconf-connector/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.genius/genius-features/{{VERSION}}/xml/features</repository>
+  <repository>mvn:org.opendaylight.netvirt/vpnservice-features/{{VERSION}}/xml/features</repository>
 
-  <feature name='odl-unimgr-api' version='${project.version}' description='OpenDaylight :: UniMgr :: api'>
+  <feature name='odl-unimgr-api' version='${project.version}'
+    description='OpenDaylight :: UniMgr :: api'>
     <feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
     <feature version='${ovsdb.version}'>odl-ovsdb-southbound-api</feature>
+    <bundle>mvn:org.opendaylight.unimgr/unimgr-legato-api/{{VERSION}}</bundle>
     <bundle>mvn:org.opendaylight.unimgr/unimgr-api/{{VERSION}}</bundle>
   </feature>
 
-  <feature name='odl-unimgr-presto-api' version='${project.version}' description='OpenDaylight :: UniMgr :: NRP Presto API'>
+  <feature name='odl-unimgr-presto-api' version='${project.version}'
+    description='OpenDaylight :: UniMgr :: NRP Presto API'>
     <feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
     <bundle>mvn:org.opendaylight.unimgr/unimgr-presto-api/{{VERSION}}</bundle>
   </feature>
 
-  <feature name='odl-unimgr' version='${project.version}' description='OpenDaylight :: UniMgr'>
+  <feature name='odl-unimgr' version='${project.version}'
+    description='OpenDaylight :: UniMgr'>
     <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
     <feature version='${ovsdb.version}'>odl-ovsdb-southbound-impl</feature>
     <feature version='${project.version}'>odl-unimgr-api</feature>
     <feature version='${project.version}'>odl-unimgr-presto-api</feature>
-    <!-- TODO these features should be dependencies of drivers not unimgr itself -->
+    <!-- TODO these features should be dependencies of drivers not unimgr 
+      itself -->
     <feature version='${netconf.version}'>odl-netconf-connector</feature>
     <feature version='${netconf.version}'>odl-netconf-connector-ssh</feature>
     <!-- FIXME deliver as a separate bundle/feature -->
@@ -43,17 +46,29 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <configfile finalname="${configfile.directory}/unimgr.xml">mvn:org.opendaylight.unimgr/unimgr-impl/{{VERSION}}/xml/config</configfile>
   </feature>
 
-  <feature name='odl-unimgr-console' version='${project.version}' description='OpenDaylight :: UniMgr :: CLI'>
-      <feature version="${project.version}">odl-unimgr</feature>
-      <bundle>mvn:org.opendaylight.unimgr/unimgr-cli/{{VERSION}}</bundle>
+  <feature name='odl-unimgr-netvirt' version='${project.version}'
+    description='OpenDaylight :: UniMgr - NetVirt'>
+    <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
+    <feature version='${project.version}'>odl-unimgr</feature>
+    <feature version='${genius.version}'>odl-genius-api</feature>
+    <feature version='${vpnservice.version}'>odl-netvirt-vpnservice-impl</feature>
+    <bundle>mvn:org.opendaylight.unimgr/unimgr-netvirt/{{VERSION}}</bundle>
+  </feature>
+
+  <feature name='odl-unimgr-console' version='${project.version}'
+    description='OpenDaylight :: UniMgr :: CLI'>
+    <feature version="${project.version}">odl-unimgr</feature>
+    <bundle>mvn:org.opendaylight.unimgr/unimgr-cli/{{VERSION}}</bundle>
   </feature>
 
-  <feature name='odl-unimgr-rest' version='${project.version}' description='OpenDaylight :: UniMgr :: REST'>
+  <feature name='odl-unimgr-rest' version='${project.version}'
+    description='OpenDaylight :: UniMgr :: REST'>
     <feature version="${project.version}">odl-unimgr</feature>
     <feature version="${restconf.version}">odl-restconf</feature>
   </feature>
 
-  <feature name='odl-unimgr-ui' version='${project.version}' description='OpenDaylight :: UniMgr :: UI'>
+  <feature name='odl-unimgr-ui' version='${project.version}'
+    description='OpenDaylight :: UniMgr :: UI'>
     <feature version="${project.version}">odl-unimgr-rest</feature>
     <feature version="${project.version}">odl-unimgr-console</feature>
     <feature version="${restconf.version}">odl-mdsal-apidocs</feature>
@@ -61,7 +76,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <feature version="${dlux.version}">odl-dlux-all</feature>
   </feature>
 
-  <feature name='odl-unimgr-cisco-xr-driver' version='${project.version}' description='OpenDaylight :: UniMgr :: Cisco XR Driver'>
+  <feature name='odl-unimgr-cisco-xr-driver' version='${project.version}'
+    description='OpenDaylight :: UniMgr :: Cisco XR Driver'>
     <feature version='${project.version}'>odl-unimgr</feature>
     <bundle>mvn:org.opendaylight.unimgr/cisco-xrmodels/{{VERSION}}</bundle>
     <bundle>mvn:org.opendaylight.unimgr/unimgr-cisco-xr-driver/{{VERSION}}</bundle>
index dd2802a67cee29e6d185ab48be7a1c4634beba69..4998f0915f9c98551ff693ce5377769f96719132 100644 (file)
@@ -40,7 +40,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
                 <artifactId>maven-bundle-plugin</artifactId>
                 <configuration>
                     <instructions>
-                        <Import-Package>*</Import-Package>
                         <Export-Package>
                             org.opendaylight.unimgr.mef.nrp.common,
                             org.opendaylight.unimgr.mef.nrp.api,
diff --git a/netvirt/pom.xml b/netvirt/pom.xml
new file mode 100644 (file)
index 0000000..ed0dad0
--- /dev/null
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (c) 2016 Hewlett Packard Enterprise, Co. 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.controller</groupId>
+    <artifactId>config-parent</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+    <relativePath />
+  </parent>
+
+  <properties>
+    <genius.version>0.1.0-SNAPSHOT</genius.version>
+    <vpnservices.version>0.3.0-SNAPSHOT</vpnservices.version>
+  </properties>
+
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.opendaylight.unimgr</groupId>
+  <artifactId>unimgr-netvirt</artifactId>
+  <version>0.1.0-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.8</source>
+          <target>1.8</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Import-Package>
+              *
+            </Import-Package>
+            <Export-Package>
+            </Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>unimgr-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>unimgr-impl</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.netvirt</groupId>
+      <artifactId>elanmanager-api</artifactId>
+      <version>${vpnservices.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>unimgr-legato-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <!-- Testing Dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-module-junit4</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-api-mockito</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-api-support</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-reflect</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.mdsal.model</groupId>
+      <artifactId>ietf-yang-types-20130715</artifactId>
+    </dependency>
+    <!-- dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> 
+      </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> 
+      </dependency -->
+
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+
+
+  </dependencies>
+</project>
diff --git a/netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/EvcListener.java b/netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/EvcListener.java
new file mode 100644 (file)
index 0000000..9cd73a4
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. 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.unimgr.mef.netvirt;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.mdsalutil.AbstractDataChangeListener;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
+import org.opendaylight.unimgr.command.EvcAddCommand;
+import org.opendaylight.unimgr.command.EvcRemoveCommand;
+import org.opendaylight.unimgr.command.EvcUpdateCommand;
+import org.opendaylight.unimgr.impl.UnimgrConstants;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.MefServices;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.MefService;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.Evc;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.Uni;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.uni.EvcUniCeVlans;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.services.rev150526.mef.services.mef.service.evc.unis.uni.evc.uni.ce.vlans.EvcUniCeVlan;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EvcListener extends UnimgrDataTreeChangeListener<Evc> {
+
+    private static final Logger log = LoggerFactory.getLogger(EvcListener.class);
+    private ListenerRegistration<EvcListener> evcListenerRegistration;
+
+    public EvcListener(final DataBroker dataBroker) {
+        super(dataBroker);
+
+        registerListener();
+    }
+
+    public void registerListener() {
+        try {
+            final DataTreeIdentifier<Evc> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
+                    getEvcTopologyPath());
+            evcListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
+            log.info("EvcDataTreeChangeListener created and registered");
+        } catch (final Exception e) {
+            log.error("Evc DataChange listener registration failed !", e);
+            throw new IllegalStateException("Evc registration Listener failed.", e);
+        }
+    }
+
+    private InstanceIdentifier<Evc> getEvcTopologyPath() {
+        return InstanceIdentifier.create(MefServices.class).child(MefService.class).child(Evc.class);
+    }
+
+    @Override
+    public void close() throws Exception {
+        evcListenerRegistration.close();
+    }
+
+    @Override
+    public void add(DataTreeModification<Evc> newDataObject) {
+        if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
+            log.info("evc {} created", newDataObject.getRootNode().getIdentifier());
+            addEvc(newDataObject);
+        }
+    }
+
+    @Override
+    public void remove(DataTreeModification<Evc> removedDataObject) {
+        if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
+            log.info("evc {} deleted", removedDataObject.getRootNode().getIdentifier());
+            removeEvc(removedDataObject);
+        }
+    }
+
+    @Override
+    public void update(DataTreeModification<Evc> modifiedDataObject) {
+        if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
+            log.info("evc {} updated", modifiedDataObject.getRootNode().getIdentifier());
+            updateEvc(modifiedDataObject);
+        }
+    }
+
+    private InstanceIdentifier<Evc> getWildCardPath() {
+        InstanceIdentifier<Evc> instanceIdentifier = InstanceIdentifier.create(MefServices.class)
+                .child(MefService.class).child(Evc.class);
+
+        return instanceIdentifier;
+    }
+
+    private void addEvc(DataTreeModification<Evc> newDataObject) {
+        try {
+            Evc data = newDataObject.getRootNode().getDataAfter();
+
+            String instanceName = data.getEvcId().getValue();
+
+            log.info("Adding elan instance: " + instanceName);
+            NetvirtUtils.createElanInstance(dataBroker, instanceName);
+
+            // Create elan interfaces
+            for (Uni uni : data.getUnis().getUni()) {
+                createUni(instanceName, uni);
+            }
+        } catch (final Exception e) {
+            log.error("Add evc failed !", e);
+        }
+    }
+
+    private void removeEvc(DataTreeModification<Evc> removedDataObject) {
+        try {
+            Evc data = removedDataObject.getRootNode().getDataBefore();
+
+            String instanceName = data.getEvcId().getValue();
+            
+            for(Uni uni : data.getUnis().getUni())
+            {
+                removeUni(instanceName, uni);
+            }
+            
+            log.info("Removing elan instance: " + instanceName);
+            NetvirtUtils.deleteElanInstance(dataBroker, instanceName);
+        } catch (final Exception e) {
+            log.error("Remove evc failed !", e);
+        }
+    }
+
+    private void updateEvc(DataTreeModification<Evc> modifiedDataObject) {
+        try {
+            Evc original = modifiedDataObject.getRootNode().getDataBefore();
+            Evc update = modifiedDataObject.getRootNode().getDataAfter();
+
+            String instanceName = original.getEvcId().getValue();
+
+            log.info("Updating elan instance: " + instanceName);
+
+            List<Uni> originalUni = original.getUnis().getUni();
+            List<Uni> updateUni = update.getUnis().getUni();
+            if (updateUni != null && !updateUni.isEmpty()) {
+                List<Uni> existingClonedUni = new ArrayList<>();
+                if (originalUni != null && !originalUni.isEmpty()) {
+                    existingClonedUni.addAll(0, originalUni);
+                    originalUni.removeAll(updateUni);
+                    updateUni.removeAll(existingClonedUni);
+                    // removing the Uni which are not presented in the updated
+                    // List
+                    for (Uni uni : originalUni) {
+                        removeUni(instanceName, uni);
+                    }
+                }
+
+                // Adding the new Uni which are presented in the updated List
+                if (updateUni.size() > 0) {
+                    for (Uni uni : updateUni) {
+                        createUni(instanceName, uni);
+                    }
+                }
+            } else if (originalUni != null && !originalUni.isEmpty()) {
+                for (Uni uni : originalUni) {
+                    removeUni(instanceName, uni);
+                }
+            }
+        } catch (final Exception e) {
+            log.error("Update evc failed !", e);
+        }
+    }
+
+    private void removeUni(String instanceName, Uni uni) {
+        String uniId = uni.getUniId().getValue();
+        EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
+
+        if (evcUniCeVlans != null && !evcUniCeVlans.getEvcUniCeVlan().isEmpty()) {
+            for (EvcUniCeVlan x : evcUniCeVlans.getEvcUniCeVlan()) {
+
+                String interfaceName = NetvirtUtils.getInterfaceNameForVlan(uniId, x.getVid().toString());
+                log.info("Removing elan interface: " + interfaceName);
+                NetvirtUtils.deleteElanInterface(dataBroker, instanceName, interfaceName);
+            }
+        } else {
+            log.info("Removing elan interface: " + uniId);
+            NetvirtUtils.deleteElanInterface(dataBroker, instanceName, uniId);
+        }
+    }
+
+    private void createUni(String instanceName, Uni uni) {
+        String uniId = uni.getUniId().getValue();
+        EvcUniCeVlans evcUniCeVlans = uni.getEvcUniCeVlans();
+
+        if (evcUniCeVlans != null && !evcUniCeVlans.getEvcUniCeVlan().isEmpty()) {
+            for (EvcUniCeVlan x : evcUniCeVlans.getEvcUniCeVlan()) {
+
+                String interfaceName = NetvirtUtils.getInterfaceNameForVlan(uniId, x.getVid().toString());
+
+                log.info("Adding elan interface: " + interfaceName);
+                NetvirtUtils.createElanInterface(dataBroker, instanceName, interfaceName);
+            }
+        } else {
+            log.info("Adding elan interface: " + uniId);
+            NetvirtUtils.createElanInterface(dataBroker, instanceName, uniId);
+        }
+    }
+}
diff --git a/netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/MdsalUtils.java b/netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/MdsalUtils.java
new file mode 100644 (file)
index 0000000..c712adc
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. 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.unimgr.mef.netvirt;
+
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.CheckedFuture;
+
+public class MdsalUtils {
+
+    private static final Logger logger = LoggerFactory.getLogger(MdsalUtils.class);
+
+    public static <T extends DataObject> void syncWrite(DataBroker broker, LogicalDatastoreType datastoreType,
+            InstanceIdentifier<T> path, T data) {
+        CheckedFuture<Void, TransactionCommitFailedException> futures = write(broker, datastoreType, path, data);
+        try {
+            futures.get();
+        } catch (InterruptedException | ExecutionException e) {
+            logger.error("Error writing to datastore (path, data) : ({}, {})", path, data);
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    public static <T extends DataObject> void syncUpdate(DataBroker broker, LogicalDatastoreType datastoreType,
+            InstanceIdentifier<T> path, T data) {
+        CheckedFuture<Void, TransactionCommitFailedException> futures = update(broker, datastoreType, path, data);
+        try {
+            futures.get();
+        } catch (InterruptedException | ExecutionException e) {
+            logger.error("Error writing to datastore (path, data) : ({}, {})", path, data);
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    public static <T extends DataObject> void syncDelete(DataBroker broker, LogicalDatastoreType datastoreType,
+            InstanceIdentifier<T> obj) {
+        CheckedFuture<Void, TransactionCommitFailedException> futures = delete(broker, datastoreType, obj);
+        try {
+            futures.get();
+        } catch (InterruptedException | ExecutionException e) {
+            logger.error("Error deleting from datastore (path) : ({})", obj);
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    public static <T extends DataObject> CheckedFuture<Void, TransactionCommitFailedException> write(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();
+        return futures;
+    }
+
+    public static <T extends DataObject> CheckedFuture<Void, TransactionCommitFailedException> update(DataBroker broker,
+            LogicalDatastoreType datastoreType, InstanceIdentifier<T> path, T data) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.merge(datastoreType, path, data, true);
+        CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
+        return futures;
+    }
+
+    public static <T extends DataObject> CheckedFuture<Void, TransactionCommitFailedException> delete(DataBroker broker,
+            LogicalDatastoreType datastoreType, InstanceIdentifier<T> obj) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.delete(datastoreType, obj);
+        CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
+        return futures;
+    }
+
+}
diff --git a/netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/NetvirtUtils.java b/netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/NetvirtUtils.java
new file mode 100644 (file)
index 0000000..6fa3b26
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2016 Hewlett Packard Enterprise, Co. 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.unimgr.mef.netvirt;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.MefInterfaces;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.Unis;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.Uni;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.interfaces.rev150526.mef.interfaces.unis.UniKey;
+import org.opendaylight.yang.gen.v1.http.metroethernetforum.org.ns.yang.mef.types.rev150526.Identifier45;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlanBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.util.concurrent.CheckedFuture;
+
+public class NetvirtUtils {
+    public static void createElanInstanceSync(DataBroker dataBroker, String instanceName) {
+
+        ElanInstanceBuilder einstBuilder = createElanInstance(instanceName);
+
+        MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                getElanInstanceInstanceIdentifier(instanceName), einstBuilder.build());
+    }
+
+    public static void createElanInterfaceSync(DataBroker dataBroker, String instanceName, String interfaceName) {
+        ElanInterfaceBuilder einterfaceBuilder = createElanInterface(instanceName, interfaceName);
+
+        MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                getElanInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
+    }
+
+    public static void updateElanInstanceSync(DataBroker dataBroker, String instanceName) {
+
+        ElanInstanceBuilder einstBuilder = createElanInstance(instanceName);
+
+        MdsalUtils.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                getElanInstanceInstanceIdentifier(instanceName), einstBuilder.build());
+    }
+
+    public static void updateElanInterfaceSync(DataBroker dataBroker, String instanceName, String interfaceName) {
+        ElanInterfaceBuilder einterfaceBuilder = createElanInterface(instanceName, interfaceName);
+
+        MdsalUtils.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                getElanInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
+    }
+
+    public static void deleteElanInstanceSync(DataBroker dataBroker, String instanceName) {
+        MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                getElanInstanceInstanceIdentifier(instanceName));
+    }
+
+    public static void deleteElanInterfaceSync(DataBroker dataBroker, String instanceName, String interfaceName) {
+        MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                getElanInterfaceInstanceIdentifier(interfaceName));
+    }
+
+    public static CheckedFuture createElanInstance(DataBroker dataBroker, String instanceName) {
+
+        ElanInstanceBuilder einstBuilder = createElanInstance(instanceName);
+
+        return MdsalUtils.write(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                getElanInstanceInstanceIdentifier(instanceName), einstBuilder.build());
+    }
+
+    public static void createElanInterface(DataBroker dataBroker, String instanceName, String interfaceName) {
+        ElanInterfaceBuilder einterfaceBuilder = createElanInterface(instanceName, interfaceName);
+
+        MdsalUtils.write(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                getElanInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
+    }
+
+    public static void updateElanInstance(DataBroker dataBroker, String instanceName) {
+
+        ElanInstanceBuilder einstBuilder = createElanInstance(instanceName);
+
+        MdsalUtils.update(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                getElanInstanceInstanceIdentifier(instanceName), einstBuilder.build());
+    }
+
+    public static void updateElanInterface(DataBroker dataBroker, String instanceName, String interfaceName) {
+        ElanInterfaceBuilder einterfaceBuilder = createElanInterface(instanceName, interfaceName);
+
+        MdsalUtils.update(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                getElanInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
+    }
+
+    public static void deleteElanInstance(DataBroker dataBroker, String instanceName) {
+        MdsalUtils.delete(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                getElanInstanceInstanceIdentifier(instanceName));
+    }
+
+    public static void deleteElanInterface(DataBroker dataBroker, String instanceName, String interfaceName) {
+        MdsalUtils.delete(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                getElanInterfaceInstanceIdentifier(interfaceName));
+    }
+
+    public static String getInterfaceNameForVlan(String uniId, String vlanId) {
+        return uniId + "#" + vlanId;
+    }
+
+    private static ElanInstanceBuilder createElanInstance(String instanceName) {
+        ElanInstanceBuilder einstBuilder = new ElanInstanceBuilder();
+        einstBuilder.setElanInstanceName(instanceName);
+        einstBuilder.setKey(new ElanInstanceKey(instanceName));
+        return einstBuilder;
+    }
+
+    private static ElanInterfaceBuilder createElanInterface(String instanceName, String interfaceName) {
+        ElanInterfaceBuilder einterfaceBuilder = new ElanInterfaceBuilder();
+        einterfaceBuilder.setElanInstanceName(instanceName);
+        einterfaceBuilder.setName(interfaceName);
+        return einterfaceBuilder;
+    }
+
+    private static InstanceIdentifier getElanInstanceInstanceIdentifier(String instanceName) {
+        return InstanceIdentifier.builder(ElanInstances.class)
+                .child(ElanInstance.class, new ElanInstanceKey(instanceName)).build();
+    }
+
+    private static InstanceIdentifier getElanInterfaceInstanceIdentifier(String interfaceName) {
+        return InstanceIdentifier.builder(ElanInterfaces.class)
+                .child(ElanInterface.class, new ElanInterfaceKey(interfaceName)).build();
+    }
+
+    private static InstanceIdentifier getUniInterfaceInstanceIdentifier(String interfaceName) {
+        return InstanceIdentifier.builder(MefInterfaces.class).child(Unis.class)
+                .child(Uni.class, new UniKey(new Identifier45(interfaceName))).build();
+    }
+}
diff --git a/netvirt/src/main/resources/org/opendaylight/blueprint/netvirt-driver.xml b/netvirt/src/main/resources/org/opendaylight/blueprint/netvirt-driver.xml
new file mode 100644 (file)
index 0000000..4b763f1
--- /dev/null
@@ -0,0 +1,16 @@
+<!-- Copyright (c) 2016 Hewlett Packard Enterprise, Co. and others. All rights 
+  reserved. This program and the accompanying materials are made available 
+  under the terms of the Eclipse Public License v1.0 which accompanies this 
+  distribution, and is available at http://www.eclipse.org/legal/epl-v10.html -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+  xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+  odl:use-default-for-reference-types="true">
+
+  <reference id="dataBroker"
+    interface="org.opendaylight.controller.md.sal.binding.api.DataBroker" />
+
+  <bean class="org.opendaylight.unimgr.mef.netvirt.EvcListener">
+    <argument index="0" ref="dataBroker" />
+  </bean>
+
+</blueprint>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index d6468c80e835610707649aa836072260287c5a5d..2f3cac5fe946b0def2573dfa0d86592122290ba1 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -61,6 +61,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
         <module>legato-api</module>
         <module>presto-api</module>
         <module>impl</module>
+        <module>netvirt</module>
         <module>cisco-xr-driver</module>
         <module>cli</module>
         <module>karaf</module>