Baseline for neutron-vpp mapping 72/38372/25
authorTomas Cechvala <tcechval@cisco.com>
Wed, 25 May 2016 16:16:04 +0000 (18:16 +0200)
committerMartin Sunal <msunal@cisco.com>
Fri, 27 May 2016 13:27:36 +0000 (13:27 +0000)
Initial implementation of neutron-vpp mapper
Initial yang for vpp renderer

Change-Id: Ief0fbc85e68f9c094c9c0ca6687c132cbd8ca6ea
Signed-off-by: Tomas Cechvala <tcechval@cisco.com>
19 files changed:
artifacts/pom.xml
features/pom.xml
features/src/main/features/features.xml
neutron-vpp-mapper/pom.xml [new file with mode: 0644]
neutron-vpp-mapper/src/main/config/default-config.xml [new file with mode: 0644]
neutron-vpp-mapper/src/main/java/org/opendaylight/controller/config/yang/config/neutron_vpp_mapper/impl/NeutronVppMapperModule.java [new file with mode: 0644]
neutron-vpp-mapper/src/main/java/org/opendaylight/controller/config/yang/config/neutron_vpp_mapper/impl/NeutronVppMapperModuleFactory.java [new file with mode: 0644]
neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/NeutronVppMapper.java [new file with mode: 0644]
neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/BaseEndpointByPortListener.java [new file with mode: 0644]
neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/MappingProvider.java [new file with mode: 0644]
neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/NeutronListener.java [new file with mode: 0644]
neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandler.java [new file with mode: 0644]
neutron-vpp-mapper/src/main/yang/neutron-vpp-mapper-impl.yang [new file with mode: 0644]
neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/NeutronListenerTest.java [new file with mode: 0644]
neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandlerTest.java [new file with mode: 0644]
neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/TestUtils.java [new file with mode: 0644]
pom.xml
renderers/vpp/pom.xml
renderers/vpp/src/main/yang/vpp-renderer.yang [new file with mode: 0644]

index 93101c44ab947e5ec7cc320946cdc5611e4539d8..c8d26b90bcb2eead9c5918921da08a507c87a542 100755 (executable)
         <artifactId>neutron-mapper</artifactId>
         <version>${project.version}</version>
       </dependency>
+      <dependency>
+        <groupId>${project.groupId}</groupId>
+        <artifactId>neutron-vpp-mapper</artifactId>
+        <version>${project.version}</version>
+      </dependency>
       <dependency>
         <groupId>${project.groupId}</groupId>
         <artifactId>neutron-ovsdb</artifactId>
         <type>xml</type>
         <classifier>config</classifier>
       </dependency>
+      <dependency>
+        <groupId>${project.groupId}</groupId>
+        <artifactId>neutron-vpp-mapper</artifactId>
+        <version>${project.version}</version>
+        <type>xml</type>
+        <classifier>config</classifier>
+      </dependency>
       <dependency>
         <groupId>${project.groupId}</groupId>
         <artifactId>neutron-ovsdb</artifactId>
index fd26227806d5ed27910986c5e15db3232981aa47..72cc9ac6362faa2b299602a608c835c152eaafb7 100755 (executable)
       <groupId>org.opendaylight.groupbasedpolicy</groupId>
       <artifactId>neutron-mapper</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.groupbasedpolicy</groupId>
+      <artifactId>neutron-vpp-mapper</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.groupbasedpolicy</groupId>
       <artifactId>neutron-ovsdb</artifactId>
       <type>xml</type>
       <classifier>config</classifier>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.groupbasedpolicy</groupId>
+      <artifactId>neutron-vpp-mapper</artifactId>
+      <type>xml</type>
+      <classifier>config</classifier>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.groupbasedpolicy</groupId>
       <artifactId>neutron-ovsdb</artifactId>
index 0177b8b1d56d2f5484f7511ba7f8eb5725d0a3ea..379b1c9198662cc9848b133645006bd2aa28256d 100755 (executable)
         <configfile finalname="${config.configfile.directory}/15-vpp-renderer.xml">mvn:org.opendaylight.groupbasedpolicy/vpp-renderer/{{VERSION}}/xml/config</configfile>
     </feature>
 
+    <!--
+        The Neutron-VPP provider
+    -->
+    <feature name='odl-groupbasedpolicy-neutron-vpp-mapper' version='${project.version}' description='OpenDaylight :: groupbasedpolicy :: Neutron Mapper mapps neutron APIs to GBP APIs '>
+        <feature version="${project.version}">odl-groupbasedpolicy-neutronmapper</feature>
+        <feature version="${project.version}">odl-groupbasedpolicy-vpp</feature>
+        <bundle>mvn:org.opendaylight.groupbasedpolicy/neutron-vpp-mapper/{{VERSION}}</bundle>
+        <configfile finalname="${config.configfile.directory}/15-neutron-vpp-mapper.xml">mvn:org.opendaylight.groupbasedpolicy/neutron-vpp-mapper/{{VERSION}}/xml/config</configfile>
+    </feature>
+
     <!--
          The UI Backend
     -->
