-<?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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
-/*
- * 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
--- /dev/null
+/*\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
--- /dev/null
+/*\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