Merge "Initial draft of vpn service"
authorVivek Srivastava <vivek.v.srivastava@ericsson.com>
Wed, 1 Apr 2015 09:44:17 +0000 (09:44 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 1 Apr 2015 09:44:17 +0000 (09:44 +0000)
vpnmanager-impl/pom.xml
vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/AbstractDataChangeListener.java [new file with mode: 0644]
vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java [new file with mode: 0644]
vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnManager.java [new file with mode: 0644]
vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnserviceProvider.java
vpnmanager-impl/src/test/java/org/opendaylight/vpnservice/test/MockDataChangedEvent.java [new file with mode: 0644]
vpnmanager-impl/src/test/java/org/opendaylight/vpnservice/test/VpnServiceTest.java [new file with mode: 0644]

index 59cd96d78e6cd1073558b8e4b4a6ca15ac5d9b79..d776200203849ec8abca87b31fd9693674fc7666 100644 (file)
@@ -1,31 +1,41 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: --><!--
-Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
-
-This program and the accompanying materials are made available under the
-terms of the Eclipse Public License v1.0 which accompanies this distribution,
-and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<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.3.0-SNAPSHOT</version>
-    <relativePath/>
-  </parent>
-
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>org.opendaylight.vpnservice</groupId>
-  <artifactId>vpnmanager-impl</artifactId>
-  <version>1.0-SNAPSHOT</version>
-  <packaging>bundle</packaging>
-  <dependencies>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>vpnmanager-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!-- vi: set et smarttab sw=4 tabstop=4: --><!--\r
+Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.\r
+\r
+This program and the accompanying materials are made available under the\r
+terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+and is available at http://www.eclipse.org/legal/epl-v10.html\r
+-->\r
+<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">\r
+\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>config-parent</artifactId>\r
+    <version>0.3.0-SNAPSHOT</version>\r
+    <relativePath/>\r
+  </parent>\r
+\r
+  <modelVersion>4.0.0</modelVersion>\r
+  <groupId>org.opendaylight.vpnservice</groupId>\r
+  <artifactId>vpnmanager-impl</artifactId>\r
+  <version>1.0-SNAPSHOT</version>\r
+  <packaging>bundle</packaging>\r
+  <dependencies>\r
+    <dependency>\r
+      <groupId>${project.groupId}</groupId>\r
+      <artifactId>vpnmanager-api</artifactId>\r
+      <version>${project.version}</version>\r
+    </dependency>\r
+           <!--  TEST Dependencies -->\r
+    <dependency>\r
+      <groupId>junit</groupId>\r
+      <artifactId>junit</artifactId>\r
+    </dependency>\r
+       <dependency>\r
+       <groupId>org.mockito</groupId>\r
+       <artifactId>mockito-all</artifactId>\r
+       <scope>test</scope>\r
+    </dependency>\r
+  </dependencies>\r
+\r
+</project>\r
diff --git a/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/AbstractDataChangeListener.java b/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/AbstractDataChangeListener.java
new file mode 100644 (file)
index 0000000..38530a7
--- /dev/null
@@ -0,0 +1,110 @@
+/*\r
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.vpnservice;\r
+\r
+import com.google.common.base.Optional;\r
+import com.google.common.base.Preconditions;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+\r
+import java.util.Collections;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+/**\r
+ * AbstractDataChangeListener implemented basic {@link DataChangeListener} processing for\r
+ * VPN related Data Objects.\r
+ */\r
+public abstract class AbstractDataChangeListener <T extends DataObject> implements DataChangeListener {\r
+\r
+    protected final Class<T> clazz;\r
+\r
+    public AbstractDataChangeListener(Class<T> clazz) {\r
+        this.clazz = Preconditions.checkNotNull(clazz, "Class can not be null!");\r
+    }\r
+\r
+    @Override\r
+    public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {\r
+        Preconditions.checkNotNull(changeEvent,"Async ChangeEvent can not be null!");\r
+\r
+        /* All DataObjects for create */\r
+        final Map<InstanceIdentifier<?>, DataObject> createdData = changeEvent.getCreatedData() != null\r
+                ? changeEvent.getCreatedData() : Collections.<InstanceIdentifier<?>, DataObject> emptyMap();\r
+        /* All DataObjects for remove */\r
+        final Set<InstanceIdentifier<?>> removeData = changeEvent.getRemovedPaths() != null\r
+                ? changeEvent.getRemovedPaths() : Collections.<InstanceIdentifier<?>> emptySet();\r
+        /* All DataObjects for updates */\r
+        final Map<InstanceIdentifier<?>, DataObject> updateData = changeEvent.getUpdatedData() != null\r
+                ? changeEvent.getUpdatedData() : Collections.<InstanceIdentifier<?>, DataObject> emptyMap();\r
+        /* All Original DataObjects */\r
+        final Map<InstanceIdentifier<?>, DataObject> originalData = changeEvent.getOriginalData() != null\r
+                ? changeEvent.getOriginalData() : Collections.<InstanceIdentifier<?>, DataObject> emptyMap();\r
+\r
+        this.createData(createdData);\r
+        this.updateData(updateData, originalData);\r
+        this.removeData(removeData, originalData);\r
+    }\r
+\r
+    @SuppressWarnings("unchecked")\r
+    private void createData(final Map<InstanceIdentifier<?>, DataObject> createdData) {\r
+        final Set<InstanceIdentifier<?>> keys = createdData.keySet() != null\r
+                ? createdData.keySet() : Collections.<InstanceIdentifier<?>> emptySet();\r
+        for (InstanceIdentifier<?> key : keys) {\r
+            if (clazz.equals(key.getTargetType())) {\r
+                 InstanceIdentifier<T> createKeyIdent = key.firstIdentifierOf(clazz);\r
+                 final Optional<DataObject> value = Optional.of(createdData.get(key));\r
+                 if (value.isPresent()) {\r
+                     this.add(createKeyIdent, (T)value.get());\r
+                 }\r
+            }\r
+        }\r
+    }\r
+\r
+    @SuppressWarnings("unchecked")\r
+    private void updateData(final Map<InstanceIdentifier<?>, DataObject> updateData,\r
+            final Map<InstanceIdentifier<?>, DataObject> originalData) {\r
+\r
+        final Set<InstanceIdentifier<?>> keys = updateData.keySet() != null\r
+                ? updateData.keySet() : Collections.<InstanceIdentifier<?>> emptySet();\r
+        for (InstanceIdentifier<?> key : keys) {\r
+          if (clazz.equals(key.getTargetType())) {\r
+              InstanceIdentifier<T> updateKeyIdent = key.firstIdentifierOf(clazz);\r
+              final Optional<DataObject> value = Optional.of(updateData.get(key));\r
+              final Optional<DataObject> original = Optional.of(originalData.get(key));\r
+              if (value.isPresent() && original.isPresent()) {\r
+                this.update(updateKeyIdent, (T)original.get(), (T)value.get());\r
+              }\r
+          }\r
+        }\r
+    }\r
+\r
+    @SuppressWarnings("unchecked")\r
+    private void removeData(final Set<InstanceIdentifier<?>> removeData,\r
+            final Map<InstanceIdentifier<?>, DataObject> originalData) {\r
+\r
+        for (InstanceIdentifier<?> key : removeData) {\r
+            if (clazz.equals(key.getTargetType())) {\r
+                   final InstanceIdentifier<T> ident = key.firstIdentifierOf(clazz);\r
+                    final DataObject removeValue = originalData.get(key);\r
+                    this.remove(ident, (T)removeValue);\r
+            }\r
+        }\r
+    }\r
+\r
+    protected abstract void remove(InstanceIdentifier<T> identifier, T del);\r
+\r
+    protected abstract void update(InstanceIdentifier<T> identifier, T original, T update);\r
+\r
+    protected abstract void add(InstanceIdentifier<T> identifier, T add);\r
+\r
+}\r
+\r
+\r
diff --git a/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java b/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java
new file mode 100644 (file)
index 0000000..ae286b6
--- /dev/null
@@ -0,0 +1,157 @@
+/*\r
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.vpnservice;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.concurrent.Future;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;\r
+import org.opendaylight.yangtools.concepts.ListenerRegistration;\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.NextHopList;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.next.hop.list.*;\r
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInterface1;\r
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;\r
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.google.common.base.Optional;\r
+import com.google.common.collect.FluentIterable;\r
+\r
+public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface> implements AutoCloseable{\r
+    private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceManager.class);\r
+    private ListenerRegistration<DataChangeListener> listenerRegistration;\r
+    private final DataBroker broker;\r
+    \r
+    public VpnInterfaceManager(final DataBroker db) {\r
+        super(VpnInterface.class);\r
+        broker = db;\r
+        registerListener(db);\r
+    }\r
+\r
+    @Override\r
+    public void close() throws Exception {\r
+        if (listenerRegistration != null) {\r
+            try {\r
+                listenerRegistration.close();\r
+            } catch (final Exception e) {\r
+                LOG.error("Error when cleaning up DataChangeListener.", e);\r
+            }\r
+            listenerRegistration = null;\r
+        }\r
+        LOG.info("VPN Interface Manager Closed");\r
+    }\r
+    \r
+    private void registerListener(final DataBroker db) {\r
+        try {\r
+            listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,\r
+                    getWildCardPath(), VpnInterfaceManager.this, DataChangeScope.SUBTREE);\r
+        } catch (final Exception e) {\r
+            LOG.error("VPN Service DataChange listener registration fail!", e);\r
+            throw new IllegalStateException("VPN Service registration Listener failed.", e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected void add(final InstanceIdentifier<VpnInterface> identifier,\r
+            final VpnInterface vpnInterface) {\r
+        LOG.info("key: " + identifier + ", value=" + vpnInterface );\r
+        addInterface(identifier, vpnInterface);\r
+    }\r
+\r
+    private void addInterface(final InstanceIdentifier<VpnInterface> identifier,\r
+                              final VpnInterface vpnInterface) {\r
+        final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);\r
+        String interfaceName = key.getName();\r
+        InstanceIdentifierBuilder<Interface> idBuilder = \r
+                InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));\r
+        InstanceIdentifier<Interface> id = idBuilder.build();\r
+        Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);\r
+        if(port.isPresent()) {\r
+            Interface interf = port.get();\r
+            bindServiceOnInterface(interf);\r
+            updateNextHops(identifier);\r
+        }\r
+    }\r
+\r
+    private void updateNextHops(final InstanceIdentifier<VpnInterface> identifier) {\r
+        //Read NextHops\r
+        InstanceIdentifier<VpnInterface1> path = identifier.augmentation(VpnInterface1.class);\r
+        Optional<VpnInterface1> nextHopList = read(LogicalDatastoreType.CONFIGURATION, path);\r
+        \r
+        if(nextHopList.isPresent()) {\r
+            List<L3NextHops> nextHops = nextHopList.get().getL3NextHops();\r
+            \r
+            if(!nextHops.isEmpty()) {\r
+                LOG.info("NextHops are "+ nextHops);\r
+                for(L3NextHops nextHop : nextHops) {\r
+                    //TODO: Generate label for the prefix and store it in the next hop model\r
+                    \r
+                    //TODO: Update BGP\r
+                    updatePrefixToBGP(nextHop);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    private void bindServiceOnInterface(Interface intf) {\r
+        //TODO: Create Ingress flow on the interface to bind the VPN service\r
+    }\r
+\r
+    private void updatePrefixToBGP(L3NextHops nextHop) {\r
+        //TODO: Update the Prefix to BGP\r
+    }\r
+\r
+    private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,\r
+            InstanceIdentifier<T> path) {\r
+\r
+        ReadOnlyTransaction tx = broker.newReadOnlyTransaction();\r
+\r
+        Optional<T> result = Optional.absent();\r
+        try {\r
+            result = tx.read(datastoreType, path).get();\r
+        } catch (Exception e) {\r
+            throw new RuntimeException(e);\r
+        }\r
+\r
+        return result;\r
+    }\r
+\r
+    private InstanceIdentifier<VpnInterface> getWildCardPath() {\r
+        return InstanceIdentifier.create(VpnInterfaces.class).child(VpnInterface.class);\r
+    }\r
+\r
+    @Override\r
+    protected void remove( InstanceIdentifier<VpnInterface> identifier, VpnInterface del) {\r
+        // TODO Auto-generated method stub\r
+\r
+    }\r
+\r
+    @Override\r
+    protected void update(InstanceIdentifier<VpnInterface> identifier, \r
+                                   VpnInterface original, VpnInterface update) {\r
+        // TODO Auto-generated method stub\r
+\r
+    }\r
+\r
+}\r
diff --git a/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnManager.java b/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnManager.java
new file mode 100644 (file)
index 0000000..7a957af
--- /dev/null
@@ -0,0 +1,87 @@
+/*\r
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.vpnservice;\r
+\r
+import java.util.Collections;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;\r
+import org.opendaylight.yangtools.concepts.ListenerRegistration;\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;\r
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.google.common.base.Optional;\r
+import com.google.common.base.Preconditions;\r
+\r
+public class VpnManager extends AbstractDataChangeListener<VpnInstance> implements AutoCloseable{\r
+    private static final Logger LOG = LoggerFactory.getLogger(VpnManager.class);\r
+    private ListenerRegistration<DataChangeListener> listenerRegistration;\r
+    private final DataBroker broker;\r
+\r
+    public VpnManager(final DataBroker db) {\r
+        super(VpnInstance.class);\r
+        broker = db;\r
+        registerListener(db);\r
+    }\r
+\r
+    private void registerListener(final DataBroker db) {\r
+        try {\r
+            listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,\r
+                    getWildCardPath(), VpnManager.this, DataChangeScope.SUBTREE);\r
+        } catch (final Exception e) {\r
+            LOG.error("VPN Service DataChange listener registration fail!", e);\r
+            throw new IllegalStateException("VPN Service registration Listener failed.", e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected void remove(InstanceIdentifier<VpnInstance> identifier,\r
+            VpnInstance del) {\r
+        // TODO Auto-generated method stub\r
+    }\r
+\r
+    @Override\r
+    protected void update(InstanceIdentifier<VpnInstance> identifier,\r
+            VpnInstance original, VpnInstance update) {\r
+        // TODO Auto-generated method stub\r
+    }\r
+\r
+    @Override\r
+    protected void add(InstanceIdentifier<VpnInstance> identifier,\r
+            VpnInstance value) {\r
+        LOG.info("key: " + identifier + ", value=" + value);\r
+        //TODO: Generate VPN ID for this instance, where to store in model ... ?\r
+\r
+        //TODO: Add VRF to BGP\r
+    }\r
+\r
+    private InstanceIdentifier<?> getWildCardPath() {\r
+        return InstanceIdentifier.create(VpnInstances.class).child(VpnInstance.class);\r
+    }\r
+\r
+    @Override\r
+    public void close() throws Exception {\r
+        if (listenerRegistration != null) {\r
+            try {\r
+                listenerRegistration.close();\r
+            } catch (final Exception e) {\r
+                LOG.error("Error when cleaning up DataChangeListener.", e);\r
+            }\r
+            listenerRegistration = null;\r
+        }\r
+        LOG.info("VPN Manager Closed");\r
+    }\r
+}\r
index ef4223ff91e7635c4c19ce9ffa0be295cb0208b0..1ad8b59385261b29377e6c43c3fb01972e5911b7 100644 (file)
@@ -1,29 +1,41 @@
-/*
- * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.vpnservice;
-
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class VpnserviceProvider implements BindingAwareProvider, AutoCloseable {
-
-    private static final Logger LOG = LoggerFactory.getLogger(VpnserviceProvider.class);
-
-    @Override
-    public void onSessionInitiated(ProviderContext session) {
-        LOG.info("VpnserviceProvider Session Initiated");
-    }
-
-    @Override
-    public void close() throws Exception {
-        LOG.info("VpnserviceProvider Closed");
-    }
-
-}
+/*\r
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.vpnservice;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;\r
+import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;\r
+\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+public class VpnserviceProvider implements BindingAwareProvider,\r
+                                                       AutoCloseable {\r
+\r
+    private static final Logger LOG = LoggerFactory.getLogger(VpnserviceProvider.class);\r
+    private VpnInterfaceManager vpnInterfaceManager;\r
+    private VpnManager vpnManager;\r
+\r
+    @Override\r
+    public void onSessionInitiated(ProviderContext session) {\r
+        LOG.info("VpnserviceProvider Session Initiated");\r
+        try {\r
+            final  DataBroker dataBroker = session.getSALService(DataBroker.class);\r
+            vpnManager = new VpnManager(dataBroker);\r
+            vpnInterfaceManager = new VpnInterfaceManager(dataBroker);\r
+        } catch(Exception e) {\r
+            LOG.error("Error initializing services", e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void close() throws Exception {\r
+        vpnManager.close();\r
+        vpnInterfaceManager.close();\r
+    }\r
+}\r
diff --git a/vpnmanager-impl/src/test/java/org/opendaylight/vpnservice/test/MockDataChangedEvent.java b/vpnmanager-impl/src/test/java/org/opendaylight/vpnservice/test/MockDataChangedEvent.java
new file mode 100644 (file)
index 0000000..5e03dea
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.vpnservice.test;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+\r
+class MockDataChangedEvent implements AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> {\r
+  Map<InstanceIdentifier<?>,DataObject> created = new HashMap<>();\r
+  Map<InstanceIdentifier<?>,DataObject> updated = new HashMap<>();\r
+  Map<InstanceIdentifier<?>,DataObject> original = new HashMap<>();\r
+  Set<InstanceIdentifier<?>> removed = new HashSet<>();\r
+\r
+  @Override\r
+  public Map<InstanceIdentifier<?>, DataObject> getCreatedData() {\r
+      return created;\r
+  }\r
+\r
+  @Override\r
+  public Map<InstanceIdentifier<?>, DataObject> getUpdatedData() {\r
+      return updated;\r
+  }\r
+\r
+  @Override\r
+  public Set<InstanceIdentifier<?>> getRemovedPaths() {\r
+      return removed;\r
+  }\r
+\r
+  @Override\r
+  public Map<InstanceIdentifier<?>, DataObject> getOriginalData() {\r
+      return original;\r
+  }\r
+\r
+  @Override\r
+  public DataObject getOriginalSubtree() {\r
+      throw new UnsupportedOperationException("Not implemented by mock");\r
+  }\r
+\r
+  @Override\r
+  public DataObject getUpdatedSubtree() {\r
+      throw new UnsupportedOperationException("Not implemented by mock");\r
+  }\r
+}\r
diff --git a/vpnmanager-impl/src/test/java/org/opendaylight/vpnservice/test/VpnServiceTest.java b/vpnmanager-impl/src/test/java/org/opendaylight/vpnservice/test/VpnServiceTest.java
new file mode 100644 (file)
index 0000000..a28c298
--- /dev/null
@@ -0,0 +1,75 @@
+/*\r
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.vpnservice.test;\r
+\r
+import static org.junit.Assert.*;\r
+import static org.mockito.Matchers.*;\r
+import static org.mockito.Mockito.when;\r
+\r
+import org.junit.*;\r
+import org.junit.runner.RunWith;\r
+import org.mockito.Mock;\r
+import org.mockito.runners.MockitoJUnitRunner;\r
+\r
+import org.opendaylight.vpnservice.VpnManager;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yangtools.concepts.ListenerRegistration;\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;\r
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.*;\r
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.*;\r
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.apply.label.apply.label.mode.*;\r
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.apply.label.ApplyLabelMode;\r
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.ApplyLabelBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance.Ipv4FamilyBuilder;\r
+\r
+@RunWith(MockitoJUnitRunner.class)\r
+public class VpnServiceTest {\r
+    @Mock DataBroker dataBroker;\r
+    @Mock ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;\r
+    MockDataChangedEvent event;\r
+\r
+    @Before\r
+    public void setUp() throws Exception {\r
+        when(dataBroker.registerDataChangeListener(\r
+                any(LogicalDatastoreType.class),\r
+                any(InstanceIdentifier.class),\r
+                any(DataChangeListener.class),\r
+                any(DataChangeScope.class)))\r
+                .thenReturn(dataChangeListenerRegistration);\r
+        event = new MockDataChangedEvent();\r
+    }\r
+\r
+    @Test\r
+    public void test() {\r
+        VpnInstanceBuilder builder = new VpnInstanceBuilder().setKey(new VpnInstanceKey("Vpn1")).\r
+                setIpv4Family(new Ipv4FamilyBuilder().setRouteDistinguisher("100:1").setImportRoutePolicy("100:2").\r
+                    setExportRoutePolicy("100:1").setApplyLabel(new ApplyLabelBuilder().setApplyLabelMode(\r
+                        new PerRouteBuilder().setApplyLabelPerRoute(true).build()).build()).build());\r
+        VpnInstance instance = builder.build();\r
+        VpnManager vpnManager = new VpnManager(dataBroker);\r
+        event.created.put(createVpnId("Vpn1"), instance);\r
+        vpnManager.onDataChanged(event);\r
+    }\r
+\r
+    private InstanceIdentifier<VpnInstance> createVpnId(String name) {\r
+       InstanceIdentifierBuilder<VpnInstance> idBuilder = \r
+           InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class, new VpnInstanceKey(name));\r
+       InstanceIdentifier<VpnInstance> id = idBuilder.build();\r
+       return id;\r
+    }\r
+\r
+}\r