diff --git a/neutron-vpp-mapper/pom.xml b/neutron-vpp-mapper/pom.xml
new file mode 100644 (file)
index 0000000..705cbc8
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0"?>
+<!-- Copyright (c) 2015 Cisco Systems, Inc. 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
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+  xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>config-parent</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>org.opendaylight.groupbasedpolicy</groupId>
+  <artifactId>neutron-vpp-mapper</artifactId>
+  <version>0.4.0-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <properties>
+    <neutron.version>0.7.0-SNAPSHOT</neutron.version>
+  </properties>
+
+  <dependencies>
+    <!-- project specific dependencies -->
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>groupbasedpolicy</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>neutron-mapper</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.neutron</groupId>
+      <artifactId>neutron-spi</artifactId>
+      <version>${neutron.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.groupbasedpolicy</groupId>
+      <artifactId>vpp-renderer</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.opendaylight.controller</groupId>
+      <artifactId>sal-binding-broker-impl</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.mdsal.model</groupId>
+      <artifactId>ietf-yang-types-20130715</artifactId>
+    </dependency>
+  </dependencies>
+
+ <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+         <!--   <Export-Package>
+            </Export-Package> -->
+            <Import-Package>*</Import-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file
diff --git a/neutron-vpp-mapper/src/main/config/default-config.xml b/neutron-vpp-mapper/src/main/config/default-config.xml
new file mode 100644 (file)
index 0000000..2a196a5
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<snapshot>
+    <configuration>
+        <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <module>
+                    <type xmlns:neutron-vpp-mapper="urn:opendaylight:params:xml:ns:yang:controller:config:neutron-vpp-mapper:impl">
+                        neutron-vpp-mapper:neutron-vpp-mapper-impl
+                    </type>
+                    <name>neutron-vpp-mapper-impl</name>
+                    <rpc-registry>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+                        <name>binding-rpc-broker</name>
+                    </rpc-registry>
+                    <data-broker>
+                      <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
+                      <name>binding-data-broker</name>
+                    </data-broker>
+                </module>
+            </modules>
+        </data>
+    </configuration>
+    <required-capabilities>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:neutron-vpp-mapper:impl?module=neutron-vpp-mapper-impl&amp;revision=2016-04-25</capability>
+    </required-capabilities>
+</snapshot>
diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/controller/config/yang/config/neutron_vpp_mapper/impl/NeutronVppMapperModule.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/controller/config/yang/config/neutron_vpp_mapper/impl/NeutronVppMapperModule.java
new file mode 100644 (file)
index 0000000..6723613
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. 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.controller.config.yang.config.neutron_vpp_mapper.impl;
+
+import org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.NeutronVppMapper;
+
+public class NeutronVppMapperModule extends org.opendaylight.controller.config.yang.config.neutron_vpp_mapper.impl.AbstractNeutronVppMapperModule {
+    public NeutronVppMapperModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public NeutronVppMapperModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.config.neutron_vpp_mapper.impl.NeutronVppMapperModule oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        NeutronVppMapper neutronVppMapper = new NeutronVppMapper(getDataBrokerDependency());
+        return neutronVppMapper;
+    }
+
+}
diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/controller/config/yang/config/neutron_vpp_mapper/impl/NeutronVppMapperModuleFactory.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/controller/config/yang/config/neutron_vpp_mapper/impl/NeutronVppMapperModuleFactory.java
new file mode 100644 (file)
index 0000000..b1c9cc5
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. 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
+ */
+/*
+* Generated file
+*
+* Generated from: yang module name: neutron-vpp-mapper-impl yang module local name: neutron-vpp-mapper-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Mon May 02 12:30:34 CEST 2016
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.config.neutron_vpp_mapper.impl;
+public class NeutronVppMapperModuleFactory extends org.opendaylight.controller.config.yang.config.neutron_vpp_mapper.impl.AbstractNeutronVppMapperModuleFactory {
+
+}
diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/NeutronVppMapper.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/NeutronVppMapper.java
new file mode 100644 (file)
index 0000000..70f859f
--- /dev/null
@@ -0,0 +1,30 @@
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. 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
+\r
+package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors.NeutronListener;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+public class NeutronVppMapper implements AutoCloseable {\r
+\r
+    NeutronListener neutronListener;\r
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronVppMapper.class);\r
+\r
+    public NeutronVppMapper(DataBroker dataBroker) {\r
+        neutronListener = new NeutronListener(dataBroker);\r
+        LOG.info("Neutron VPP started!");\r
+    }\r
+\r
+    @Override\r
+    public void close() throws Exception {\r
+        neutronListener.close();\r
+    }\r
+}\r
diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/BaseEndpointByPortListener.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/BaseEndpointByPortListener.java
new file mode 100644 (file)
index 0000000..31f7050
--- /dev/null
@@ -0,0 +1,77 @@
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. 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
+\r
+package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.GbpByNeutronMappings;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.BaseEndpointsByPorts;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+\r
+public class BaseEndpointByPortListener extends DataTreeChangeHandler<BaseEndpointByPort> implements MappingProvider<Port> {\r
+\r
+    private final PortHandler portHandler;\r
+\r
+    protected BaseEndpointByPortListener(PortHandler portHandler, DataBroker dataProvider) {\r
+        super(dataProvider);\r
+        this.portHandler = portHandler;\r
+        registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,\r
+                InstanceIdentifier.builder(Mappings.class)\r
+                    .child(GbpByNeutronMappings.class)\r
+                    .child(BaseEndpointsByPorts.class)\r
+                    .child(BaseEndpointByPort.class)\r
+                    .build()));\r
+    }\r
+\r
+    @Override\r
+    public InstanceIdentifier<Port> getNeutronDtoIid() {\r
+        return portHandler.createWildcartedPortIid();\r
+    }\r
+\r
+    @Override\r
+    public void processCreatedNeutronDto(Port port) {\r
+        portHandler.processCreated(port);\r
+    }\r
+\r
+    @Override\r
+    public void processUpdatedNeutronDto(Port original, Port delta) {\r
+        portHandler.processUpdated(original, delta);\r
+    }\r
+\r
+    @Override\r
+    public void processDeletedNeutronDto(Port port) {\r
+        // handled by BaseEndpointByPort removal\r
+    }\r
+\r
+    @Override\r
+    protected void onWrite(DataObjectModification<BaseEndpointByPort> rootNode,\r
+            InstanceIdentifier<BaseEndpointByPort> rootIdentifier) {\r
+        if (rootNode.getDataBefore() == null) {\r
+            portHandler.processCreated(rootNode.getDataAfter());\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected void onDelete(DataObjectModification<BaseEndpointByPort> rootNode,\r
+            InstanceIdentifier<BaseEndpointByPort> rootIdentifier) {\r
+        portHandler.processDeleted(rootNode.getDataBefore());\r
+    }\r
+\r
+    @Override\r
+    protected void onSubtreeModified(DataObjectModification<BaseEndpointByPort> rootNode,\r
+            InstanceIdentifier<BaseEndpointByPort> rootIdentifier) {\r
+        // update should not happen\r
+    }\r
+}\r
diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/MappingProvider.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/MappingProvider.java
new file mode 100644 (file)
index 0000000..794dfac
--- /dev/null
@@ -0,0 +1,23 @@
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. 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
+\r
+package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors;\r
+\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+\r
+interface MappingProvider<T extends DataObject> {\r
+\r
+    InstanceIdentifier<T> getNeutronDtoIid();\r
+\r
+    void processCreatedNeutronDto(T t);\r
+\r
+    void processUpdatedNeutronDto(T original, T delta);\r
+\r
+    void processDeletedNeutronDto(T t);\r
+}\r
diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/NeutronListener.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/NeutronListener.java
new file mode 100644 (file)
index 0000000..d8b5073
--- /dev/null
@@ -0,0 +1,122 @@
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. 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
+\r
+package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors;\r
+\r
+import java.io.Closeable;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.LinkedHashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+import java.util.concurrent.ExecutionException;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;\r
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;\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.PathArgument;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.google.common.collect.Iterators;\r
+import com.google.common.collect.PeekingIterator;\r
+\r
+public class NeutronListener implements DataTreeChangeListener<Neutron>, Closeable {\r
+\r
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronListener.class);\r
+\r
+    private final Set<MappingProvider<? extends DataObject>> dataChangeProviders = new LinkedHashSet<>();\r
+    protected ListenerRegistration<NeutronListener> registeredListener;\r
+\r
+    public NeutronListener(DataBroker dataBroker) {\r
+        registerHandlersAndListeners(dataBroker);\r
+        registeredListener = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(\r
+                LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(Neutron.class).build()), this);\r
+    }\r
+\r
+    private void registerHandlersAndListeners(DataBroker dataBroker) {\r
+        PortHandler portHandler = new PortHandler(dataBroker);\r
+        dataChangeProviders.add(new BaseEndpointByPortListener(portHandler, dataBroker));\r
+    }\r
+\r
+    @Override\r
+    public void onDataTreeChanged(Collection<DataTreeModification<Neutron>> changes) {\r
+        for (DataTreeModification<Neutron> change : changes) {\r
+            DataObjectModification<Neutron> rootNode = change.getRootNode();\r
+            for (MappingProvider<? extends DataObject> provider : dataChangeProviders) {\r
+                for (DataObjectModification<? extends DataObject> modDto : findModifiedData(provider, rootNode)) {\r
+                    try {\r
+                        processChangedData(modDto, modDto.getModificationType(), provider);\r
+                    } catch (InterruptedException | ExecutionException e) {\r
+                        LOG.error("Failed to process {} modification of node: {}. {}", modDto.getModificationType(),\r
+                                modDto.getIdentifier(), e.getStackTrace());\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    List<DataObjectModification<? extends DataObject>> findModifiedData(MappingProvider<? extends DataObject> provider,\r
+            DataObjectModification<Neutron> rootNode) {\r
+        List<DataObjectModification<? extends DataObject>> modDtos = new ArrayList<>();\r
+        PeekingIterator<PathArgument> pathArgs = Iterators.peekingIterator(provider.getNeutronDtoIid()\r
+            .getPathArguments()\r
+            .iterator());\r
+        DataObjectModification<? extends DataObject> modifDto = rootNode;\r
+        while (pathArgs.hasNext()) {\r
+            pathArgs.next();\r
+            for (DataObjectModification<? extends DataObject> childDto : modifDto.getModifiedChildren()) {\r
+                if (pathArgs.hasNext() && childDto.getDataType().equals(pathArgs.peek().getType())) {\r
+                    if (childDto.getDataType().equals(provider.getNeutronDtoIid().getTargetType())) {\r
+                        modDtos.add(childDto);\r
+                    } else {\r
+                        modifDto = childDto;\r
+                        break;\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return modDtos;\r
+    }\r
+\r
+    @SuppressWarnings("unchecked")\r
+    <T extends DataObject> void processChangedData(DataObjectModification<?> dto, ModificationType m,\r
+            MappingProvider<T> processor) throws InterruptedException, ExecutionException {\r
+        switch (m) {\r
+            case WRITE: {\r
+                if (dto.getDataBefore() != null) {\r
+                    processor.processUpdatedNeutronDto((T) dto.getDataBefore(), (T) dto.getDataAfter());\r
+                } else {\r
+                    processor.processCreatedNeutronDto((T) dto.getDataAfter());\r
+                }\r
+                break;\r
+            }\r
+            case SUBTREE_MODIFIED: {\r
+                processor.processUpdatedNeutronDto((T) dto.getDataBefore(), (T) dto.getDataAfter());\r
+                break;\r
+            }\r
+            case DELETE: {\r
+                processor.processDeletedNeutronDto((T) dto.getDataBefore());\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void close() {\r
+        registeredListener.close();\r
+    }\r
+}\r
diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandler.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandler.java
new file mode 100644 (file)
index 0000000..2887a44
--- /dev/null
@@ -0,0 +1,163 @@
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. 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
+\r
+package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;\r
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;\r
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.GbpByNeutronMappings;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.BaseEndpointsByPorts;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPortKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.VhostUserCaseBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.google.common.annotations.VisibleForTesting;\r
+import com.google.common.base.Optional;\r
+\r
+public class PortHandler  implements TransactionChainListener {\r
+\r
+    private static final Logger LOG = LoggerFactory.getLogger(MappingProvider.class);\r
+\r
+    private BindingTransactionChain transactionChain;\r
+    BaseEndpointByPortListener portByBaseEpListener;\r
+    DataBroker dataBroker;\r
+\r
+    PortHandler(DataBroker dataBroker) {\r
+        this.dataBroker = dataBroker;\r
+        transactionChain = this.dataBroker.createTransactionChain(this);\r
+    }\r
+\r
+    void processCreated(Port port) {\r
+        ReadTransaction rTx = dataBroker.newReadOnlyTransaction();\r
+        Optional<BaseEndpointByPort> optBaseEpByPort = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,\r
+                createBaseEpByPortIid(port.getUuid()), rTx);\r
+        if (!optBaseEpByPort.isPresent()) {\r
+            return;\r
+        }\r
+        processCreatedData(port, optBaseEpByPort.get());\r
+    }\r
+\r
+    void processCreated(BaseEndpointByPort bebp) {\r
+        ReadTransaction rTx = dataBroker.newReadOnlyTransaction();\r
+        Optional<Port> optPort = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, createPortIid(\r
+                bebp.getPortId()), rTx);\r
+        if (!optPort.isPresent()) {\r
+            return;\r
+        }\r
+        processCreatedData(optPort.get(), bebp);\r
+    }\r
+\r
+    @VisibleForTesting\r
+    void processCreatedData(Port port, BaseEndpointByPort bebp) {\r
+        // port not used yet\r
+        VppEndpoint vppEp = buildVppEp(bebp);\r
+        writeVppEndpoint(createVppEndpointIid(vppEp.getKey()), vppEp, true);\r
+        LOG.debug("Created vpp-endpoint {}", vppEp);\r
+    }\r
+\r
+    void processUpdated(Port original, Port delta) {\r
+        processCreated(delta);\r
+    }\r
+\r
+    void processDeleted(BaseEndpointByPort bebp) {\r
+        VppEndpoint vppEp = buildVppEp(bebp);\r
+        writeVppEndpoint(createVppEndpointIid(vppEp.getKey()), vppEp, false);\r
+        LOG.debug("Deleted vpp-endpoint {}", vppEp);\r
+    }\r
+\r
+    private void writeVppEndpoint(InstanceIdentifier<VppEndpoint> vppEpIid, VppEndpoint vppEp, boolean created) {\r
+        WriteTransaction wTx = transactionChain.newWriteOnlyTransaction();\r
+        InstanceIdentifier<VppEndpoint> iid = createVppEndpointIid(vppEp.getKey());\r
+        if (created == true) {\r
+            wTx.put(LogicalDatastoreType.CONFIGURATION, iid, vppEp, true);\r
+        } else {\r
+            wTx.delete(LogicalDatastoreType.CONFIGURATION, iid);\r
+        }\r
+        try {\r
+            wTx.submit().checkedGet();\r
+        } catch (TransactionCommitFailedException e) {\r
+            LOG.error("Transaction chain commit failed. {}", e);\r
+            transactionChain.close();\r
+            transactionChain = dataBroker.createTransactionChain(this);\r
+        }\r
+    }\r
+\r
+    @VisibleForTesting\r
+    VppEndpoint buildVppEp(BaseEndpointByPort bebp) {\r
+        return new VppEndpointBuilder().setContextId(bebp.getContextId())\r
+            .setContextType(bebp.getContextType())\r
+            .setAddress(bebp.getAddress())\r
+            .setInterfaceTypeChoice(new VhostUserCaseBuilder().setSocket(bebp.getPortId().getValue()).build())\r
+            .setAddressType(bebp.getAddressType())\r
+            .build();\r
+    }\r
+\r
+    private InstanceIdentifier<VppEndpoint> createVppEndpointIid(VppEndpointKey vppEpKey) {\r
+        return InstanceIdentifier.builder(Config.class).child(VppEndpoint.class, vppEpKey).build();\r
+    }\r
+\r
+    private InstanceIdentifier<BaseEndpointByPort> createBaseEpByPortIid(Uuid uuid) {\r
+        return createBaseEpByPortIid(new UniqueId(uuid.getValue()));\r
+    }\r
+\r
+    private InstanceIdentifier<BaseEndpointByPort> createBaseEpByPortIid(UniqueId uuid) {\r
+        return InstanceIdentifier.builder(Mappings.class)\r
+            .child(GbpByNeutronMappings.class)\r
+            .child(BaseEndpointsByPorts.class)\r
+            .child(BaseEndpointByPort.class, new BaseEndpointByPortKey(uuid))\r
+            .build();\r
+    }\r
+\r
+    InstanceIdentifier<Port> createWildcartedPortIid() {\r
+        return portsIid().child(Port.class).build();\r
+    }\r
+\r
+    private InstanceIdentifier<Port> createPortIid(UniqueId uuid) {\r
+        return portsIid().child(Port.class, new PortKey(new Uuid(uuid.getValue()))).build();\r
+    }\r
+\r
+    private InstanceIdentifierBuilder<Ports> portsIid() {\r
+        return InstanceIdentifier.builder(Neutron.class).child(Ports.class);\r
+    }\r
+\r
+    @Override\r
+    public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction,\r
+            Throwable cause) {\r
+        LOG.error("Transaction chain failed. {}", cause.getMessage());\r
+        transactionChain.close();\r
+        transactionChain = dataBroker.createTransactionChain(this);\r
+    }\r
+\r
+    @Override\r
+    public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {\r
+        LOG.trace("Transaction chain was successfull. {}", chain);\r
+    }\r
+}\r
diff --git a/neutron-vpp-mapper/src/main/yang/neutron-vpp-mapper-impl.yang b/neutron-vpp-mapper/src/main/yang/neutron-vpp-mapper-impl.yang
new file mode 100644 (file)
index 0000000..86243d3
--- /dev/null
@@ -0,0 +1,52 @@
+module neutron-vpp-mapper-impl {
+
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:config:neutron-vpp-mapper:impl";
+    prefix "neutron-vpp-mapper-impl";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
+
+    description
+        "This module contains the base YANG definitions for
+        neutron-vpp-mapper implementation.";
+
+    revision "2016-04-25" {
+        description
+            "Initial revision.";
+    }
+
+    // This is the definition of the service implementation as a module identity.
+    identity neutron-vpp-mapper-impl {
+        base config:module-type;
+
+        // Specifies the prefix for generated java classes.
+        config:java-name-prefix NeutronVppMapper;
+    }
+
+    // Augments the 'configuration' choice node under modules/module.
+    augment "/config:modules/config:module/config:configuration" {
+        case neutron-vpp-mapper-impl {
+            when "/config:modules/config:module/config:type = 'neutron-vpp-mapper-impl'";
+
+            container data-broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity mdsal:binding-async-data-broker;
+                    }
+                }
+            }
+
+            container rpc-registry {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity mdsal:binding-rpc-registry;
+                    }
+                }
+            }
+
+        }
+    }
+}
\ No newline at end of file
diff --git a/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/NeutronListenerTest.java b/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/NeutronListenerTest.java
new file mode 100644 (file)
index 0000000..9ae9a19
--- /dev/null
@@ -0,0 +1,136 @@
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. 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
+\r
+package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertNotNull;\r
+import static org.junit.Assert.assertNull;\r
+import static org.mockito.Matchers.any;\r
+import static org.mockito.Matchers.eq;\r
+import static org.mockito.Mockito.verify;\r
+\r
+import java.util.Collection;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.mockito.Mockito;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;\r
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;\r
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;\r
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.MacAddressType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.GbpByNeutronMappings;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.BaseEndpointsByPorts;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPortBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;\r
+import org.opendaylight.yangtools.concepts.ListenerRegistration;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+\r
+public class NeutronListenerTest extends AbstractDataBrokerTest implements DataTreeChangeListener<VppEndpoint> {\r
+\r
+    private DataBroker dataBroker;\r
+    private Integer eventCount;\r
+    private static final LogicalDatastoreType CONFIG = LogicalDatastoreType.CONFIGURATION;\r
+    private static final LogicalDatastoreType OPER = LogicalDatastoreType.OPERATIONAL;\r
+\r
+    private final Port port = new PortBuilder().setUuid(new Uuid("00000000-1111-2222-3333-444444444444")).build();\r
+    private final BaseEndpointByPort bebp = new BaseEndpointByPortBuilder().setContextId(\r
+            new ContextId("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"))\r
+        .setAddress("00:11:11:11:11:11")\r
+        .setPortId(new UniqueId("00000000-1111-2222-3333-444444444444"))\r
+        .setContextType(MappingUtils.L2_BRDIGE_DOMAIN)\r
+        .setAddressType(MacAddressType.class)\r
+        .build();\r
+\r
+    @Before\r
+    public void init() {\r
+        dataBroker = getDataBroker();\r
+    }\r
+\r
+    @Test\r
+    public void constructorTest() {\r
+        dataBroker = Mockito.spy(dataBroker);\r
+        NeutronListener neutronListener = new NeutronListener(dataBroker);\r
+        verify(dataBroker).registerDataTreeChangeListener(\r
+                eq(new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,\r
+                        InstanceIdentifier.builder(Neutron.class)\r
+                            .build())), any(NeutronListener.class));\r
+        verify(dataBroker).registerDataTreeChangeListener(\r
+                eq(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,\r
+                        InstanceIdentifier.builder(Mappings.class)\r
+                        .child(GbpByNeutronMappings.class)\r
+                        .child(BaseEndpointsByPorts.class)\r
+                        .child(BaseEndpointByPort.class)\r
+                        .build())), any(BaseEndpointByPortListener.class));\r
+        neutronListener.close();\r
+    }\r
+\r
+    @Test\r
+    public void createAndDeleteTest() throws Exception {\r
+        eventCount = 0;\r
+        ListenerRegistration<NeutronListenerTest> registerDataTreeChangeListener = registerVppEpListener();\r
+        NeutronListener neutronListener = new NeutronListener(dataBroker);\r
+        WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();\r
+        wTx.put(CONFIG, TestUtils.createPortIid(port.getKey()), port);\r
+        wTx.put(OPER, TestUtils.createBaseEpByPortIid(port.getUuid()), bebp);\r
+        wTx.submit().get();\r
+        wTx = dataBroker.newWriteOnlyTransaction();\r
+        wTx.delete(CONFIG, TestUtils.createPortIid(port.getKey()));\r
+        wTx.delete(OPER, TestUtils.createBaseEpByPortIid(port.getUuid()));\r
+        DataStoreHelper.submitToDs(wTx);\r
+        // manual delay for max 5s\r
+        for (int i = 0; i < 50; i++) {\r
+            if (eventCount >= 2) {\r
+                break;\r
+            }\r
+            Thread.sleep(100);\r
+        }\r
+        assertEquals(Integer.valueOf(2), eventCount);\r
+        registerDataTreeChangeListener.close();\r
+        neutronListener.close();\r
+    }\r
+\r
+    @Override\r
+    public void onDataTreeChanged(Collection<DataTreeModification<VppEndpoint>> changes) {\r
+        for (DataTreeModification<VppEndpoint> change : changes) {\r
+            DataObjectModification<VppEndpoint> vppEpChange = change.getRootNode();\r
+            ModificationType modType = vppEpChange.getModificationType();\r
+            if (modType.equals(ModificationType.WRITE)) {\r
+                assertNull(vppEpChange.getDataBefore());\r
+                assertNotNull(vppEpChange.getDataAfter());\r
+                eventCount++;\r
+            } else if (modType.equals(ModificationType.DELETE)) {\r
+                assertNotNull(vppEpChange.getDataBefore());\r
+                assertNull(vppEpChange.getDataAfter());\r
+                eventCount++;\r
+            }\r
+        }\r
+    }\r
+\r
+    private ListenerRegistration<NeutronListenerTest> registerVppEpListener() {\r
+        return dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,\r
+                InstanceIdentifier.builder(Config.class).child(VppEndpoint.class).build()), this);\r
+    }\r
+}\r
diff --git a/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandlerTest.java b/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandlerTest.java
new file mode 100644 (file)
index 0000000..aa92d28
--- /dev/null
@@ -0,0 +1,128 @@
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. 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
+\r
+package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertFalse;\r
+import static org.junit.Assert.assertTrue;\r
+import static org.junit.Assert.assertNotNull;\r
+import static org.mockito.Mockito.verify;\r
+import static org.mockito.Mockito.when;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.mockito.Mockito;\r
+import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;\r
+import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;\r
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;\r
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.MacAddressType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPortBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.VhostUserCase;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+\r
+import com.google.common.base.Optional;\r
+\r
+public class PortHandlerTest extends AbstractDataBrokerTest {\r
+\r
+    private DataBroker dataBroker;\r
+    private PortHandler portHandler;\r
+    private ReadWriteTransaction rwTx;\r
+    private BindingTransactionChain transactionChain;\r
+\r
+    private final Port port = new PortBuilder().setUuid(new Uuid("00000000-1111-2222-3333-444444444444")).build();\r
+    private final BaseEndpointByPort bebp = new BaseEndpointByPortBuilder().setContextId(\r
+            new ContextId("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"))\r
+        .setAddress("00:11:11:11:11:11")\r
+        .setPortId(new UniqueId("00000000-1111-2222-3333-444444444444"))\r
+        .setContextType(MappingUtils.L2_BRDIGE_DOMAIN)\r
+        .setAddressType(MacAddressType.class)\r
+        .build();\r
+\r
+    @Before\r
+    public void init() {\r
+        dataBroker = Mockito.spy(getDataBroker());\r
+        transactionChain = dataBroker.createTransactionChain(portHandler);\r
+        when(dataBroker.createTransactionChain(portHandler)).thenReturn(transactionChain);\r
+        portHandler = new PortHandler(dataBroker);\r
+        rwTx = Mockito.spy(dataBroker.newReadWriteTransaction());\r
+        when(transactionChain.newWriteOnlyTransaction()).thenReturn(rwTx);\r
+    }\r
+\r
+    @Test\r
+    public void buildVppEpTest() {\r
+        VppEndpoint vppEp = portHandler.buildVppEp(bebp);\r
+        assertEquals(vppEp.getAddress(),bebp.getAddress());\r
+        assertEquals(vppEp.getAddressType(), bebp.getAddressType());\r
+        assertEquals(vppEp.getContextId(), bebp.getContextId());\r
+        assertEquals(vppEp.getContextType(), bebp.getContextType());\r
+        assertTrue(vppEp.getInterfaceTypeChoice() instanceof VhostUserCase);\r
+        VhostUserCase vhostUserCase = (VhostUserCase) vppEp.getInterfaceTypeChoice();\r
+        assertNotNull(vhostUserCase);\r
+        assertEquals(vhostUserCase.getSocket(), bebp.getPortId().getValue());\r
+    }\r
+\r
+    @Test\r
+    public void createWildcartedPortIidTest() throws TransactionCommitFailedException {\r
+        InstanceIdentifier<Port> iid = portHandler.createWildcartedPortIid();\r
+        Class<?>[] expectedTypes = {Neutron.class, Ports.class, Port.class};\r
+        TestUtils.assertPathArgumentTypes(iid.getPathArguments(), expectedTypes);\r
+        assertEquals(iid.getTargetType(), Port.class);\r
+    }\r
+\r
+    @Test\r
+    public void processCreatedDataTest() throws Exception {\r
+        portHandler.processCreatedData(port, bebp);\r
+        ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();\r
+        Optional<VppEndpoint> optVppEp = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+                TestUtils.createVppEpIid(TestUtils.createVppEndpointKey(bebp)), rTx);\r
+        assertTrue(optVppEp.isPresent());\r
+    }\r
+\r
+    @Test\r
+    public void processUpdatedTest() throws Exception {\r
+        ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();\r
+        tx.put(LogicalDatastoreType.OPERATIONAL, TestUtils.createBaseEpByPortIid(port.getUuid()), bebp, true);\r
+        DataStoreHelper.submitToDs(tx);\r
+        portHandler.processUpdated(port, port);\r
+        ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();\r
+        Optional<VppEndpoint> optVppEp = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+                TestUtils.createVppEpIid(TestUtils.createVppEndpointKey(bebp)), rTx);\r
+        assertTrue(optVppEp.isPresent());\r
+        verify(rwTx).submit();\r
+    }\r
+\r
+    @Test\r
+    public void processDeletedTest() throws Exception {\r
+        ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();\r
+        tx.put(LogicalDatastoreType.OPERATIONAL, TestUtils.createVppEpIid(TestUtils.createVppEndpointKey(bebp)),\r
+                portHandler.buildVppEp(bebp));\r
+        DataStoreHelper.submitToDs(tx);\r
+        portHandler.processDeleted(bebp);\r
+        ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();\r
+        Optional<VppEndpoint> optVppEp = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+                TestUtils.createVppEpIid(TestUtils.createVppEndpointKey(bebp)), rTx);\r
+        assertFalse(optVppEp.isPresent());\r
+        verify(rwTx).submit();\r
+    }\r
+}\r
diff --git a/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/TestUtils.java b/neutron-vpp-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/TestUtils.java
new file mode 100644 (file)
index 0000000..6411071
--- /dev/null
@@ -0,0 +1,77 @@
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. 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
+\r
+package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertNotNull;\r
+import static org.junit.Assert.assertTrue;\r
+\r
+import java.util.Iterator;\r
+\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.AddressType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.ContextType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.GbpByNeutronMappings;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.BaseEndpointsByPorts;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.base.endpoints.by.ports.BaseEndpointByPortKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.PortsByEndpoints;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;\r
+\r
+public class TestUtils {\r
+\r
+    public static VppEndpointKey createVppEndpointKey(BaseEndpointByPort bebp) {\r
+        return new VppEndpointKey(bebp.getAddress(), bebp.getAddressType(), bebp.getContextId(), bebp.getContextType());\r
+    }\r
+\r
+    public static InstanceIdentifier<VppEndpoint> createVppEpIid(VppEndpointKey key) {\r
+        return InstanceIdentifier.builder(Config.class).child(VppEndpoint.class, key).build();\r
+    }\r
+\r
+    public static InstanceIdentifier<VppEndpoint> createVppEpIid(String addr, Class<? extends AddressType> addrType,\r
+            ContextId ctxId, Class<? extends ContextType> ctxType) {\r
+        return createVppEpIid(new VppEndpointKey(addr, addrType, ctxId, ctxType));\r
+    }\r
+\r
+    public static InstanceIdentifier<Port> createPortIid(PortKey portKey) {\r
+        return InstanceIdentifier.builder(Neutron.class).child(Ports.class).child(Port.class, portKey).build();\r
+    }\r
+\r
+    public static InstanceIdentifier<BaseEndpointByPort> createBaseEpByPortIid(Uuid uuid) {\r
+        return createBaseEpByPortIid(new UniqueId(uuid.getValue()));\r
+    }\r
+\r
+    public static InstanceIdentifier<BaseEndpointByPort> createBaseEpByPortIid(UniqueId uuid) {\r
+        return InstanceIdentifier.builder(Mappings.class)\r
+            .child(GbpByNeutronMappings.class)\r
+            .child(BaseEndpointsByPorts.class)\r
+            .child(BaseEndpointByPort.class, new BaseEndpointByPortKey(uuid))\r
+            .build();\r
+    }\r
+\r
+    public static void assertPathArgumentTypes(Iterable<PathArgument> pathArguments, Class<?>[] expectedTypes) {\r
+        assertNotNull(pathArguments);\r
+        Iterator<PathArgument> it = pathArguments.iterator();\r
+        for (int i = 0; i < expectedTypes.length; ++i) {\r
+            assertTrue("Next path argument expected.", it.hasNext());\r
+            assertEquals("Unexpected path argument type.", expectedTypes[i], it.next().getType());\r
+        }\r
+    }\r
+}\r
diff --git a/pom.xml b/pom.xml
index 257a4c8d5b6ca5864c80229d6e83a2a9033ffbc2..3a306a984e1f2101193283a13fc047c755ae6388 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -21,6 +21,7 @@
     <module>renderers</module>
     <module>location-providers</module>
     <module>neutron-mapper</module>
+    <module>neutron-vpp-mapper</module>
     <module>neutron-ovsdb</module>
     <module>ui-backend</module>
     <module>groupbasedpolicy-ui</module>
index 0da97aaec80ba8f636820d2811c5c578f62d1be3..0a1df5f39d30dfbc689dd2772035d764e6ae5f61 100644 (file)
@@ -49,7 +49,7 @@
         <configuration>
           <instructions>
             <Export-Package>
-              org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp.input.rev160425.*
+              org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.*
             </Export-Package> -->
           </instructions>
         </configuration>
diff --git a/renderers/vpp/src/main/yang/vpp-renderer.yang b/renderers/vpp/src/main/yang/vpp-renderer.yang
new file mode 100644 (file)
index 0000000..283444a
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. 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
+ */
+
+module vpp-renderer {
+    yang-version 1;
+
+    namespace "urn:opendaylight:groupbasedpolicy:vpp_renderer";
+    prefix "vpp-renderer";
+
+    description
+        "This module is a baseline for the group-based policy vpp renderer model.";
+
+    revision "2016-04-25" {
+        description
+            "Initial revision.";
+    }
+
+    import base-endpoint { prefix base-ep; revision-date 2016-04-27; }
+
+    container config {
+        list vpp-endpoint {
+            key "context-type context-id address-type address";
+            uses base-ep:address-endpoint-key;
+            choice interface-type-choice {
+                case vhost-user-case {
+                    leaf socket {
+                        description "A unique ID for the neutron port";
+                        type string {
+                            length 1..255;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}