Initial push of Neutron interface 94/1294/8
authorRyan Moats <rmoats@us.ibm.com>
Fri, 20 Sep 2013 17:51:39 +0000 (12:51 -0500)
committerGiovanni Meo <gmeo@cisco.com>
Mon, 23 Sep 2013 14:27:01 +0000 (16:27 +0200)
Two bundles included in this:
-networkconfig.neutron (contains JAXB annotated classes, *CRUD
interfaces with an implementation [for storing objects], and
Aware interfaces [for other bundles to register services])
-networkconfig.neutron.northbound (contains the JAXRS annotated
classes along with JAXB annotated request specific classes)

Commit amended to refactor .internal package to separate
implementation bundle and package

Commit re-amended to clean up issues in commons/opendaylight
and distribution/opendaylight poms

Commit re-re-amended to fix conflicts on rebase (I hope)

Getting close to just abandoning the change and starting over

Commit re-re-re-amended to fix parent issues in pom

amend to remove leaked CRs in distribution pom

- Cleanup of some duplicates artifact and of commons-net in modules
dependencies, anyway they get in via the commons.opendaylight

Change-Id: I15724c55e843237c010dfaec1e1e523560174f51
Signed-off-by: Ryan Moats <rmoats@us.ibm.com>
47 files changed:
opendaylight/commons/opendaylight/pom.xml
opendaylight/distribution/opendaylight/pom.xml
opendaylight/networkconfiguration/neutron/implementation/pom.xml [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronFloatingIPInterface.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronNetworkInterface.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronPortInterface.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronRouterInterface.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSubnetInterface.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/pom.xml [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFloatingIPAware.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFloatingIPCRUD.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronNetworkAware.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronNetworkCRUD.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronPortAware.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronPortCRUD.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronRouterAware.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronRouterCRUD.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSubnetAware.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSubnetCRUD.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronCRUDInterfaces.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronFloatingIP.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_Interface.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_NetworkReference.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_HostRoute.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/enunciate.xml [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/pom.xml [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPRequest.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPsNorthbound.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNBInterfaces.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworkRequest.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworksNorthbound.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortRequest.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRouterRequest.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRoutersNorthbound.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetRequest.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetsNorthbound.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/resources/WEB-INF/web.xml [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/resources/org/opendaylight/controller/networkconfig/neutron/northbound/jaxb.properties [new file with mode: 0644]

index 31dd741cfdb0d7cfa8328e26cc639c94769f208b..3ae9c6ee6ca7d2ae70c43c3fce5e227b2bfb0725 100644 (file)
       <artifactId>commons-fileupload</artifactId>
       <version>1.2.2</version>
     </dependency>
       <artifactId>commons-fileupload</artifactId>
       <version>1.2.2</version>
     </dependency>
+    <dependency>
+        <groupId>commons-net</groupId>
+        <artifactId>commons-net</artifactId>
+        <version>3.0.1</version>
+    </dependency>
     <dependency>
       <groupId>equinoxSDK381</groupId>
       <artifactId>javax.servlet</artifactId>
     <dependency>
       <groupId>equinoxSDK381</groupId>
       <artifactId>javax.servlet</artifactId>
         <artifactId>asm-all</artifactId>
         <version>4.1</version>
     </dependency>
         <artifactId>asm-all</artifactId>
         <version>4.1</version>
     </dependency>
+    <dependency>
+        <groupId>org.eclipse.persistence</groupId>
+        <artifactId>org.eclipse.persistence.moxy</artifactId>
+        <version>2.5.0</version>
+    </dependency>
+    <dependency>
+        <groupId>org.eclipse.persistence</groupId>
+        <artifactId>org.eclipse.persistence.core</artifactId>
+        <version>2.5.0</version>
+    </dependency>
+    <dependency>
+        <groupId>org.eclipse.persistence</groupId>
+        <artifactId>org.eclipse.persistence.antlr</artifactId>
+        <version>2.5.0</version>
+    </dependency>
   </dependencies>
 </project>
   </dependencies>
 </project>
index 3efd97e2aa3857fa549e752ae16d1aa6990ab0f3..13ac14b5ea1f598ead7d083d338da75252030e05 100644 (file)
     <module>../../web/troubleshoot</module>
     <module>../../web/topology</module>
 
     <module>../../web/troubleshoot</module>
     <module>../../web/topology</module>
 
+    <!--  Neutron -->
+    <module>../../networkconfiguration/neutron</module>
+    <module>../../networkconfiguration/neutron/implementation</module>
+    <module>../../northbound/networkconfiguration/neutron</module>
+
     <!-- Northbound bundles -->
     <module>../../northbound/commons</module>
     <module>../../northbound/bundlescanner/api</module>
     <!-- Northbound bundles -->
     <module>../../northbound/commons</module>
     <module>../../northbound/bundlescanner/api</module>
diff --git a/opendaylight/networkconfiguration/neutron/implementation/pom.xml b/opendaylight/networkconfiguration/neutron/implementation/pom.xml
new file mode 100644 (file)
index 0000000..5aa3c32
--- /dev/null
@@ -0,0 +1,81 @@
+<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
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>commons.opendaylight</artifactId>\r
+    <version>1.4.0-SNAPSHOT</version>\r
+    <relativePath>../../../commons/opendaylight</relativePath>\r
+  </parent>\r
+      <properties>\r
+        <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>\r
+        <enunciate.version>1.26.2</enunciate.version>\r
+    </properties>\r
+\r
+    <distributionManagement>\r
+        <!-- OpenDayLight Released artifact -->\r
+        <repository>\r
+            <id>opendaylight-release</id>\r
+            <url>${nexusproxy}/repositories/opendaylight.release/</url>\r
+        </repository>\r
+        <!-- OpenDayLight Snapshot artifact -->\r
+        <snapshotRepository>\r
+            <id>opendaylight-snapshot</id>\r
+            <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>\r
+        </snapshotRepository>\r
+        <!-- Site deployment -->\r
+        <site>\r
+            <id>website</id>\r
+            <url>${sitedeploy}</url>\r
+        </site>\r
+    </distributionManagement>\r
+  <groupId>org.opendaylight.controller</groupId>\r
+  <artifactId>networkconfig.neutron.implementation</artifactId>\r
+  <version>0.4.0-SNAPSHOT</version>\r
+  <packaging>bundle</packaging>\r
+  <build>\r
+        <plugins>\r
+            <plugin>\r
+                <groupId>org.apache.felix</groupId>\r
+                <artifactId>maven-bundle-plugin</artifactId>\r
+                <version>2.3.6</version>\r
+                <extensions>true</extensions>\r
+                <configuration>\r
+                    <instructions>\r
+                        <Import-Package>\r
+                            org.opendaylight.controller.clustering.services,\r
+                            org.opendaylight.controller.sal.core,\r
+                            org.opendaylight.controller.sal.utils,\r
+                            org.apache.felix.dm,\r
+                            org.apache.commons.net.util,\r
+                            org.osgi.service.component,\r
+                            org.opendaylight.controller.networkconfig.neutron,\r
+                            org.slf4j,\r
+                            javax.xml.bind.annotation\r
+                        </Import-Package>\r
+                        <Bundle-Activator>\r
+                            org.opendaylight.controller.networkconfig.neutron.implementation.Activator\r
+                        </Bundle-Activator>\r
+                    </instructions>\r
+                    <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>\r
+                </configuration>\r
+            </plugin>\r
+        </plugins>\r
+    </build>\r
+     <dependencies>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller</groupId>\r
+            <artifactId>clustering.services</artifactId>\r
+            <version>0.4.0-SNAPSHOT</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller</groupId>\r
+            <artifactId>networkconfig.neutron</artifactId>\r
+            <version>0.4.0-SNAPSHOT</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller</groupId>\r
+            <artifactId>sal</artifactId>\r
+            <version>0.5.0-SNAPSHOT</version>\r
+        </dependency>\r
+    </dependencies>\r
+</project>\r
diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java
new file mode 100644 (file)
index 0000000..d8d5cc4
--- /dev/null
@@ -0,0 +1,141 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.implementation;\r
+\r
+import java.util.Hashtable;\r
+import java.util.Dictionary;\r
+import org.apache.felix.dm.Component;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.implementation.NeutronFloatingIPInterface;\r
+import org.opendaylight.controller.networkconfig.neutron.implementation.NeutronNetworkInterface;\r
+import org.opendaylight.controller.networkconfig.neutron.implementation.NeutronPortInterface;\r
+import org.opendaylight.controller.networkconfig.neutron.implementation.NeutronRouterInterface;\r
+import org.opendaylight.controller.networkconfig.neutron.implementation.NeutronSubnetInterface;\r
+import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;\r
+\r
+public class Activator extends ComponentActivatorAbstractBase {\r
+    protected static final Logger logger = LoggerFactory\r
+    .getLogger(Activator.class);\r
+\r
+    /**\r
+     * Function called when the activator starts just after some\r
+     * initializations are done by the\r
+     * ComponentActivatorAbstractBase.\r
+     *\r
+     */\r
+    public void init() {\r
+\r
+    }\r
+\r
+    /**\r
+     * Function called when the activator stops just before the\r
+     * cleanup done by ComponentActivatorAbstractBase\r
+     *\r
+     */\r
+    public void destroy() {\r
+\r
+    }\r
+\r
+    /**\r
+     * Function that is used to communicate to dependency manager the\r
+     * list of known implementations for services inside a container\r
+     *\r
+     *\r
+     * @return An array containing all the CLASS objects that will be\r
+     * instantiated in order to get an fully working implementation\r
+     * Object\r
+     */\r
+    public Object[] getImplementations() {\r
+        Object[] res = { NeutronFloatingIPInterface.class,\r
+                NeutronRouterInterface.class,\r
+                NeutronPortInterface.class,\r
+                NeutronSubnetInterface.class,\r
+                NeutronNetworkInterface.class };\r
+        return res;\r
+    }\r
+\r
+    /**\r
+     * Function that is called when configuration of the dependencies\r
+     * is required.\r
+     *\r
+     * @param c dependency manager Component object, used for\r
+     * configuring the dependencies exported and imported\r
+     * @param imp Implementation class that is being configured,\r
+     * needed as long as the same routine can configure multiple\r
+     * implementations\r
+     * @param containerName The containerName being configured, this allow\r
+     * also optional per-container different behavior if needed, usually\r
+     * should not be the case though.\r
+     */\r
+    public void configureInstance(Component c, Object imp, String containerName) {\r
+        if (imp.equals(NeutronFloatingIPInterface.class)) {\r
+            // export the service\r
+            c.setInterface(\r
+                    new String[] { INeutronFloatingIPCRUD.class.getName() }, null);\r
+            Dictionary<String, String> props = new Hashtable<String, String>();\r
+            props.put("salListenerName", "neutron");\r
+            c.add(createContainerServiceDependency(containerName)\r
+                    .setService(IClusterContainerServices.class)\r
+                    .setCallbacks("setClusterContainerService",\r
+                    "unsetClusterContainerService").setRequired(true));\r
+        }\r
+        if (imp.equals(NeutronRouterInterface.class)) {\r
+            // export the service\r
+            c.setInterface(\r
+                    new String[] { INeutronRouterCRUD.class.getName() }, null);\r
+            Dictionary<String, String> props = new Hashtable<String, String>();\r
+            props.put("salListenerName", "neutron");\r
+            c.add(createContainerServiceDependency(containerName)\r
+                    .setService(IClusterContainerServices.class)\r
+                    .setCallbacks("setClusterContainerService",\r
+                    "unsetClusterContainerService").setRequired(true));\r
+        }\r
+        if (imp.equals(NeutronPortInterface.class)) {\r
+            // export the service\r
+            c.setInterface(\r
+                    new String[] { INeutronPortCRUD.class.getName() }, null);\r
+            Dictionary<String, String> props = new Hashtable<String, String>();\r
+            props.put("salListenerName", "neutron");\r
+            c.add(createContainerServiceDependency(containerName)\r
+                    .setService(IClusterContainerServices.class)\r
+                    .setCallbacks("setClusterContainerService",\r
+                    "unsetClusterContainerService").setRequired(true));\r
+        }\r
+        if (imp.equals(NeutronSubnetInterface.class)) {\r
+            // export the service\r
+            c.setInterface(\r
+                    new String[] { INeutronSubnetCRUD.class.getName() }, null);\r
+            Dictionary<String, String> props = new Hashtable<String, String>();\r
+            props.put("salListenerName", "neutron");\r
+            c.add(createContainerServiceDependency(containerName)\r
+                    .setService(IClusterContainerServices.class)\r
+                    .setCallbacks("setClusterContainerService",\r
+                    "unsetClusterContainerService").setRequired(true));\r
+        }\r
+        if (imp.equals(NeutronNetworkInterface.class)) {\r
+            // export the service\r
+            c.setInterface(\r
+                    new String[] { INeutronNetworkCRUD.class.getName() }, null);\r
+            Dictionary<String, String> props = new Hashtable<String, String>();\r
+            props.put("salListenerName", "neutron");\r
+            c.add(createContainerServiceDependency(containerName)\r
+                    .setService(IClusterContainerServices.class)\r
+                    .setCallbacks("setClusterContainerService",\r
+                    "unsetClusterContainerService").setRequired(true));\r
+        }\r
+    }\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronFloatingIPInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronFloatingIPInterface.java
new file mode 100644 (file)
index 0000000..7b10756
--- /dev/null
@@ -0,0 +1,266 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.implementation;\r
+\r
+import java.lang.reflect.Method;\r
+import java.util.ArrayList;\r
+import java.util.Dictionary;\r
+import java.util.EnumSet;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+import java.util.Map.Entry;\r
+import java.util.concurrent.ConcurrentMap;\r
+\r
+import org.apache.felix.dm.Component;\r
+import org.opendaylight.controller.clustering.services.CacheConfigException;\r
+import org.opendaylight.controller.clustering.services.CacheExistException;\r
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
+import org.opendaylight.controller.clustering.services.IClusterServices;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {\r
+    private static final Logger logger = LoggerFactory.getLogger(NeutronFloatingIPInterface.class);\r
+    private String containerName = null;\r
+\r
+    private IClusterContainerServices clusterContainerService = null;\r
+    private ConcurrentMap<String, NeutronFloatingIP> floatingIPDB;\r
+\r
+    // methods needed for creating caches\r
+\r
+    void setClusterContainerService(IClusterContainerServices s) {\r
+        logger.debug("Cluster Service set");\r
+        this.clusterContainerService = s;\r
+    }\r
+\r
+    void unsetClusterContainerService(IClusterContainerServices s) {\r
+        if (this.clusterContainerService == s) {\r
+            logger.debug("Cluster Service removed!");\r
+            this.clusterContainerService = null;\r
+        }\r
+    }\r
+\r
+    @SuppressWarnings("deprecation")\r
+    private void allocateCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterContainerService, can't create cache");\r
+            return;\r
+        }\r
+        logger.debug("Creating Cache for Neutron FloatingIPs");\r
+        try {\r
+            // neutron caches\r
+            this.clusterContainerService.createCache("neutronFloatingIPs",\r
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
+        } catch (CacheConfigException cce) {\r
+            logger.error("Cache couldn't be created for Neutron -  check cache mode");\r
+        } catch (CacheExistException cce) {\r
+            logger.error("Cache for Neutron already exists, destroy and recreate");\r
+        }\r
+        logger.debug("Cache successfully created for NeutronFloatingIps");\r
+    }\r
+\r
+    @SuppressWarnings({ "unchecked", "deprecation" })\r
+    private void retrieveCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
+            return;\r
+        }\r
+\r
+        logger.debug("Retrieving cache for Neutron FloatingIPs");\r
+        floatingIPDB = (ConcurrentMap<String, NeutronFloatingIP>) this.clusterContainerService\r
+        .getCache("neutronFloatingIPs");\r
+        if (floatingIPDB == null) {\r
+            logger.error("Cache couldn't be retrieved for Neutron FloatingIPs");\r
+        }\r
+        logger.debug("Cache was successfully retrieved for Neutron FloatingIPs");\r
+    }\r
+\r
+    @SuppressWarnings("deprecation")\r
+    private void destroyCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterMger, can't destroy cache");\r
+            return;\r
+        }\r
+        logger.debug("Destroying Cache for HostTracker");\r
+        this.clusterContainerService.destroyCache("neutronFloatingIPs");\r
+    }\r
+\r
+    private void startUp() {\r
+        allocateCache();\r
+        retrieveCache();\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager when all the required\r
+     * dependencies are satisfied\r
+     *\r
+     */\r
+    void init(Component c) {\r
+        Dictionary<?, ?> props = c.getServiceProperties();\r
+        if (props != null) {\r
+            this.containerName = (String) props.get("containerName");\r
+            logger.debug("Running containerName: {}", this.containerName);\r
+        } else {\r
+            // In the Global instance case the containerName is empty\r
+            this.containerName = "";\r
+        }\r
+        startUp();\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager when at least one dependency\r
+     * become unsatisfied or when the component is shutting down because for\r
+     * example bundle is being stopped.\r
+     *\r
+     */\r
+    void destroy() {\r
+        destroyCache();\r
+    }\r
+\r
+    /**\r
+     * Function called by dependency manager after "init ()" is called and after\r
+     * the services provided by the class are registered in the service registry\r
+     *\r
+     */\r
+    void start() {\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager before the services exported by\r
+     * the component are unregistered, this will be followed by a "destroy ()"\r
+     * calls\r
+     *\r
+     */\r
+    void stop() {\r
+    }\r
+\r
+    // this method uses reflection to update an object from it's delta.\r
+\r
+    private boolean overwrite(Object target, Object delta) {\r
+        Method[] methods = target.getClass().getMethods();\r
+\r
+        for(Method toMethod: methods){\r
+            if(toMethod.getDeclaringClass().equals(target.getClass())\r
+                    && toMethod.getName().startsWith("set")){\r
+\r
+                String toName = toMethod.getName();\r
+                String fromName = toName.replace("set", "get");\r
+\r
+                try {\r
+                    Method fromMethod = delta.getClass().getMethod(fromName);\r
+                    Object value = fromMethod.invoke(delta, (Object[])null);\r
+                    if(value != null){\r
+                        toMethod.invoke(target, value);\r
+                    }\r
+                } catch (Exception e) {\r
+                    e.printStackTrace();\r
+                    return false;\r
+                }\r
+            }\r
+        }\r
+        return true;\r
+    }\r
+\r
+    // IfNBFloatingIPCRUD interface methods\r
+\r
+    public boolean floatingIPExists(String uuid) {\r
+        return floatingIPDB.containsKey(uuid);\r
+    }\r
+\r
+    public NeutronFloatingIP getFloatingIP(String uuid) {\r
+        if (!floatingIPExists(uuid))\r
+            return null;\r
+        return floatingIPDB.get(uuid);\r
+    }\r
+\r
+    public List<NeutronFloatingIP> getAllFloatingIPs() {\r
+        Set<NeutronFloatingIP> allIPs = new HashSet<NeutronFloatingIP>();\r
+        for (Entry<String, NeutronFloatingIP> entry : floatingIPDB.entrySet()) {\r
+            NeutronFloatingIP floatingip = entry.getValue();\r
+            allIPs.add(floatingip);\r
+        }\r
+        logger.debug("Exiting getAllFloatingIPs, Found {} FloatingIPs", allIPs.size());\r
+        List<NeutronFloatingIP> ans = new ArrayList<NeutronFloatingIP>();\r
+        ans.addAll(allIPs);\r
+        return ans;\r
+    }\r
+\r
+    public boolean addFloatingIP(NeutronFloatingIP input) {\r
+        INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
+        INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
+        INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
+\r
+        if (floatingIPExists(input.getID()))\r
+            return false;\r
+        //if floating_ip_address isn't there, allocate from the subnet pool\r
+        NeutronSubnet subnet = subnetCRUD.getSubnet(networkCRUD.getNetwork(input.getFloatingNetworkUUID()).getSubnets().get(0));\r
+        if (input.getFloatingIPAddress() == null)\r
+            input.setFloatingIPAddress(subnet.getLowAddr());\r
+        subnet.allocateIP(input.getFloatingIPAddress());\r
+\r
+        //if port_id is there, bind port to this floating ip\r
+        if (input.getPortUUID() != null) {\r
+            NeutronPort port = portCRUD.getPort(input.getPortUUID());\r
+            port.addFloatingIP(input.getFixedIPAddress(), input);\r
+        }\r
+\r
+        floatingIPDB.putIfAbsent(input.getID(), input);\r
+        return true;\r
+    }\r
+\r
+    public boolean removeFloatingIP(String uuid) {\r
+        INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
+        INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
+        INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
+\r
+        if (!floatingIPExists(uuid))\r
+            return false;\r
+        NeutronFloatingIP floatIP = getFloatingIP(uuid);\r
+        //if floating_ip_address isn't there, allocate from the subnet pool\r
+        NeutronSubnet subnet = subnetCRUD.getSubnet(networkCRUD.getNetwork(floatIP.getFloatingNetworkUUID()).getSubnets().get(0));\r
+        subnet.releaseIP(floatIP.getFloatingIPAddress());\r
+        if (floatIP.getPortUUID() != null) {\r
+            NeutronPort port = portCRUD.getPort(floatIP.getPortUUID());\r
+            port.removeFloatingIP(floatIP.getFixedIPAddress());\r
+        }\r
+        floatingIPDB.remove(uuid);\r
+        return true;\r
+    }\r
+\r
+    public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta) {\r
+        INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
+\r
+        if (!floatingIPExists(uuid))\r
+            return false;\r
+        NeutronFloatingIP target = floatingIPDB.get(uuid);\r
+        if (target.getPortUUID() != null) {\r
+            NeutronPort port = portCRUD.getPort(target.getPortUUID());\r
+            port.removeFloatingIP(target.getFixedIPAddress());\r
+        }\r
+\r
+        //if port_id is there, bind port to this floating ip\r
+        if (delta.getPortUUID() != null) {\r
+            NeutronPort port = portCRUD.getPort(delta.getPortUUID());\r
+            port.addFloatingIP(delta.getFixedIPAddress(), delta);\r
+        }\r
+\r
+        target.setPortUUID(delta.getPortUUID());\r
+        target.setFixedIPAddress(delta.getFixedIPAddress());\r
+        return true;\r
+    }\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronNetworkInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronNetworkInterface.java
new file mode 100644 (file)
index 0000000..035e6dc
--- /dev/null
@@ -0,0 +1,227 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.implementation;\r
+\r
+import java.lang.reflect.Method;\r
+import java.util.ArrayList;\r
+import java.util.Dictionary;\r
+import java.util.EnumSet;\r
+import java.util.HashSet;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Set;\r
+import java.util.Map.Entry;\r
+import java.util.concurrent.ConcurrentMap;\r
+\r
+import org.apache.felix.dm.Component;\r
+import org.opendaylight.controller.clustering.services.CacheConfigException;\r
+import org.opendaylight.controller.clustering.services.CacheExistException;\r
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
+import org.opendaylight.controller.clustering.services.IClusterServices;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+public class NeutronNetworkInterface implements INeutronNetworkCRUD {\r
+    private static final Logger logger = LoggerFactory.getLogger(NeutronNetworkInterface.class);\r
+    private String containerName = null;\r
+\r
+    private ConcurrentMap<String, NeutronNetwork> networkDB;\r
+    private IClusterContainerServices clusterContainerService = null;\r
+\r
+    // methods needed for creating caches\r
+\r
+    void setClusterContainerService(IClusterContainerServices s) {\r
+        logger.debug("Cluster Service set");\r
+        this.clusterContainerService = s;\r
+    }\r
+\r
+    void unsetClusterContainerService(IClusterContainerServices s) {\r
+        if (this.clusterContainerService == s) {\r
+            logger.debug("Cluster Service removed!");\r
+            this.clusterContainerService = null;\r
+        }\r
+    }\r
+\r
+    @SuppressWarnings("deprecation")\r
+    private void allocateCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterContainerService, can't create cache");\r
+            return;\r
+        }\r
+        logger.debug("Creating Cache for Neutron Networks");\r
+        try {\r
+            // neutron caches\r
+            this.clusterContainerService.createCache("neutronNetworks",\r
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
+        } catch (CacheConfigException cce) {\r
+            logger.error("Cache couldn't be created for Neutron Networks -  check cache mode");\r
+        } catch (CacheExistException cce) {\r
+            logger.error("Cache for Neutron Networks already exists, destroy and recreate");\r
+        }\r
+        logger.debug("Cache successfully created for Neutron Networks");\r
+    }\r
+\r
+    @SuppressWarnings({ "unchecked", "deprecation" })\r
+    private void retrieveCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
+            return;\r
+        }\r
+        logger.debug("Retrieving cache for Neutron Networks");\r
+        networkDB = (ConcurrentMap<String, NeutronNetwork>) this.clusterContainerService.getCache("neutronNetworks");\r
+        if (networkDB == null) {\r
+            logger.error("Cache couldn't be retrieved for Neutron Networks");\r
+        }\r
+        logger.debug("Cache was successfully retrieved for Neutron Networks");\r
+    }\r
+\r
+    private void startUp() {\r
+        allocateCache();\r
+        retrieveCache();\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager when all the required\r
+     * dependencies are satisfied\r
+     *\r
+     */\r
+    void init(Component c) {\r
+        Dictionary<?, ?> props = c.getServiceProperties();\r
+        if (props != null) {\r
+            this.containerName = (String) props.get("containerName");\r
+            logger.debug("Running containerName: {}", this.containerName);\r
+        } else {\r
+            // In the Global instance case the containerName is empty\r
+            this.containerName = "";\r
+        }\r
+        startUp();\r
+    }\r
+\r
+    @SuppressWarnings("deprecation")\r
+    private void destroyCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterMger, can't destroy cache");\r
+            return;\r
+        }\r
+        logger.debug("Destroying Cache for Neutron Networks");\r
+        this.clusterContainerService.destroyCache("Neutron Networks");\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager when at least one dependency\r
+     * become unsatisfied or when the component is shutting down because for\r
+     * example bundle is being stopped.\r
+     *\r
+     */\r
+    void destroy() {\r
+        destroyCache();\r
+    }\r
+\r
+    /**\r
+     * Function called by dependency manager after "init ()" is called and after\r
+     * the services provided by the class are registered in the service registry\r
+     *\r
+     */\r
+    void start() {\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager before the services exported by\r
+     * the component are unregistered, this will be followed by a "destroy ()"\r
+     * calls\r
+     *\r
+     */\r
+    void stop() {\r
+    }\r
+\r
+    // this method uses reflection to update an object from it's delta.\r
+\r
+    private boolean overwrite(Object target, Object delta) {\r
+        Method[] methods = target.getClass().getMethods();\r
+\r
+        for(Method toMethod: methods){\r
+            if(toMethod.getDeclaringClass().equals(target.getClass())\r
+                    && toMethod.getName().startsWith("set")){\r
+\r
+                String toName = toMethod.getName();\r
+                String fromName = toName.replace("set", "get");\r
+\r
+                try {\r
+                    Method fromMethod = delta.getClass().getMethod(fromName);\r
+                    Object value = fromMethod.invoke(delta, (Object[])null);\r
+                    if(value != null){\r
+                        toMethod.invoke(target, value);\r
+                    }\r
+                } catch (Exception e) {\r
+                    e.printStackTrace();\r
+                    return false;\r
+                }\r
+            }\r
+        }\r
+        return true;\r
+    }\r
+\r
+    // IfNBNetworkCRUD methods\r
+\r
+    public boolean networkExists(String uuid) {\r
+        return networkDB.containsKey(uuid);\r
+    }\r
+\r
+    public NeutronNetwork getNetwork(String uuid) {\r
+        if (!networkExists(uuid))\r
+            return null;\r
+        return networkDB.get(uuid);\r
+    }\r
+\r
+    public List<NeutronNetwork> getAllNetworks() {\r
+        Set<NeutronNetwork> allNetworks = new HashSet<NeutronNetwork>();\r
+        for (Entry<String, NeutronNetwork> entry : networkDB.entrySet()) {\r
+            NeutronNetwork network = entry.getValue();\r
+            allNetworks.add(network);\r
+        }\r
+        logger.debug("Exiting getAllNetworks, Found {} OpenStackNetworks", allNetworks.size());\r
+        List<NeutronNetwork> ans = new ArrayList<NeutronNetwork>();\r
+        ans.addAll(allNetworks);\r
+        return ans;\r
+    }\r
+\r
+    public boolean addNetwork(NeutronNetwork input) {\r
+        if (networkExists(input.getID()))\r
+            return false;\r
+        networkDB.putIfAbsent(input.getID(), input);\r
+      //TODO: add code to find INeutronNetworkAware services and call newtorkCreated on them\r
+        return true;\r
+    }\r
+\r
+    public boolean removeNetwork(String uuid) {\r
+        if (!networkExists(uuid))\r
+            return false;\r
+        networkDB.remove(uuid);\r
+      //TODO: add code to find INeutronNetworkAware services and call newtorkDeleted on them\r
+        return true;\r
+    }\r
+\r
+    public boolean updateNetwork(String uuid, NeutronNetwork delta) {\r
+        if (!networkExists(uuid))\r
+            return false;\r
+        NeutronNetwork target = networkDB.get(uuid);\r
+        return overwrite(target, delta);\r
+    }\r
+\r
+    public boolean networkInUse(String netUUID) {\r
+        if (!networkExists(netUUID))\r
+            return true;\r
+        NeutronNetwork target = networkDB.get(netUUID);\r
+        if (target.getPortsOnNetwork().size() > 0)\r
+            return true;\r
+        return false;\r
+    }\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronPortInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronPortInterface.java
new file mode 100644 (file)
index 0000000..eea1977
--- /dev/null
@@ -0,0 +1,313 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.implementation;\r
+\r
+import java.lang.reflect.Method;\r
+import java.util.ArrayList;\r
+import java.util.Dictionary;\r
+import java.util.EnumSet;\r
+import java.util.HashSet;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Set;\r
+import java.util.Map.Entry;\r
+import java.util.concurrent.ConcurrentMap;\r
+\r
+import org.apache.felix.dm.Component;\r
+import org.opendaylight.controller.clustering.services.CacheConfigException;\r
+import org.opendaylight.controller.clustering.services.CacheExistException;\r
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
+import org.opendaylight.controller.clustering.services.IClusterServices;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
+import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+public class NeutronPortInterface implements INeutronPortCRUD {\r
+    private static final Logger logger = LoggerFactory.getLogger(NeutronPortInterface.class);\r
+    private String containerName = null;\r
+\r
+    private IClusterContainerServices clusterContainerService = null;\r
+    private ConcurrentMap<String, NeutronPort> portDB;\r
+\r
+    // methods needed for creating caches\r
+\r
+    void setClusterContainerService(IClusterContainerServices s) {\r
+        logger.debug("Cluster Service set");\r
+        this.clusterContainerService = s;\r
+    }\r
+\r
+    void unsetClusterContainerService(IClusterContainerServices s) {\r
+        if (this.clusterContainerService == s) {\r
+            logger.debug("Cluster Service removed!");\r
+            this.clusterContainerService = null;\r
+        }\r
+    }\r
+\r
+    @SuppressWarnings("deprecation")\r
+    private void allocateCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterContainerService, can't create cache");\r
+            return;\r
+        }\r
+        logger.debug("Creating Cache for OpenDOVE");\r
+        try {\r
+            // neutron caches\r
+            this.clusterContainerService.createCache("neutronPorts",\r
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
+        } catch (CacheConfigException cce) {\r
+            logger.error("Cache couldn't be created for OpenDOVE -  check cache mode");\r
+        } catch (CacheExistException cce) {\r
+            logger.error("Cache for OpenDOVE already exists, destroy and recreate");\r
+        }\r
+        logger.debug("Cache successfully created for OpenDOVE");\r
+    }\r
+\r
+    @SuppressWarnings({ "unchecked", "deprecation" })\r
+    private void retrieveCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
+            return;\r
+        }\r
+\r
+        logger.debug("Retrieving cache for Neutron Ports");\r
+        portDB = (ConcurrentMap<String, NeutronPort>) this.clusterContainerService\r
+        .getCache("neutronPorts");\r
+        if (portDB == null) {\r
+            logger.error("Cache couldn't be retrieved for Neutron Ports");\r
+        }\r
+        logger.debug("Cache was successfully retrieved for Neutron Ports");\r
+    }\r
+\r
+    @SuppressWarnings("deprecation")\r
+    private void destroyCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterMger, can't destroy cache");\r
+            return;\r
+        }\r
+        logger.debug("Destroying Cache for HostTracker");\r
+        this.clusterContainerService.destroyCache("neutronPorts");\r
+    }\r
+\r
+    private void startUp() {\r
+        allocateCache();\r
+        retrieveCache();\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager when all the required\r
+     * dependencies are satisfied\r
+     *\r
+     */\r
+    void init(Component c) {\r
+        Dictionary<?, ?> props = c.getServiceProperties();\r
+        if (props != null) {\r
+            this.containerName = (String) props.get("containerName");\r
+            logger.debug("Running containerName: {}", this.containerName);\r
+        } else {\r
+            // In the Global instance case the containerName is empty\r
+            this.containerName = "";\r
+        }\r
+        startUp();\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager when at least one dependency\r
+     * become unsatisfied or when the component is shutting down because for\r
+     * example bundle is being stopped.\r
+     *\r
+     */\r
+    void destroy() {\r
+        destroyCache();\r
+    }\r
+\r
+    /**\r
+     * Function called by dependency manager after "init ()" is called and after\r
+     * the services provided by the class are registered in the service registry\r
+     *\r
+     */\r
+    void start() {\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager before the services exported by\r
+     * the component are unregistered, this will be followed by a "destroy ()"\r
+     * calls\r
+     *\r
+     */\r
+    void stop() {\r
+    }\r
+\r
+    // this method uses reflection to update an object from it's delta.\r
+\r
+    private boolean overwrite(Object target, Object delta) {\r
+        Method[] methods = target.getClass().getMethods();\r
+\r
+        for(Method toMethod: methods){\r
+            if(toMethod.getDeclaringClass().equals(target.getClass())\r
+                    && toMethod.getName().startsWith("set")){\r
+\r
+                String toName = toMethod.getName();\r
+                String fromName = toName.replace("set", "get");\r
+\r
+                try {\r
+                    Method fromMethod = delta.getClass().getMethod(fromName);\r
+                    Object value = fromMethod.invoke(delta, (Object[])null);\r
+                    if(value != null){\r
+                        toMethod.invoke(target, value);\r
+                    }\r
+                } catch (Exception e) {\r
+                    e.printStackTrace();\r
+                    return false;\r
+                }\r
+            }\r
+        }\r
+        return true;\r
+    }\r
+\r
+    // IfNBPortCRUD methods\r
+\r
+    public boolean portExists(String uuid) {\r
+        return portDB.containsKey(uuid);\r
+    }\r
+\r
+    public NeutronPort getPort(String uuid) {\r
+        if (!portExists(uuid))\r
+            return null;\r
+        return portDB.get(uuid);\r
+    }\r
+\r
+    public List<NeutronPort> getAllPorts() {\r
+        Set<NeutronPort> allPorts = new HashSet<NeutronPort>();\r
+        for (Entry<String, NeutronPort> entry : portDB.entrySet()) {\r
+            NeutronPort port = entry.getValue();\r
+            allPorts.add(port);\r
+        }\r
+        logger.debug("Exiting getAllPorts, Found {} OpenStackPorts", allPorts.size());\r
+        List<NeutronPort> ans = new ArrayList<NeutronPort>();\r
+        ans.addAll(allPorts);\r
+        return ans;\r
+    }\r
+\r
+    public boolean addPort(NeutronPort input) {\r
+        if (portExists(input.getID()))\r
+            return false;\r
+        portDB.putIfAbsent(input.getID(), input);\r
+        // if there are no fixed IPs, allocate one for each subnet in the network\r
+        INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
+        if (input.getFixedIPs().size() == 0) {\r
+            List<Neutron_IPs> list = input.getFixedIPs();\r
+            Iterator<NeutronSubnet> subnetIterator = systemCRUD.getAllSubnets().iterator();\r
+            while (subnetIterator.hasNext()) {\r
+                NeutronSubnet subnet = subnetIterator.next();\r
+                if (subnet.getNetworkUUID().equals(input.getNetworkUUID()))\r
+                    list.add(new Neutron_IPs(subnet.getID()));\r
+            }\r
+        }\r
+        Iterator<Neutron_IPs> fixedIPIterator = input.getFixedIPs().iterator();\r
+        while (fixedIPIterator.hasNext()) {\r
+            Neutron_IPs ip = fixedIPIterator.next();\r
+            NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());\r
+            if (ip.getIpAddress() == null)\r
+                ip.setIpAddress(subnet.getLowAddr());\r
+            if (!ip.getIpAddress().equals(subnet.getGatewayIP()))\r
+                subnet.allocateIP(ip.getIpAddress());\r
+            else\r
+                subnet.setGatewayIPAllocated();\r
+            subnet.addPort(input);\r
+        }\r
+        INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
+\r
+        NeutronNetwork network = networkIf.getNetwork(input.getNetworkUUID());\r
+        network.addPort(input);\r
+        return true;\r
+    }\r
+\r
+    public boolean removePort(String uuid) {\r
+        if (!portExists(uuid))\r
+            return false;\r
+        NeutronPort port = getPort(uuid);\r
+        portDB.remove(uuid);\r
+        INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
+        INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
+\r
+        NeutronNetwork network = networkCRUD.getNetwork(port.getNetworkUUID());\r
+        network.removePort(port);\r
+        Iterator<Neutron_IPs> fixedIPIterator = port.getFixedIPs().iterator();\r
+        while (fixedIPIterator.hasNext()) {\r
+            Neutron_IPs ip = fixedIPIterator.next();\r
+            NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());\r
+            if (!ip.getIpAddress().equals(subnet.getGatewayIP()))\r
+                subnet.releaseIP(ip.getIpAddress());\r
+            else\r
+                subnet.resetGatewayIPAllocated();\r
+            subnet.removePort(port);\r
+        }\r
+        return true;\r
+    }\r
+\r
+    public boolean updatePort(String uuid, NeutronPort delta) {\r
+        if (!portExists(uuid))\r
+            return false;\r
+        NeutronPort target = portDB.get(uuid);\r
+        // remove old Fixed_IPs\r
+        NeutronPort port = getPort(uuid);\r
+        INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
+        Iterator<Neutron_IPs> fixedIPIterator = port.getFixedIPs().iterator();\r
+        while (fixedIPIterator.hasNext()) {\r
+            Neutron_IPs ip = fixedIPIterator.next();\r
+            NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());\r
+            subnet.releaseIP(ip.getIpAddress());\r
+        }\r
+\r
+        // allocate new Fixed_IPs\r
+        fixedIPIterator = delta.getFixedIPs().iterator();\r
+        while (fixedIPIterator.hasNext()) {\r
+            Neutron_IPs ip = fixedIPIterator.next();\r
+            NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());\r
+            if (ip.getIpAddress() == null)\r
+                ip.setIpAddress(subnet.getLowAddr());\r
+            subnet.allocateIP(ip.getIpAddress());\r
+        }\r
+        return overwrite(target, delta);\r
+    }\r
+\r
+    public boolean macInUse(String macAddress) {\r
+        List<NeutronPort> ports = getAllPorts();\r
+        Iterator<NeutronPort> portIterator = ports.iterator();\r
+        while (portIterator.hasNext()) {\r
+            NeutronPort port = portIterator.next();\r
+            if (macAddress.equalsIgnoreCase(port.getMacAddress()))\r
+                return true;\r
+        }\r
+        return false;\r
+    }\r
+\r
+    public NeutronPort getGatewayPort(String subnetUUID) {\r
+        INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
+        NeutronSubnet subnet = systemCRUD.getSubnet(subnetUUID);\r
+        Iterator<NeutronPort> portIterator = getAllPorts().iterator();\r
+        while (portIterator.hasNext()) {\r
+            NeutronPort port = portIterator.next();\r
+            List<Neutron_IPs> fixedIPs = port.getFixedIPs();\r
+            if (fixedIPs.size() == 1) {\r
+                if (subnet.getGatewayIP().equals(fixedIPs.get(0).getIpAddress()))\r
+                    return port;\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronRouterInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronRouterInterface.java
new file mode 100644 (file)
index 0000000..0a7afa5
--- /dev/null
@@ -0,0 +1,224 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.implementation;\r
+\r
+import java.lang.reflect.Method;\r
+import java.util.ArrayList;\r
+import java.util.Dictionary;\r
+import java.util.EnumSet;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+import java.util.Map.Entry;\r
+import java.util.concurrent.ConcurrentMap;\r
+\r
+import org.apache.felix.dm.Component;\r
+import org.opendaylight.controller.clustering.services.CacheConfigException;\r
+import org.opendaylight.controller.clustering.services.CacheExistException;\r
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
+import org.opendaylight.controller.clustering.services.IClusterServices;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+public class NeutronRouterInterface implements INeutronRouterCRUD {\r
+    private static final Logger logger = LoggerFactory.getLogger(NeutronRouterInterface.class);\r
+    private String containerName = null;\r
+\r
+    private IClusterContainerServices clusterContainerService = null;\r
+    private ConcurrentMap<String, NeutronRouter> routerDB;\r
+    // methods needed for creating caches\r
+\r
+    void setClusterContainerService(IClusterContainerServices s) {\r
+        logger.debug("Cluster Service set");\r
+        this.clusterContainerService = s;\r
+    }\r
+\r
+    void unsetClusterContainerService(IClusterContainerServices s) {\r
+        if (this.clusterContainerService == s) {\r
+            logger.debug("Cluster Service removed!");\r
+            this.clusterContainerService = null;\r
+        }\r
+    }\r
+\r
+    @SuppressWarnings("deprecation")\r
+    private void allocateCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterContainerService, can't create cache");\r
+            return;\r
+        }\r
+        logger.debug("Creating Cache for Neutron Routers");\r
+        try {\r
+            // neutron caches\r
+            this.clusterContainerService.createCache("neutronRouters",\r
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
+        } catch (CacheConfigException cce) {\r
+            logger.error("Cache couldn't be created for Neutron Routers -  check cache mode");\r
+        } catch (CacheExistException cce) {\r
+            logger.error("Cache for Neutron Routers already exists, destroy and recreate");\r
+        }\r
+        logger.debug("Cache successfully created for Neutron Routers");\r
+    }\r
+\r
+    @SuppressWarnings({ "unchecked", "deprecation" })\r
+    private void retrieveCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
+            return;\r
+        }\r
+\r
+        logger.debug("Retrieving cache for Neutron Routers");\r
+        routerDB = (ConcurrentMap<String, NeutronRouter>) this.clusterContainerService\r
+        .getCache("neutronRouters");\r
+        if (routerDB == null) {\r
+            logger.error("Cache couldn't be retrieved for Neutron Routers");\r
+        }\r
+        logger.debug("Cache was successfully retrieved for Neutron Routers");\r
+    }\r
+\r
+    @SuppressWarnings("deprecation")\r
+    private void destroyCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterMger, can't destroy cache");\r
+            return;\r
+        }\r
+        logger.debug("Destroying Cache for HostTracker");\r
+        this.clusterContainerService.destroyCache("neutronRouters");\r
+    }\r
+\r
+    private void startUp() {\r
+        allocateCache();\r
+        retrieveCache();\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager when all the required\r
+     * dependencies are satisfied\r
+     *\r
+     */\r
+    void init(Component c) {\r
+        Dictionary<?, ?> props = c.getServiceProperties();\r
+        if (props != null) {\r
+            this.containerName = (String) props.get("containerName");\r
+            logger.debug("Running containerName: {}", this.containerName);\r
+        } else {\r
+            // In the Global instance case the containerName is empty\r
+            this.containerName = "";\r
+        }\r
+        startUp();\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager when at least one dependency\r
+     * become unsatisfied or when the component is shutting down because for\r
+     * example bundle is being stopped.\r
+     *\r
+     */\r
+    void destroy() {\r
+        destroyCache();\r
+    }\r
+\r
+    /**\r
+     * Function called by dependency manager after "init ()" is called and after\r
+     * the services provided by the class are registered in the service registry\r
+     *\r
+     */\r
+    void start() {\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager before the services exported by\r
+     * the component are unregistered, this will be followed by a "destroy ()"\r
+     * calls\r
+     *\r
+     */\r
+    void stop() {\r
+    }\r
+\r
+    // this method uses reflection to update an object from it's delta.\r
+\r
+    private boolean overwrite(Object target, Object delta) {\r
+        Method[] methods = target.getClass().getMethods();\r
+\r
+        for(Method toMethod: methods){\r
+            if(toMethod.getDeclaringClass().equals(target.getClass())\r
+                    && toMethod.getName().startsWith("set")){\r
+\r
+                String toName = toMethod.getName();\r
+                String fromName = toName.replace("set", "get");\r
+\r
+                try {\r
+                    Method fromMethod = delta.getClass().getMethod(fromName);\r
+                    Object value = fromMethod.invoke(delta, (Object[])null);\r
+                    if(value != null){\r
+                        toMethod.invoke(target, value);\r
+                    }\r
+                } catch (Exception e) {\r
+                    e.printStackTrace();\r
+                    return false;\r
+                }\r
+            }\r
+        }\r
+        return true;\r
+    }\r
+\r
+\r
+    // IfNBRouterCRUD Interface methods\r
+\r
+    public boolean routerExists(String uuid) {\r
+        return routerDB.containsKey(uuid);\r
+    }\r
+\r
+    public NeutronRouter getRouter(String uuid) {\r
+        if (!routerExists(uuid))\r
+            return null;\r
+        return routerDB.get(uuid);\r
+    }\r
+\r
+    public List<NeutronRouter> getAllRouters() {\r
+        Set<NeutronRouter> allRouters = new HashSet<NeutronRouter>();\r
+        for (Entry<String, NeutronRouter> entry : routerDB.entrySet()) {\r
+            NeutronRouter router = entry.getValue();\r
+            allRouters.add(router);\r
+        }\r
+        logger.debug("Exiting getAllRouters, Found {} Routers", allRouters.size());\r
+        List<NeutronRouter> ans = new ArrayList<NeutronRouter>();\r
+        ans.addAll(allRouters);\r
+        return ans;\r
+    }\r
+\r
+    public boolean addRouter(NeutronRouter input) {\r
+        if (routerExists(input.getID()))\r
+            return false;\r
+        routerDB.putIfAbsent(input.getID(), input);\r
+        return true;\r
+    }\r
+\r
+    public boolean removeRouter(String uuid) {\r
+        if (!routerExists(uuid))\r
+            return false;\r
+        routerDB.remove(uuid);\r
+        return true;\r
+    }\r
+\r
+    public boolean updateRouter(String uuid, NeutronRouter delta) {\r
+        if (!routerExists(uuid))\r
+            return false;\r
+        NeutronRouter target = routerDB.get(uuid);\r
+        return overwrite(target, delta);\r
+    }\r
+\r
+    public boolean routerInUse(String routerUUID) {\r
+        if (!routerExists(routerUUID))\r
+            return true;\r
+        NeutronRouter target = routerDB.get(routerUUID);\r
+        return (target.getInterfaces().size() > 0);\r
+    }\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSubnetInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSubnetInterface.java
new file mode 100644 (file)
index 0000000..0fc3337
--- /dev/null
@@ -0,0 +1,238 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.implementation;\r
+\r
+import java.lang.reflect.Method;\r
+import java.util.ArrayList;\r
+import java.util.Dictionary;\r
+import java.util.EnumSet;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+import java.util.Map.Entry;\r
+import java.util.concurrent.ConcurrentMap;\r
+\r
+import org.apache.felix.dm.Component;\r
+import org.opendaylight.controller.clustering.services.CacheConfigException;\r
+import org.opendaylight.controller.clustering.services.CacheExistException;\r
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
+import org.opendaylight.controller.clustering.services.IClusterServices;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+public class NeutronSubnetInterface implements INeutronSubnetCRUD {\r
+    private static final Logger logger = LoggerFactory.getLogger(NeutronSubnetInterface.class);\r
+    private String containerName = null;\r
+\r
+    private IClusterContainerServices clusterContainerService = null;\r
+    private ConcurrentMap<String, NeutronSubnet> subnetDB;\r
+\r
+    // methods needed for creating caches\r
+\r
+    void setClusterContainerService(IClusterContainerServices s) {\r
+        logger.debug("Cluster Service set");\r
+        this.clusterContainerService = s;\r
+    }\r
+\r
+    void unsetClusterContainerService(IClusterContainerServices s) {\r
+        if (this.clusterContainerService == s) {\r
+            logger.debug("Cluster Service removed!");\r
+            this.clusterContainerService = null;\r
+        }\r
+    }\r
+\r
+    @SuppressWarnings("deprecation")\r
+    private void allocateCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterContainerService, can't create cache");\r
+            return;\r
+        }\r
+        logger.debug("Creating Cache for Neutron Subnets");\r
+        try {\r
+            // neutron caches\r
+            this.clusterContainerService.createCache("neutronSubnets",\r
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
+        } catch (CacheConfigException cce) {\r
+            logger.error("Cache couldn't be created for Neutron Subnets -  check cache mode");\r
+        } catch (CacheExistException cce) {\r
+            logger.error("Cache for Neutron Subnets already exists, destroy and recreate");\r
+        }\r
+        logger.debug("Cache successfully created for Neutron Subnets");\r
+    }\r
+\r
+    @SuppressWarnings({ "unchecked", "deprecation" })\r
+    private void retrieveCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
+            return;\r
+        }\r
+\r
+        logger.debug("Retrieving cache for Neutron Subnets");\r
+        subnetDB = (ConcurrentMap<String, NeutronSubnet>) this.clusterContainerService\r
+        .getCache("neutronSubnets");\r
+        if (subnetDB == null) {\r
+            logger.error("Cache couldn't be retrieved for Neutron Subnets");\r
+        }\r
+        logger.debug("Cache was successfully retrieved for Neutron Subnets");\r
+    }\r
+\r
+    @SuppressWarnings("deprecation")\r
+    private void destroyCache() {\r
+        if (this.clusterContainerService == null) {\r
+            logger.error("un-initialized clusterMger, can't destroy cache");\r
+            return;\r
+        }\r
+        logger.debug("Destroying Cache for HostTracker");\r
+        this.clusterContainerService.destroyCache("neutronSubnets");\r
+    }\r
+\r
+    private void startUp() {\r
+        allocateCache();\r
+        retrieveCache();\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager when all the required\r
+     * dependencies are satisfied\r
+     *\r
+     */\r
+    void init(Component c) {\r
+        Dictionary<?, ?> props = c.getServiceProperties();\r
+        if (props != null) {\r
+            this.containerName = (String) props.get("containerName");\r
+            logger.debug("Running containerName: {}", this.containerName);\r
+        } else {\r
+            // In the Global instance case the containerName is empty\r
+            this.containerName = "";\r
+        }\r
+        startUp();\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager when at least one dependency\r
+     * become unsatisfied or when the component is shutting down because for\r
+     * example bundle is being stopped.\r
+     *\r
+     */\r
+    void destroy() {\r
+        destroyCache();\r
+    }\r
+\r
+    /**\r
+     * Function called by dependency manager after "init ()" is called and after\r
+     * the services provided by the class are registered in the service registry\r
+     *\r
+     */\r
+    void start() {\r
+    }\r
+\r
+    /**\r
+     * Function called by the dependency manager before the services exported by\r
+     * the component are unregistered, this will be followed by a "destroy ()"\r
+     * calls\r
+     *\r
+     */\r
+    void stop() {\r
+    }\r
+\r
+    // this method uses reflection to update an object from it's delta.\r
+\r
+    private boolean overwrite(Object target, Object delta) {\r
+        Method[] methods = target.getClass().getMethods();\r
+\r
+        for(Method toMethod: methods){\r
+            if(toMethod.getDeclaringClass().equals(target.getClass())\r
+                    && toMethod.getName().startsWith("set")){\r
+\r
+                String toName = toMethod.getName();\r
+                String fromName = toName.replace("set", "get");\r
+\r
+                try {\r
+                    Method fromMethod = delta.getClass().getMethod(fromName);\r
+                    Object value = fromMethod.invoke(delta, (Object[])null);\r
+                    if(value != null){\r
+                        toMethod.invoke(target, value);\r
+                    }\r
+                } catch (Exception e) {\r
+                    e.printStackTrace();\r
+                    return false;\r
+                }\r
+            }\r
+        }\r
+        return true;\r
+    }\r
+\r
+\r
+    // IfNBSubnetCRUD methods\r
+\r
+    public boolean subnetExists(String uuid) {\r
+        return subnetDB.containsKey(uuid);\r
+    }\r
+\r
+    public NeutronSubnet getSubnet(String uuid) {\r
+        if (!subnetExists(uuid))\r
+            return null;\r
+        return subnetDB.get(uuid);\r
+    }\r
+\r
+    public List<NeutronSubnet> getAllSubnets() {\r
+        Set<NeutronSubnet> allSubnets = new HashSet<NeutronSubnet>();\r
+        for (Entry<String, NeutronSubnet> entry : subnetDB.entrySet()) {\r
+            NeutronSubnet subnet = entry.getValue();\r
+            allSubnets.add(subnet);\r
+        }\r
+        logger.debug("Exiting getAllSubnets, Found {} OpenStackSubnets", allSubnets.size());\r
+        List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();\r
+        ans.addAll(allSubnets);\r
+        return ans;\r
+    }\r
+\r
+    public boolean addSubnet(NeutronSubnet input) {\r
+        String id = input.getID();\r
+        if (subnetExists(id))\r
+            return false;\r
+        subnetDB.putIfAbsent(id, input);\r
+        INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
+\r
+        NeutronNetwork targetNet = networkIf.getNetwork(input.getNetworkUUID());\r
+        targetNet.addSubnet(id);\r
+        return true;\r
+    }\r
+\r
+    public boolean removeSubnet(String uuid) {\r
+        if (!subnetExists(uuid))\r
+            return false;\r
+        NeutronSubnet target = subnetDB.get(uuid);\r
+        INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
+\r
+        NeutronNetwork targetNet = networkIf.getNetwork(target.getNetworkUUID());\r
+        targetNet.removeSubnet(uuid);\r
+        subnetDB.remove(uuid);\r
+        return true;\r
+    }\r
+\r
+    public boolean updateSubnet(String uuid, NeutronSubnet delta) {\r
+        if (!subnetExists(uuid))\r
+            return false;\r
+        NeutronSubnet target = subnetDB.get(uuid);\r
+        return overwrite(target, delta);\r
+    }\r
+\r
+    public boolean subnetInUse(String subnetUUID) {\r
+        if (!subnetExists(subnetUUID))\r
+            return true;\r
+        NeutronSubnet target = subnetDB.get(subnetUUID);\r
+        return (target.getPortsInSubnet().size() > 0);\r
+    }\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/pom.xml b/opendaylight/networkconfiguration/neutron/pom.xml
new file mode 100644 (file)
index 0000000..a905ebf
--- /dev/null
@@ -0,0 +1,71 @@
+<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
+  <modelVersion>4.0.0</modelVersion>\r
+  <parent>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>commons.opendaylight</artifactId>\r
+    <version>1.4.0-SNAPSHOT</version>\r
+    <relativePath>../../commons/opendaylight</relativePath>\r
+  </parent>\r
+      <properties>\r
+        <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>\r
+        <enunciate.version>1.26.2</enunciate.version>\r
+    </properties>\r
+    <distributionManagement>\r
+        <!-- OpenDayLight Released artifact -->\r
+        <repository>\r
+            <id>opendaylight-release</id>\r
+            <url>${nexusproxy}/repositories/opendaylight.release/</url>\r
+        </repository>\r
+        <!-- OpenDayLight Snapshot artifact -->\r
+        <snapshotRepository>\r
+            <id>opendaylight-snapshot</id>\r
+            <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>\r
+        </snapshotRepository>\r
+        <!-- Site deployment -->\r
+        <site>\r
+            <id>website</id>\r
+            <url>${sitedeploy}</url>\r
+        </site>\r
+    </distributionManagement>\r
+  <groupId>org.opendaylight.controller</groupId>\r
+  <artifactId>networkconfig.neutron</artifactId>\r
+  <version>0.4.0-SNAPSHOT</version>\r
+  <packaging>bundle</packaging>\r
+  <build>\r
+        <plugins>\r
+            <plugin>\r
+                <groupId>org.apache.felix</groupId>\r
+                <artifactId>maven-bundle-plugin</artifactId>\r
+                <version>2.3.6</version>\r
+                <extensions>true</extensions>\r
+                <configuration>\r
+                    <instructions>\r
+                        <Import-Package>\r
+                            org.opendaylight.controller.clustering.services,\r
+                            org.opendaylight.controller.sal.core,\r
+                            org.opendaylight.controller.sal.utils,\r
+                            org.apache.felix.dm,\r
+                            org.apache.commons.net.util,\r
+                            org.osgi.service.component,\r
+                            org.slf4j,\r
+                            javax.xml.bind.annotation\r
+                        </Import-Package>\r
+                    </instructions>\r
+                    <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>\r
+                </configuration>\r
+            </plugin>\r
+        </plugins>\r
+    </build>\r
+     <dependencies>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller</groupId>\r
+            <artifactId>clustering.services</artifactId>\r
+            <version>0.4.0-SNAPSHOT</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller</groupId>\r
+            <artifactId>sal</artifactId>\r
+            <version>0.5.0-SNAPSHOT</version>\r
+        </dependency>\r
+    </dependencies>\r
+</project>\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFloatingIPAware.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFloatingIPAware.java
new file mode 100644 (file)
index 0000000..05d50be
--- /dev/null
@@ -0,0 +1,83 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+/**\r
+ * This interface defines the methods a service that wishes to be aware of Neutron FloatingIPs needs to implement\r
+ *\r
+ */\r
+\r
+public interface INeutronFloatingIPAware {\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified floatingIP can be created\r
+     *\r
+     * @param floatingIP\r
+     *            instance of proposed new Neutron FloatingIP object\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the create operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canCreateFloatingIP(NeutronFloatingIP floatingIP);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a floatingIP has been created\r
+     *\r
+     * @param floatingIP\r
+     *            instance of new Neutron FloatingIP object\r
+     * @return void\r
+     */\r
+    public void neutronFloatingIPCreated(NeutronFloatingIP floatingIP);\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified floatingIP can be changed using the specified\r
+     * delta\r
+     *\r
+     * @param delta\r
+     *            updates to the floatingIP object using patch semantics\r
+     * @param floatingIP\r
+     *            instance of the Neutron FloatingIP object to be updated\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the update operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canUpdateFloatingIP(NeutronFloatingIP delta, NeutronFloatingIP original);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a floatingIP has been updated\r
+     *\r
+     * @param floatingIP\r
+     *            instance of modified Neutron FloatingIP object\r
+     * @return void\r
+     */\r
+    public void neutronFloatingIPUpdated(NeutronFloatingIP floatingIP);\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified floatingIP can be deleted\r
+     *\r
+     * @param floatingIP\r
+     *            instance of the Neutron FloatingIP object to be deleted\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the delete operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canDeleteFloatingIP(NeutronFloatingIP floatingIP);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a floatingIP has been deleted\r
+     *\r
+     * @param floatingIP\r
+     *            instance of deleted Neutron FloatingIP object\r
+     * @return void\r
+     */\r
+    public void neutronFloatingIPDeleted(NeutronFloatingIP floatingIP);\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFloatingIPCRUD.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFloatingIPCRUD.java
new file mode 100644 (file)
index 0000000..7443dee
--- /dev/null
@@ -0,0 +1,83 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * This interface defines the methods for CRUD of NB FloatingIP objects\r
+ *\r
+ */\r
+\r
+public interface INeutronFloatingIPCRUD {\r
+    /**\r
+     * Applications call this interface method to determine if a particular\r
+     * FloatingIP object exists\r
+     *\r
+     * @param uuid\r
+     *            UUID of the FloatingIP object\r
+     * @return boolean\r
+     */\r
+\r
+    public boolean floatingIPExists(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to return if a particular\r
+     * FloatingIP object exists\r
+     *\r
+     * @param uuid\r
+     *            UUID of the FloatingIP object\r
+     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP.OpenStackFloatingIPs}\r
+     *          OpenStack FloatingIP class\r
+     */\r
+\r
+    public NeutronFloatingIP getFloatingIP(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to return all FloatingIP objects\r
+     *\r
+     * @return a Set of OpenStackFloatingIPs objects\r
+     */\r
+\r
+    public List<NeutronFloatingIP> getAllFloatingIPs();\r
+\r
+    /**\r
+     * Applications call this interface method to add a FloatingIP object to the\r
+     * concurrent map\r
+     *\r
+     * @param input\r
+     *            OpenStackFloatingIP object\r
+     * @return boolean on whether the object was added or not\r
+     */\r
+\r
+    public boolean addFloatingIP(NeutronFloatingIP input);\r
+\r
+    /**\r
+     * Applications call this interface method to remove a FloatingIP object to the\r
+     * concurrent map\r
+     *\r
+     * @param uuid\r
+     *            identifier for the FloatingIP object\r
+     * @return boolean on whether the object was removed or not\r
+     */\r
+\r
+    public boolean removeFloatingIP(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to edit a FloatingIP object\r
+     *\r
+     * @param uuid\r
+     *            identifier of the FloatingIP object\r
+     * @param delta\r
+     *            OpenStackFloatingIP object containing changes to apply\r
+     * @return boolean on whether the object was updated or not\r
+     */\r
+\r
+    public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta);\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronNetworkAware.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronNetworkAware.java
new file mode 100644 (file)
index 0000000..dc6df25
--- /dev/null
@@ -0,0 +1,83 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+/**\r
+ * This interface defines the methods a service that wishes to be aware of Neutron Networks needs to implement\r
+ *\r
+ */\r
+\r
+public interface INeutronNetworkAware {\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified network can be created\r
+     *\r
+     * @param network\r
+     *            instance of proposed new Neutron Network object\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the create operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canCreateNetwork(NeutronNetwork network);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a network has been created\r
+     *\r
+     * @param network\r
+     *            instance of new Neutron Network object\r
+     * @return void\r
+     */\r
+    public void neutronNetworkCreated(NeutronNetwork network);\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified network can be changed using the specified\r
+     * delta\r
+     *\r
+     * @param delta\r
+     *            updates to the network object using patch semantics\r
+     * @param network\r
+     *            instance of the Neutron Network object to be updated\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the update operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canUpdateNetwork(NeutronNetwork delta, NeutronNetwork original);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a network has been updated\r
+     *\r
+     * @param network\r
+     *            instance of modified Neutron Network object\r
+     * @return void\r
+     */\r
+    public void neutronNetworkUpdated(NeutronNetwork network);\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified network can be deleted\r
+     *\r
+     * @param network\r
+     *            instance of the Neutron Network object to be deleted\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the delete operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canDeleteNetwork(NeutronNetwork network);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a network has been deleted\r
+     *\r
+     * @param network\r
+     *            instance of deleted Neutron Network object\r
+     * @return void\r
+     */\r
+    public void neutronNetworkDeleted(NeutronNetwork network);\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronNetworkCRUD.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronNetworkCRUD.java
new file mode 100644 (file)
index 0000000..2481531
--- /dev/null
@@ -0,0 +1,95 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * This interface defines the methods for CRUD of NB network objects\r
+ *\r
+ */\r
+\r
+public interface INeutronNetworkCRUD {\r
+    /**\r
+     * Applications call this interface method to determine if a particular\r
+     * Network object exists\r
+     *\r
+     * @param uuid\r
+     *            UUID of the Network object\r
+     * @return boolean\r
+     */\r
+\r
+    public boolean networkExists(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to return if a particular\r
+     * Network object exists\r
+     *\r
+     * @param uuid\r
+     *            UUID of the Network object\r
+     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronNetwork.OpenStackNetworks}\r
+     *          OpenStack Network class\r
+     */\r
+\r
+    public NeutronNetwork getNetwork(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to return all Network objects\r
+     *\r
+     * @return List of OpenStackNetworks objects\r
+     */\r
+\r
+    public List<NeutronNetwork> getAllNetworks();\r
+\r
+    /**\r
+     * Applications call this interface method to add a Network object to the\r
+     * concurrent map\r
+     *\r
+     * @param input\r
+     *            OpenStackNetwork object\r
+     * @return boolean on whether the object was added or not\r
+     */\r
+\r
+    public boolean addNetwork(NeutronNetwork input);\r
+\r
+    /**\r
+     * Applications call this interface method to remove a Network object to the\r
+     * concurrent map\r
+     *\r
+     * @param uuid\r
+     *            identifier for the network object\r
+     * @return boolean on whether the object was removed or not\r
+     */\r
+\r
+    public boolean removeNetwork(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to edit a Network object\r
+     *\r
+     * @param uuid\r
+     *            identifier of the network object\r
+     * @param delta\r
+     *            OpenStackNetwork object containing changes to apply\r
+     * @return boolean on whether the object was updated or not\r
+     */\r
+\r
+    public boolean updateNetwork(String uuid, NeutronNetwork delta);\r
+\r
+    /**\r
+     * Applications call this interface method to determine if a Network object\r
+     * is use\r
+     *\r
+     * @param netUUID\r
+     *            identifier of the network object\r
+     *\r
+     * @return boolean on whether the network is in use or not\r
+     */\r
+\r
+    public boolean networkInUse(String netUUID);\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronPortAware.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronPortAware.java
new file mode 100644 (file)
index 0000000..36ed4ff
--- /dev/null
@@ -0,0 +1,83 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+/**\r
+ * This interface defines the methods a service that wishes to be aware of Neutron Ports needs to implement\r
+ *\r
+ */\r
+\r
+public interface INeutronPortAware {\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified port can be created\r
+     *\r
+     * @param port\r
+     *            instance of proposed new Neutron Port object\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the create operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canCreatePort(NeutronPort port);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a port has been created\r
+     *\r
+     * @param port\r
+     *            instance of new Neutron Port object\r
+     * @return void\r
+     */\r
+    public void neutronPortCreated(NeutronPort port);\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified port can be changed using the specified\r
+     * delta\r
+     *\r
+     * @param delta\r
+     *            updates to the port object using patch semantics\r
+     * @param port\r
+     *            instance of the Neutron Port object to be updated\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the update operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canUpdatePort(NeutronPort delta, NeutronPort original);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a port has been updated\r
+     *\r
+     * @param port\r
+     *            instance of modified Neutron Port object\r
+     * @return void\r
+     */\r
+    public void neutronPortUpdated(NeutronPort port);\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified port can be deleted\r
+     *\r
+     * @param port\r
+     *            instance of the Neutron Port object to be deleted\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the delete operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canDeletePort(NeutronPort port);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a port has been deleted\r
+     *\r
+     * @param port\r
+     *            instance of deleted Port Network object\r
+     * @return void\r
+     */\r
+    public void neutronPortDeleted(NeutronPort port);\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronPortCRUD.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronPortCRUD.java
new file mode 100644 (file)
index 0000000..681e925
--- /dev/null
@@ -0,0 +1,105 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * This interface defines the methods for CRUD of NB Port objects\r
+ *\r
+ */\r
+\r
+public interface INeutronPortCRUD {\r
+    /**\r
+     * Applications call this interface method to determine if a particular\r
+     * Port object exists\r
+     *\r
+     * @param uuid\r
+     *            UUID of the Port object\r
+     * @return boolean\r
+     */\r
+\r
+    public boolean portExists(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to return if a particular\r
+     * Port object exists\r
+     *\r
+     * @param uuid\r
+     *            UUID of the Port object\r
+     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronPort.OpenStackPorts}\r
+     *          OpenStack Port class\r
+     */\r
+\r
+    public NeutronPort getPort(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to return all Port objects\r
+     *\r
+     * @return List of OpenStackPorts objects\r
+     */\r
+\r
+    public List<NeutronPort> getAllPorts();\r
+\r
+    /**\r
+     * Applications call this interface method to add a Port object to the\r
+     * concurrent map\r
+     *\r
+     * @param input\r
+     *            OpenStackPort object\r
+     * @return boolean on whether the object was added or not\r
+     */\r
+\r
+    public boolean addPort(NeutronPort input);\r
+\r
+    /**\r
+     * Applications call this interface method to remove a Port object to the\r
+     * concurrent map\r
+     *\r
+     * @param uuid\r
+     *            identifier for the Port object\r
+     * @return boolean on whether the object was removed or not\r
+     */\r
+\r
+    public boolean removePort(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to edit a Port object\r
+     *\r
+     * @param uuid\r
+     *            identifier of the Port object\r
+     * @param delta\r
+     *            OpenStackPort object containing changes to apply\r
+     * @return boolean on whether the object was updated or not\r
+     */\r
+\r
+    public boolean updatePort(String uuid, NeutronPort delta);\r
+\r
+    /**\r
+     * Applications call this interface method to see if a MAC address is in use\r
+     *\r
+     * @param macAddress\r
+     *            mac Address to be tested\r
+     * @return boolean on whether the macAddress is already associated with a\r
+     * port or not\r
+     */\r
+\r
+    public boolean macInUse(String macAddress);\r
+\r
+    /**\r
+     * Applications call this interface method to retrieve the port associated with\r
+     * the gateway address of a subnet\r
+     *\r
+     * @param subnetUUID\r
+     *            identifier of the subnet\r
+     * @return OpenStackPorts object if the port exists and null if it does not\r
+     */\r
+\r
+    public NeutronPort getGatewayPort(String subnetUUID);\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronRouterAware.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronRouterAware.java
new file mode 100644 (file)
index 0000000..16a9aec
--- /dev/null
@@ -0,0 +1,105 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+/**\r
+ * This interface defines the methods a service that wishes to be aware of Neutron Routers needs to implement\r
+ *\r
+ */\r
+\r
+public interface INeutronRouterAware {\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified router can be created\r
+     *\r
+     * @param router\r
+     *            instance of proposed new Neutron Router object\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the create operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canCreateRouter(NeutronRouter router);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a router has been created\r
+     *\r
+     * @param router\r
+     *            instance of new Neutron Router object\r
+     * @return void\r
+     */\r
+    public void neutronRouterCreated(NeutronRouter router);\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified router can be changed using the specified\r
+     * delta\r
+     *\r
+     * @param delta\r
+     *            updates to the router object using patch semantics\r
+     * @param router\r
+     *            instance of the Neutron Router object to be updated\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the update operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canUpdateRouter(NeutronRouter delta, NeutronRouter original);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a router has been updated\r
+     *\r
+     * @param router\r
+     *            instance of modified Neutron Router object\r
+     * @return void\r
+     */\r
+    public void neutronRouterUpdated(NeutronRouter router);\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified router can be deleted\r
+     *\r
+     * @param router\r
+     *            instance of the Neutron Router object to be deleted\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the delete operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canDeleteRouter(NeutronRouter router);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a router has been deleted\r
+     *\r
+     * @param router\r
+     *            instance of deleted Router Network object\r
+     * @return void\r
+     */\r
+    public void neutronRouterDeleted(NeutronRouter router);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after an interface has been added to a router\r
+     *\r
+     * @param router\r
+     *            instance of the base Neutron Router object\r
+     * @param routerInterface\r
+     *            instance of the NeutronRouter_Interface being attached to the router\r
+     * @return void\r
+     */\r
+    public void neutronRouterInterfaceAttached(NeutronRouter router, NeutronRouter_Interface routerInterface);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after an interface has been removed from a router\r
+     *\r
+     * @param router\r
+     *            instance of the base Neutron Router object\r
+     * @param routerInterface\r
+     *            instance of the NeutronRouter_Interface being detached from the router\r
+     * @return void\r
+     */\r
+    public void neutronRouterInterfaceDetached(NeutronRouter router, NeutronRouter_Interface routerInterface);\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronRouterCRUD.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronRouterCRUD.java
new file mode 100644 (file)
index 0000000..19be16d
--- /dev/null
@@ -0,0 +1,93 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * This interface defines the methods for CRUD of NB Router objects\r
+ *\r
+ */\r
+\r
+public interface INeutronRouterCRUD {\r
+    /**\r
+     * Applications call this interface method to determine if a particular\r
+     * Router object exists\r
+     *\r
+     * @param uuid\r
+     *            UUID of the Router object\r
+     * @return boolean\r
+     */\r
+\r
+    public boolean routerExists(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to return if a particular\r
+     * Router object exists\r
+     *\r
+     * @param uuid\r
+     *            UUID of the Router object\r
+     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronRouter.OpenStackRouters}\r
+     *          OpenStack Router class\r
+     */\r
+\r
+    public NeutronRouter getRouter(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to return all Router objects\r
+     *\r
+     * @return List of OpenStackRouters objects\r
+     */\r
+\r
+    public List<NeutronRouter> getAllRouters();\r
+\r
+    /**\r
+     * Applications call this interface method to add a Router object to the\r
+     * concurrent map\r
+     *\r
+     * @param input\r
+     *            OpenStackRouter object\r
+     * @return boolean on whether the object was added or not\r
+     */\r
+\r
+    public boolean addRouter(NeutronRouter input);\r
+\r
+    /**\r
+     * Applications call this interface method to remove a Router object to the\r
+     * concurrent map\r
+     *\r
+     * @param uuid\r
+     *            identifier for the Router object\r
+     * @return boolean on whether the object was removed or not\r
+     */\r
+\r
+    public boolean removeRouter(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to edit a Router object\r
+     *\r
+     * @param uuid\r
+     *            identifier of the Router object\r
+     * @param delta\r
+     *            OpenStackRouter object containing changes to apply\r
+     * @return boolean on whether the object was updated or not\r
+     */\r
+\r
+    public boolean updateRouter(String uuid, NeutronRouter delta);\r
+\r
+    /**\r
+     * Applications call this interface method to check if a router is in use\r
+     *\r
+     * @param uuid\r
+     *            identifier of the Router object\r
+     * @return boolean on whether the router is in use or not\r
+     */\r
+\r
+    public boolean routerInUse(String routerUUID);\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSubnetAware.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSubnetAware.java
new file mode 100644 (file)
index 0000000..b7bafab
--- /dev/null
@@ -0,0 +1,84 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+/**\r
+ * This interface defines the methods a service that wishes to be aware of Neutron Subnets needs to implement\r
+ *\r
+ */\r
+\r
+public interface INeutronSubnetAware {\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified subnet can be created\r
+     *\r
+     * @param subnet\r
+     *            instance of proposed new Neutron Subnet object\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the create operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canCreateSubnet(NeutronSubnet subnet);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a subnet has been created\r
+     *\r
+     * @param subnet\r
+     *            instance of new Neutron Subnet object\r
+     * @return void\r
+     */\r
+    public void neutronSubnetCreated(NeutronSubnet subnet);\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified subnet can be changed using the specified\r
+     * delta\r
+     *\r
+     * @param delta\r
+     *            updates to the subnet object using patch semantics\r
+     * @param subnet\r
+     *            instance of the Neutron Subnet object to be updated\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the update operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canUpdateSubnet(NeutronSubnet delta, NeutronSubnet original);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a subnet has been updated\r
+     *\r
+     * @param subnet\r
+     *            instance of modified Neutron Subnet object\r
+     * @return void\r
+     */\r
+    public void neutronSubnetUpdated(NeutronSubnet subnet);\r
+\r
+    /**\r
+     * Services provide this interface method to indicate if the specified subnet can be deleted\r
+     *\r
+     * @param subnet\r
+     *            instance of the Subnet Router object to be deleted\r
+     * @return integer\r
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
+     *            results in the delete operation being interrupted and the returned status value reflected in the\r
+     *            HTTP response.\r
+     */\r
+    public int canDeleteSubnet(NeutronSubnet subnet);\r
+\r
+    /**\r
+     * Services provide this interface method for taking action after a subnet has been deleted\r
+     *\r
+     * @param subnet\r
+     *            instance of deleted Router Subnet object\r
+     * @return void\r
+     */\r
+    public void neutronSubnetDeleted(NeutronSubnet subnet);\r
+\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSubnetCRUD.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSubnetCRUD.java
new file mode 100644 (file)
index 0000000..9c39046
--- /dev/null
@@ -0,0 +1,95 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * This interface defines the methods for CRUD of NB Subnet objects\r
+ *\r
+ */\r
+\r
+public interface INeutronSubnetCRUD {\r
+    /**\r
+     * Applications call this interface method to determine if a particular\r
+     * Subnet object exists\r
+     *\r
+     * @param uuid\r
+     *            UUID of the Subnet object\r
+     * @return boolean\r
+     */\r
+\r
+    public boolean subnetExists(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to return if a particular\r
+     * Subnet object exists\r
+     *\r
+     * @param uuid\r
+     *            UUID of the Subnet object\r
+     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronSubnet.OpenStackSubnets}\r
+     *          OpenStack Subnet class\r
+     */\r
+\r
+    public NeutronSubnet getSubnet(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to return all Subnet objects\r
+     *\r
+     * @return List of OpenStackSubnets objects\r
+     */\r
+\r
+    public List<NeutronSubnet> getAllSubnets();\r
+\r
+    /**\r
+     * Applications call this interface method to add a Subnet object to the\r
+     * concurrent map\r
+     *\r
+     * @param input\r
+     *            OpenStackSubnet object\r
+     * @return boolean on whether the object was added or not\r
+     */\r
+\r
+    public boolean addSubnet(NeutronSubnet input);\r
+\r
+    /**\r
+     * Applications call this interface method to remove a Subnet object to the\r
+     * concurrent map\r
+     *\r
+     * @param uuid\r
+     *            identifier for the Subnet object\r
+     * @return boolean on whether the object was removed or not\r
+     */\r
+\r
+    public boolean removeSubnet(String uuid);\r
+\r
+    /**\r
+     * Applications call this interface method to edit a Subnet object\r
+     *\r
+     * @param uuid\r
+     *            identifier of the Subnet object\r
+     * @param delta\r
+     *            OpenStackSubnet object containing changes to apply\r
+     * @return boolean on whether the object was updated or not\r
+     */\r
+\r
+    public boolean updateSubnet(String uuid, NeutronSubnet delta);\r
+\r
+    /**\r
+     * Applications call this interface method to determine if a Subnet object\r
+     * is use\r
+     *\r
+     * @param subnetUUID\r
+     *            identifier of the subnet object\r
+     *\r
+     * @return boolean on whether the subnet is in use or not\r
+     */\r
+\r
+    public boolean subnetInUse(String subnetUUID);\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronCRUDInterfaces.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronCRUDInterfaces.java
new file mode 100644 (file)
index 0000000..0becb47
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import org.opendaylight.controller.sal.utils.ServiceHelper;\r
+\r
+public class NeutronCRUDInterfaces {\r
+\r
+    public static INeutronNetworkCRUD getINeutronNetworkCRUD(Object o) {\r
+        INeutronNetworkCRUD answer = (INeutronNetworkCRUD) ServiceHelper.getGlobalInstance(INeutronNetworkCRUD.class, o);\r
+        return answer;\r
+    }\r
+\r
+    public static INeutronSubnetCRUD getINeutronSubnetCRUD(Object o) {\r
+        INeutronSubnetCRUD answer = (INeutronSubnetCRUD) ServiceHelper.getGlobalInstance(INeutronSubnetCRUD.class, o);\r
+        return answer;\r
+    }\r
+\r
+    public static INeutronPortCRUD getINeutronPortCRUD(Object o) {\r
+        INeutronPortCRUD answer = (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, o);\r
+        return answer;\r
+    }\r
+\r
+    public static INeutronRouterCRUD getINeutronRouterCRUD(Object o) {\r
+        INeutronRouterCRUD answer = (INeutronRouterCRUD) ServiceHelper.getGlobalInstance(INeutronRouterCRUD.class, o);\r
+        return answer;\r
+    }\r
+\r
+    public static INeutronFloatingIPCRUD getINeutronFloatingIPCRUD(Object o) {\r
+        INeutronFloatingIPCRUD answer = (INeutronFloatingIPCRUD) ServiceHelper.getGlobalInstance(INeutronFloatingIPCRUD.class, o);\r
+        return answer;\r
+    }\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronFloatingIP.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronFloatingIP.java
new file mode 100644 (file)
index 0000000..906b4d4
--- /dev/null
@@ -0,0 +1,130 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+\r
+public class NeutronFloatingIP {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement (name="id")\r
+    String floatingIPUUID;\r
+\r
+    @XmlElement (name="floating_network_id")\r
+    String floatingNetworkUUID;\r
+\r
+    @XmlElement (name="port_id")\r
+    String portUUID;\r
+\r
+    @XmlElement (name="fixed_ip_address")\r
+    String fixedIPAddress;\r
+\r
+    @XmlElement (name="floating_ip_address")\r
+    String floatingIPAddress;\r
+\r
+    @XmlElement (name="tenant_id")\r
+    String tenantUUID;\r
+\r
+    public NeutronFloatingIP() {\r
+    }\r
+\r
+    public String getID() { return floatingIPUUID; }\r
+\r
+    public String getFloatingIPUUID() {\r
+        return floatingIPUUID;\r
+    }\r
+\r
+    public void setFloatingIPUUID(String floatingIPUUID) {\r
+        this.floatingIPUUID = floatingIPUUID;\r
+    }\r
+\r
+    public String getFloatingNetworkUUID() {\r
+        return floatingNetworkUUID;\r
+    }\r
+\r
+    public void setFloatingNetworkUUID(String floatingNetworkUUID) {\r
+        this.floatingNetworkUUID = floatingNetworkUUID;\r
+    }\r
+\r
+    public String getPortUUID() {\r
+        return portUUID;\r
+    }\r
+\r
+    public void setPortUUID(String portUUID) {\r
+        this.portUUID = portUUID;\r
+    }\r
+\r
+    public String getFixedIPAddress() {\r
+        return fixedIPAddress;\r
+    }\r
+\r
+    public void setFixedIPAddress(String fixedIPAddress) {\r
+        this.fixedIPAddress = fixedIPAddress;\r
+    }\r
+\r
+    public String getFloatingIPAddress() {\r
+        return floatingIPAddress;\r
+    }\r
+\r
+    public void setFloatingIPAddress(String floatingIPAddress) {\r
+        this.floatingIPAddress = floatingIPAddress;\r
+    }\r
+\r
+    public String getTenantUUID() {\r
+        return tenantUUID;\r
+    }\r
+\r
+    public void setTenantUUID(String tenantUUID) {\r
+        this.tenantUUID = tenantUUID;\r
+    }\r
+\r
+    /**\r
+     * This method copies selected fields from the object and returns them\r
+     * as a new object, suitable for marshaling.\r
+     *\r
+     * @param fields\r
+     *            List of attributes to be extracted\r
+     * @return an OpenStackFloatingIPs object with only the selected fields\r
+     * populated\r
+     */\r
+\r
+    public NeutronFloatingIP extractFields(List<String> fields) {\r
+        NeutronFloatingIP ans = new NeutronFloatingIP();\r
+        Iterator<String> i = fields.iterator();\r
+        while (i.hasNext()) {\r
+            String s = i.next();\r
+            if (s.equals("id"))\r
+                ans.setFloatingIPUUID(this.getFloatingIPUUID());\r
+            if (s.equals("floating_network_id"))\r
+                ans.setFloatingNetworkUUID(this.getFloatingNetworkUUID());\r
+            if (s.equals("port_id"))\r
+                ans.setPortUUID(this.getPortUUID());\r
+            if (s.equals("fixed_ip_address"))\r
+                ans.setFixedIPAddress(this.getFixedIPAddress());\r
+            if (s.equals("floating_ip_address"))\r
+                ans.setFloatingIPAddress(this.getFloatingIPAddress());\r
+            if (s.equals("tenant_id"))\r
+                ans.setTenantUUID(this.getTenantUUID());\r
+        }\r
+        return ans;\r
+    }\r
+\r
+    public void initDefaults() {\r
+    }\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java
new file mode 100644 (file)
index 0000000..eccbbcc
--- /dev/null
@@ -0,0 +1,233 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+@XmlRootElement(name = "network")\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+\r
+public class NeutronNetwork {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement (name="id")\r
+    String networkUUID;              // network UUID\r
+\r
+    @XmlElement (name="name")\r
+    String networkName;              // name\r
+\r
+    @XmlElement (defaultValue="true", name="admin_state_up")\r
+    Boolean adminStateUp;             // admin state up (true/false)\r
+\r
+    @XmlElement (defaultValue="false", name="shared")\r
+    Boolean shared;                   // shared network or not\r
+\r
+    @XmlElement (name="tenant_id")\r
+    String tenantID;                 // tenant for this network\r
+\r
+    @XmlElement (defaultValue="false", namespace="router", name="external")\r
+    Boolean routerExternal;           // network external or not\r
+\r
+    @XmlElement (defaultValue="flat", namespace="provider", name="network_type")\r
+    String providerNetworkType;      // provider network type (flat or vlan)\r
+\r
+    @XmlElement (namespace="provider", name="physical_network")\r
+    String providerPhysicalNetwork;  // provider physical network (name)\r
+\r
+    @XmlElement (namespace="provider", name="segmentation_id")\r
+    String providerSegmentationID;   // provide segmentation ID (vlan ID)\r
+\r
+    @XmlElement (name="status")\r
+    String status;                   // status (read-only)\r
+\r
+    @XmlElement (name="subnets")\r
+    List<String> subnets;            // subnets (read-only)\r
+\r
+    /* This attribute lists the ports associated with an instance\r
+     * which is needed for determining if that instance can be deleted\r
+     */\r
+\r
+    List<NeutronPort> myPorts;\r
+\r
+    public NeutronNetwork() {\r
+        myPorts = new ArrayList<NeutronPort>();\r
+    }\r
+\r
+    public void initDefaults() {\r
+        subnets = new ArrayList<String>();\r
+        if (this.status == null)\r
+            this.status = "ACTIVE";\r
+        if (this.adminStateUp == null)\r
+            this.adminStateUp = true;\r
+        if (this.shared == null)\r
+            this.shared = false;\r
+        if (this.routerExternal == null)\r
+            this.routerExternal = false;\r
+        if (this.providerNetworkType == null)\r
+            this.providerNetworkType = "flat";\r
+    }\r
+\r
+    public String getID() { return networkUUID; }\r
+\r
+    public String getNetworkUUID() {\r
+        return networkUUID;\r
+    }\r
+\r
+    public void setNetworkUUID(String networkUUID) {\r
+        this.networkUUID = networkUUID;\r
+    }\r
+\r
+    public String getNetworkName() {\r
+        return networkName;\r
+    }\r
+\r
+    public void setNetworkName(String networkName) {\r
+        this.networkName = networkName;\r
+    }\r
+\r
+    public boolean isAdminStateUp() {\r
+        return adminStateUp;\r
+    }\r
+\r
+    public Boolean getAdminStateUp() { return adminStateUp; }\r
+\r
+    public void setAdminStateUp(boolean newValue) {\r
+        this.adminStateUp = newValue;\r
+    }\r
+\r
+    public boolean isShared() { return shared; }\r
+\r
+    public Boolean getShared() { return shared; }\r
+\r
+    public void setShared(boolean newValue) {\r
+        this.shared = newValue;\r
+    }\r
+\r
+    public String getTenantID() {\r
+        return tenantID;\r
+    }\r
+\r
+    public void setTenantID(String tenantID) {\r
+        this.tenantID = tenantID;\r
+    }\r
+\r
+    public boolean isRouterExternal() { return routerExternal; }\r
+\r
+    public Boolean getRouterExternal() { return routerExternal; }\r
+\r
+    public void setRouterExternal(boolean newValue) {\r
+        this.routerExternal = newValue;\r
+    }\r
+\r
+    public String getProviderNetworkType() {\r
+        return providerNetworkType;\r
+    }\r
+\r
+    public void setProviderNetworkType(String providerNetworkType) {\r
+        this.providerNetworkType = providerNetworkType;\r
+    }\r
+\r
+    public String getProviderPhysicalNetwork() {\r
+        return providerPhysicalNetwork;\r
+    }\r
+\r
+    public void setProviderPhysicalNetwork(String providerPhysicalNetwork) {\r
+        this.providerPhysicalNetwork = providerPhysicalNetwork;\r
+    }\r
+\r
+    public String getProviderSegmentationID() {\r
+        return providerSegmentationID;\r
+    }\r
+\r
+    public void setProviderSegmentationID(String providerSegmentationID) {\r
+        this.providerSegmentationID = providerSegmentationID;\r
+    }\r
+\r
+    public String getStatus() {\r
+        return status;\r
+    }\r
+\r
+    public void setStatus(String status) {\r
+        this.status = status;\r
+    }\r
+\r
+    public List<String> getSubnets() {\r
+        return subnets;\r
+    }\r
+\r
+    public void setSubnets(List<String> subnets) {\r
+        this.subnets = subnets;\r
+    }\r
+\r
+    public void addSubnet(String uuid) {\r
+        this.subnets.add(uuid);\r
+    }\r
+\r
+    public void removeSubnet(String uuid) {\r
+        this.subnets.remove(uuid);\r
+    }\r
+\r
+    public List<NeutronPort> getPortsOnNetwork() {\r
+        return myPorts;\r
+    }\r
+\r
+    public void addPort(NeutronPort port) {\r
+        myPorts.add(port);\r
+    }\r
+\r
+    public void removePort(NeutronPort port) {\r
+        myPorts.remove(port);\r
+    }\r
+\r
+    /**\r
+     * This method copies selected fields from the object and returns them\r
+     * as a new object, suitable for marshaling.\r
+     *\r
+     * @param fields\r
+     *            List of attributes to be extracted\r
+     * @return an OpenStackNetworks object with only the selected fields\r
+     * populated\r
+     */\r
+\r
+    public NeutronNetwork extractFields(List<String> fields) {\r
+        NeutronNetwork ans = new NeutronNetwork();\r
+        Iterator<String> i = fields.iterator();\r
+        while (i.hasNext()) {\r
+            String s = i.next();\r
+            if (s.equals("id"))\r
+                ans.setNetworkUUID(this.getNetworkUUID());\r
+            if (s.equals("name"))\r
+                ans.setNetworkName(this.getNetworkName());\r
+            if (s.equals("admin_state_up"))\r
+                ans.setAdminStateUp(this.adminStateUp);\r
+            if (s.equals("status"))\r
+                ans.setStatus(this.getStatus());\r
+            if (s.equals("subnets")) {\r
+                List<String> subnetList = new ArrayList<String>();\r
+                subnetList.addAll(this.getSubnets());\r
+                ans.setSubnets(subnetList);\r
+            }\r
+            if (s.equals("shared"))\r
+                ans.setShared(this.shared);\r
+            if (s.equals("tenant_id"))\r
+                ans.setTenantID(this.getTenantID());\r
+        }\r
+        return ans;\r
+    }\r
+\r
+}\r
+\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java
new file mode 100644 (file)
index 0000000..7f7f712
--- /dev/null
@@ -0,0 +1,239 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+\r
+public class NeutronPort {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement (name="id")\r
+    String portUUID;\r
+\r
+    @XmlElement (name="network_id")\r
+    String networkUUID;\r
+\r
+    @XmlElement (name="name")\r
+    String name;\r
+\r
+    @XmlElement (defaultValue="true", name="admin_state_up")\r
+    Boolean adminStateUp;\r
+\r
+    @XmlElement (name="status")\r
+    String status;\r
+\r
+    @XmlElement (name="mac_address")\r
+    String macAddress;\r
+\r
+    @XmlElement (name="fixed_ips")\r
+    List<Neutron_IPs> fixedIPs;\r
+\r
+    @XmlElement (name="device_id")\r
+    String deviceID;\r
+\r
+    @XmlElement (name="device_owner")\r
+    String deviceOwner;\r
+\r
+    @XmlElement (name="tenant_id")\r
+    String tenantID;\r
+\r
+    // TODO: add security groups\r
+    //        @XmlElement (name="security_groups")\r
+    //        List<String> securityGroups;\r
+\r
+    /* this attribute stores the floating IP address assigned to\r
+     * each fixed IP address\r
+     */\r
+\r
+    HashMap<String, NeutronFloatingIP> floatingIPMap;\r
+\r
+    public NeutronPort() {\r
+        floatingIPMap = new HashMap<String, NeutronFloatingIP>();\r
+    }\r
+\r
+    public String getID() { return portUUID; }\r
+\r
+    public String getPortUUID() {\r
+        return portUUID;\r
+    }\r
+\r
+    public void setPortUUID(String portUUID) {\r
+        this.portUUID = portUUID;\r
+    }\r
+\r
+    public String getNetworkUUID() {\r
+        return networkUUID;\r
+    }\r
+\r
+    public void setNetworkUUID(String networkUUID) {\r
+        this.networkUUID = networkUUID;\r
+    }\r
+\r
+    public String getName() {\r
+        return name;\r
+    }\r
+\r
+    public void setName(String name) {\r
+        this.name = name;\r
+    }\r
+\r
+    public boolean isAdminStateUp() {\r
+        if (adminStateUp == null)\r
+            return true;\r
+        return adminStateUp;\r
+    }\r
+\r
+    public Boolean getAdminStateUp() { return adminStateUp; }\r
+\r
+    public void setAdminStateUp(Boolean newValue) {\r
+            this.adminStateUp = newValue;\r
+    }\r
+\r
+    public String getStatus() {\r
+        return status;\r
+    }\r
+\r
+    public void setStatus(String status) {\r
+        this.status = status;\r
+    }\r
+\r
+    public String getMacAddress() {\r
+        return macAddress;\r
+    }\r
+\r
+    public void setMacAddress(String macAddress) {\r
+        this.macAddress = macAddress;\r
+    }\r
+\r
+    public List<Neutron_IPs> getFixedIPs() {\r
+        return fixedIPs;\r
+    }\r
+\r
+    public void setFixedIPs(List<Neutron_IPs> fixedIPs) {\r
+        this.fixedIPs = fixedIPs;\r
+    }\r
+\r
+    public String getDeviceID() {\r
+        return deviceID;\r
+    }\r
+\r
+    public void setDeviceID(String deviceID) {\r
+        this.deviceID = deviceID;\r
+    }\r
+\r
+    public String getDeviceOwner() {\r
+        return deviceOwner;\r
+    }\r
+\r
+    public void setDeviceOwner(String deviceOwner) {\r
+        this.deviceOwner = deviceOwner;\r
+    }\r
+\r
+    public String getTenantID() {\r
+        return tenantID;\r
+    }\r
+\r
+    public void setTenantID(String tenantID) {\r
+        this.tenantID = tenantID;\r
+    }\r
+\r
+    public NeutronFloatingIP getFloatingIP(String key) {\r
+        if (!floatingIPMap.containsKey(key))\r
+            return null;\r
+        return floatingIPMap.get(key);\r
+    }\r
+\r
+    public void removeFloatingIP(String key) {\r
+        floatingIPMap.remove(key);\r
+    }\r
+\r
+    public void addFloatingIP(String key, NeutronFloatingIP floatingIP) {\r
+        if (!floatingIPMap.containsKey(key))\r
+            floatingIPMap.put(key, floatingIP);\r
+    }\r
+\r
+    /**\r
+     * This method copies selected fields from the object and returns them\r
+     * as a new object, suitable for marshaling.\r
+     *\r
+     * @param fields\r
+     *            List of attributes to be extracted\r
+     * @return an OpenStackPorts object with only the selected fields\r
+     * populated\r
+     */\r
+\r
+    public NeutronPort extractFields(List<String> fields) {\r
+        NeutronPort ans = new NeutronPort();\r
+        Iterator<String> i = fields.iterator();\r
+        while (i.hasNext()) {\r
+            String s = i.next();\r
+            if (s.equals("id"))\r
+                ans.setPortUUID(this.getPortUUID());\r
+            if (s.equals("network_id"))\r
+                ans.setNetworkUUID(this.getNetworkUUID());\r
+            if (s.equals("name"))\r
+                ans.setName(this.getName());\r
+            if (s.equals("admin_state_up"))\r
+                ans.setAdminStateUp(this.getAdminStateUp());\r
+            if (s.equals("status"))\r
+                ans.setStatus(this.getStatus());\r
+            if (s.equals("mac_address"))\r
+                ans.setMacAddress(this.getMacAddress());\r
+            if (s.equals("fixed_ips")) {\r
+                List<Neutron_IPs> fixedIPs = new ArrayList<Neutron_IPs>();\r
+                fixedIPs.addAll(this.getFixedIPs());\r
+                ans.setFixedIPs(fixedIPs);\r
+            }\r
+            if (s.equals("device_id")) {\r
+                ans.setDeviceID(this.getDeviceID());\r
+            }\r
+            if (s.equals("device_owner")) {\r
+                ans.setDeviceOwner(this.getDeviceOwner());\r
+            }\r
+            if (s.equals("tenant_id"))\r
+                ans.setTenantID(this.getTenantID());\r
+        }\r
+        return ans;\r
+    }\r
+\r
+    public void initDefaults() {\r
+        adminStateUp = true;\r
+        if (status == null)\r
+            status = "ACTIVE";\r
+        if (fixedIPs == null)\r
+            fixedIPs = new ArrayList<Neutron_IPs>();\r
+    }\r
+\r
+    /**\r
+     * This method checks to see if the port has a floating IPv4 address\r
+     * associated with the supplied fixed IPv4 address\r
+     *\r
+     * @param fixedIP\r
+     *            fixed IPv4 address in dotted decimal format\r
+     * @return a boolean indicating if there is a floating IPv4 address bound\r
+     * to the fixed IPv4 address\r
+     */\r
+\r
+    public boolean isBoundToFloatingIP(String fixedIP) {\r
+        return floatingIPMap.containsKey(fixedIP);\r
+    }\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java
new file mode 100644 (file)
index 0000000..8329ffc
--- /dev/null
@@ -0,0 +1,153 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+\r
+public class NeutronRouter {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+    @XmlElement (name="id")\r
+    String routerUUID;\r
+\r
+    @XmlElement (name="name")\r
+    String name;\r
+\r
+    @XmlElement (defaultValue="true", name="admin_state_up")\r
+    Boolean adminStateUp;\r
+\r
+    @XmlElement (name="status")\r
+    String status;\r
+\r
+    @XmlElement (name="tenant_id")\r
+    String tenantID;\r
+\r
+    @XmlElement (name="external_gateway_info")\r
+    NeutronRouter_NetworkReference externalGatewayInfo;\r
+\r
+    /* Holds a map of OpenStackRouterInterfaces by subnet UUID\r
+     * used for internal mapping to DOVE\r
+     */\r
+    HashMap<String, NeutronRouter_Interface> interfaces;\r
+\r
+    public NeutronRouter() {\r
+        interfaces = new HashMap<String, NeutronRouter_Interface>();\r
+    }\r
+\r
+    public String getID() { return routerUUID; }\r
+\r
+    public String getRouterUUID() {\r
+        return routerUUID;\r
+    }\r
+\r
+    public void setRouterUUID(String routerUUID) {\r
+        this.routerUUID = routerUUID;\r
+    }\r
+\r
+    public String getName() {\r
+        return name;\r
+    }\r
+\r
+    public void setName(String name) {\r
+        this.name = name;\r
+    }\r
+\r
+    public boolean isAdminStateUp() {\r
+        if (adminStateUp == null)\r
+            return true;\r
+        return adminStateUp;\r
+    }\r
+\r
+    public Boolean getAdminStateUp() { return adminStateUp; }\r
+\r
+    public void setAdminStateUp(Boolean newValue) {\r
+        this.adminStateUp = newValue;\r
+    }\r
+\r
+    public String getStatus() {\r
+        return status;\r
+    }\r
+\r
+    public void setStatus(String status) {\r
+        this.status = status;\r
+    }\r
+\r
+    public String getTenantID() {\r
+        return tenantID;\r
+    }\r
+\r
+    public void setTenantID(String tenantID) {\r
+        this.tenantID = tenantID;\r
+    }\r
+\r
+    public NeutronRouter_NetworkReference getExternalGatewayInfo() {\r
+        return externalGatewayInfo;\r
+    }\r
+\r
+    public void setExternalGatewayInfo(NeutronRouter_NetworkReference externalGatewayInfo) {\r
+        this.externalGatewayInfo = externalGatewayInfo;\r
+    }\r
+\r
+    /**\r
+     * This method copies selected fields from the object and returns them\r
+     * as a new object, suitable for marshaling.\r
+     *\r
+     * @param fields\r
+     *            List of attributes to be extracted\r
+     * @return an OpenStackRouters object with only the selected fields\r
+     * populated\r
+     */\r
+\r
+    public NeutronRouter extractFields(List<String> fields) {\r
+        NeutronRouter ans = new NeutronRouter();\r
+        Iterator<String> i = fields.iterator();\r
+        while (i.hasNext()) {\r
+            String s = i.next();\r
+            if (s.equals("id"))\r
+                ans.setRouterUUID(this.getRouterUUID());\r
+            if (s.equals("name"))\r
+                ans.setName(this.getName());\r
+            if (s.equals("admin_state_up"))\r
+                ans.setAdminStateUp(this.getAdminStateUp());\r
+            if (s.equals("status"))\r
+                ans.setStatus(this.getStatus());\r
+            if (s.equals("tenant_id"))\r
+                ans.setTenantID(this.getTenantID());\r
+            if (s.equals("external_gateway_info")) {\r
+                ans.setExternalGatewayInfo(this.getExternalGatewayInfo());\r
+            }\r
+        }\r
+        return ans;\r
+    }\r
+\r
+    public HashMap<String, NeutronRouter_Interface> getInterfaces() {\r
+        return interfaces;\r
+    }\r
+\r
+    public void addInterface(String s, NeutronRouter_Interface i) {\r
+        interfaces.put(s, i);\r
+    }\r
+\r
+    public void removeInterface(String s) {\r
+        interfaces.remove(s);\r
+    }\r
+\r
+    public void initDefaults() {\r
+        adminStateUp = true;\r
+    }\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_Interface.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_Interface.java
new file mode 100644 (file)
index 0000000..307789c
--- /dev/null
@@ -0,0 +1,65 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+public class NeutronRouter_Interface {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement (name="subnet_id")\r
+    String subnetUUID;\r
+\r
+    @XmlElement (name="port_id")\r
+    String portUUID;\r
+\r
+    @XmlElement (name="id")\r
+    String id;\r
+\r
+    @XmlElement (name="tenant_id")\r
+    String tenantID;\r
+\r
+    public NeutronRouter_Interface() {\r
+    }\r
+\r
+    public NeutronRouter_Interface(String subnetUUID, String portUUID) {\r
+        this.subnetUUID = subnetUUID;\r
+        this.portUUID = portUUID;\r
+    }\r
+\r
+    public String getSubnetUUID() {\r
+        return subnetUUID;\r
+    }\r
+\r
+    public void setSubnetUUID(String subnetUUID) {\r
+        this.subnetUUID = subnetUUID;\r
+    }\r
+\r
+    public String getPortUUID() {\r
+        return portUUID;\r
+    }\r
+\r
+    public void setPortUUID(String portUUID) {\r
+        this.portUUID = portUUID;\r
+    }\r
+\r
+    public void setID(String id) {\r
+        this.id = id;\r
+    }\r
+\r
+    public void setTenantID(String tenantID) {\r
+        this.tenantID = tenantID;\r
+    }\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_NetworkReference.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_NetworkReference.java
new file mode 100644 (file)
index 0000000..012215c
--- /dev/null
@@ -0,0 +1,36 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+\r
+public class NeutronRouter_NetworkReference {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement(name="network_id")\r
+    String networkID;\r
+\r
+    public NeutronRouter_NetworkReference() {\r
+    }\r
+\r
+    public String getNetworkID() {\r
+        return networkID;\r
+    }\r
+\r
+    public void setNetworkID(String networkID) {\r
+        this.networkID = networkID;\r
+    }\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java
new file mode 100644 (file)
index 0000000..b1414c3
--- /dev/null
@@ -0,0 +1,403 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+import org.apache.commons.net.util.SubnetUtils;\r
+import org.apache.commons.net.util.SubnetUtils.SubnetInfo;\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+\r
+public class NeutronSubnet {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement (name="id")\r
+    String subnetUUID;\r
+\r
+    @XmlElement (name="network_id")\r
+    String networkUUID;\r
+\r
+    @XmlElement (name="name")\r
+    String name;\r
+\r
+    @XmlElement (defaultValue="4", name="ip_version")\r
+    Integer ipVersion;\r
+\r
+    @XmlElement (name="cidr")\r
+    String cidr;\r
+\r
+    @XmlElement (name="gateway_ip")\r
+    String gatewayIP;\r
+\r
+    @XmlElement (name="dns_nameservers")\r
+    List<String> dnsNameservers;\r
+\r
+    @XmlElement (name="allocation_pools")\r
+    List<NeutronSubnet_IPAllocationPool> allocationPools;\r
+\r
+    @XmlElement (name="host_routes")\r
+    List<NeutronSubnet_HostRoute> hostRoutes;\r
+\r
+    @XmlElement (defaultValue="true", name="enable_dhcp")\r
+    Boolean enableDHCP;\r
+\r
+    @XmlElement (name="tenant_id")\r
+    String tenantID;\r
+\r
+    /* stores the OpenStackPorts associated with an instance\r
+     * used to determine if that instance can be deleted.\r
+     */\r
+    List<NeutronPort> myPorts;\r
+\r
+    boolean gatewayIPAssigned;\r
+\r
+    public NeutronSubnet() {\r
+        myPorts = new ArrayList<NeutronPort>();\r
+    }\r
+\r
+    public String getID() { return subnetUUID; }\r
+\r
+    public String getSubnetUUID() {\r
+        return subnetUUID;\r
+    }\r
+\r
+    public void setSubnetUUID(String subnetUUID) {\r
+        this.subnetUUID = subnetUUID;\r
+    }\r
+\r
+    public String getNetworkUUID() {\r
+        return networkUUID;\r
+    }\r
+\r
+    public void setNetworkUUID(String networkUUID) {\r
+        this.networkUUID = networkUUID;\r
+    }\r
+\r
+    public String getName() {\r
+        return name;\r
+    }\r
+\r
+    public void setName(String name) {\r
+        this.name = name;\r
+    }\r
+\r
+    public Integer getIpVersion() {\r
+        return ipVersion;\r
+    }\r
+\r
+    public void setIpVersion(Integer ipVersion) {\r
+        this.ipVersion = ipVersion;\r
+    }\r
+\r
+    public String getCidr() {\r
+        return cidr;\r
+    }\r
+\r
+    public void setCidr(String cidr) {\r
+        this.cidr = cidr;\r
+    }\r
+\r
+    public String getGatewayIP() {\r
+        return gatewayIP;\r
+    }\r
+\r
+    public void setGatewayIP(String gatewayIP) {\r
+        this.gatewayIP = gatewayIP;\r
+    }\r
+\r
+    public List<String> getDnsNameservers() {\r
+        return dnsNameservers;\r
+    }\r
+\r
+    public void setDnsNameservers(List<String> dnsNameservers) {\r
+        this.dnsNameservers = dnsNameservers;\r
+    }\r
+\r
+    public List<NeutronSubnet_IPAllocationPool> getAllocationPools() {\r
+        return allocationPools;\r
+    }\r
+\r
+    public void setAllocationPools(List<NeutronSubnet_IPAllocationPool> allocationPools) {\r
+        this.allocationPools = allocationPools;\r
+    }\r
+\r
+    public List<NeutronSubnet_HostRoute> getHostRoutes() {\r
+        return hostRoutes;\r
+    }\r
+\r
+    public void setHostRoutes(List<NeutronSubnet_HostRoute> hostRoutes) {\r
+        this.hostRoutes = hostRoutes;\r
+    }\r
+\r
+    public boolean isEnableDHCP() {\r
+        if (enableDHCP == null)\r
+            return true;\r
+        return enableDHCP;\r
+    }\r
+\r
+    public Boolean getEnableDHCP() { return enableDHCP; }\r
+\r
+    public void setEnableDHCP(Boolean newValue) {\r
+            this.enableDHCP = newValue;\r
+    }\r
+\r
+    public String getTenantID() {\r
+        return tenantID;\r
+    }\r
+\r
+    public void setTenantID(String tenantID) {\r
+        this.tenantID = tenantID;\r
+    }\r
+\r
+    /**\r
+     * This method copies selected fields from the object and returns them\r
+     * as a new object, suitable for marshaling.\r
+     *\r
+     * @param fields\r
+     *            List of attributes to be extracted\r
+     * @return an OpenStackSubnets object with only the selected fields\r
+     * populated\r
+     */\r
+\r
+    public NeutronSubnet extractFields(List<String> fields) {\r
+        NeutronSubnet ans = new NeutronSubnet();\r
+        Iterator<String> i = fields.iterator();\r
+        while (i.hasNext()) {\r
+            String s = i.next();\r
+            if (s.equals("id"))\r
+                ans.setSubnetUUID(this.getSubnetUUID());\r
+            if (s.equals("network_id"))\r
+                ans.setNetworkUUID(this.getNetworkUUID());\r
+            if (s.equals("name"))\r
+                ans.setName(this.getName());\r
+            if (s.equals("ip_version"))\r
+                ans.setIpVersion(this.getIpVersion());\r
+            if (s.equals("cidr"))\r
+                ans.setCidr(this.getCidr());\r
+            if (s.equals("gateway_ip"))\r
+                ans.setGatewayIP(this.getGatewayIP());\r
+            if (s.equals("dns_nameservers")) {\r
+                List<String> nsList = new ArrayList<String>();\r
+                nsList.addAll(this.getDnsNameservers());\r
+                ans.setDnsNameservers(nsList);\r
+            }\r
+            if (s.equals("allocation_pools")) {\r
+                List<NeutronSubnet_IPAllocationPool> aPools = new ArrayList<NeutronSubnet_IPAllocationPool>();\r
+                aPools.addAll(this.getAllocationPools());\r
+                ans.setAllocationPools(aPools);\r
+            }\r
+            if (s.equals("host_routes")) {\r
+                List<NeutronSubnet_HostRoute> hRoutes = new ArrayList<NeutronSubnet_HostRoute>();\r
+                hRoutes.addAll(this.getHostRoutes());\r
+                ans.setHostRoutes(hRoutes);\r
+            }\r
+            if (s.equals("enable_dhcp"))\r
+                ans.setEnableDHCP(this.getEnableDHCP());\r
+            if (s.equals("tenant_id"))\r
+                ans.setTenantID(this.getTenantID());\r
+        }\r
+        return ans;\r
+    }\r
+\r
+    /* test to see if the cidr address used to define this subnet\r
+     * is a valid network address (an necessary condition when creating\r
+     * a new subnet)\r
+     */\r
+    public boolean isValidCIDR() {\r
+        try {\r
+            SubnetUtils util = new SubnetUtils(cidr);\r
+            SubnetInfo info = util.getInfo();\r
+            if (!info.getNetworkAddress().equals(info.getAddress()))\r
+                return false;\r
+        } catch (Exception e) {\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    /* test to see if the gateway IP specified overlaps with specified\r
+     * allocation pools (an error condition when creating a new subnet\r
+     * or assigning a gateway IP)\r
+     */\r
+    public boolean gatewayIP_Pool_overlap() {\r
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
+        while (i.hasNext()) {\r
+            NeutronSubnet_IPAllocationPool pool = i.next();\r
+            if (pool.contains(gatewayIP))\r
+                return true;\r
+        }\r
+        return false;\r
+    }\r
+\r
+    public void initDefaults() {\r
+        if (enableDHCP == null)\r
+            enableDHCP = true;\r
+        if (ipVersion == null)\r
+            ipVersion = 4;\r
+        gatewayIPAssigned = false;\r
+        dnsNameservers = new ArrayList<String>();\r
+        allocationPools = new ArrayList<NeutronSubnet_IPAllocationPool>();\r
+        hostRoutes = new ArrayList<NeutronSubnet_HostRoute>();\r
+        try {\r
+            SubnetUtils util = new SubnetUtils(cidr);\r
+            SubnetInfo info = util.getInfo();\r
+            if (gatewayIP == null)\r
+                gatewayIP = info.getLowAddress();\r
+            if (allocationPools.size() < 1) {\r
+                NeutronSubnet_IPAllocationPool source =\r
+                    new NeutronSubnet_IPAllocationPool(info.getLowAddress(),\r
+                            info.getHighAddress());\r
+                allocationPools = source.splitPool(gatewayIP);\r
+            }\r
+        } catch (Exception e) {\r
+            ;\r
+        }\r
+    }\r
+\r
+    public List<NeutronPort> getPortsInSubnet() {\r
+        return myPorts;\r
+    }\r
+\r
+    public void addPort(NeutronPort port) {\r
+        myPorts.add(port);\r
+    }\r
+\r
+    public void removePort(NeutronPort port) {\r
+        myPorts.remove(port);\r
+    }\r
+\r
+    /* this method tests to see if the supplied IPv4 address\r
+     * is valid for this subnet or not\r
+     */\r
+    public boolean isValidIP(String ipAddress) {\r
+        try {\r
+            SubnetUtils util = new SubnetUtils(cidr);\r
+            SubnetInfo info = util.getInfo();\r
+            return info.isInRange(ipAddress);\r
+        } catch (Exception e) {\r
+            return false;\r
+        }\r
+    }\r
+\r
+    /* test to see if the supplied IPv4 address is part of one of the\r
+     * available allocation pools or not\r
+     */\r
+    public boolean isIPInUse(String ipAddress) {\r
+        if (ipAddress.equals(gatewayIP) && !gatewayIPAssigned )\r
+            return false;\r
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
+        while (i.hasNext()) {\r
+            NeutronSubnet_IPAllocationPool pool = i.next();\r
+            if (pool.contains(ipAddress))\r
+                return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    /* method to get the lowest available address of the subnet.\r
+     * go through all the allocation pools and keep the lowest of their\r
+     * low addresses.\r
+     */\r
+    public String getLowAddr() {\r
+        String ans = null;\r
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
+        while (i.hasNext()) {\r
+            NeutronSubnet_IPAllocationPool pool = i.next();\r
+            if (ans == null)\r
+                ans = pool.getPoolStart();\r
+            else\r
+                if (NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart()) <\r
+                        NeutronSubnet_IPAllocationPool.convert(ans))\r
+                    ans = pool.getPoolStart();\r
+        }\r
+        return ans;\r
+    }\r
+\r
+    /*\r
+     * allocate the parameter address.  Because this uses an iterator to\r
+     * check the instance's list of allocation pools and we want to modify\r
+     * pools while the iterator is being used, it is necessary to\r
+     * build a new list of allocation pools and replace the list when\r
+     * finished (otherwise a split will cause undefined iterator behavior.\r
+     */\r
+    public void allocateIP(String ipAddress) {\r
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
+        List<NeutronSubnet_IPAllocationPool> newList = new ArrayList<NeutronSubnet_IPAllocationPool>();    // we have to modify a separate list\r
+        while (i.hasNext()) {\r
+            NeutronSubnet_IPAllocationPool pool = i.next();\r
+            if (pool.getPoolEnd().equalsIgnoreCase(ipAddress) &&\r
+                    pool.getPoolStart().equalsIgnoreCase(ipAddress))\r
+                ; // do nothing, i.e. don't add the current pool to the new list\r
+            else\r
+                if (pool.contains(ipAddress)) {\r
+                    List<NeutronSubnet_IPAllocationPool> pools = pool.splitPool(ipAddress);\r
+                    newList.addAll(pools);\r
+                } else\r
+                    newList.add(pool);\r
+        }\r
+        allocationPools = newList;\r
+    }\r
+\r
+    /*\r
+     * release an IP address back to the subnet.  Although an iterator\r
+     * is used, the list is not modified until the iterator is complete, so\r
+     * an extra list is not necessary.\r
+     */\r
+    public void releaseIP(String ipAddress) {\r
+        NeutronSubnet_IPAllocationPool lPool = null;\r
+        NeutronSubnet_IPAllocationPool hPool = null;\r
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
+        long sIP = NeutronSubnet_IPAllocationPool.convert(ipAddress);\r
+        //look for lPool where ipAddr - 1 is high address\r
+        //look for hPool where ipAddr + 1 is low address\r
+        while (i.hasNext()) {\r
+            NeutronSubnet_IPAllocationPool pool = i.next();\r
+            long lIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart());\r
+            long hIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolEnd());\r
+            if (sIP+1 == lIP)\r
+                hPool = pool;\r
+            if (sIP-1 == hIP)\r
+                lPool = pool;\r
+        }\r
+        //if (lPool == NULL and hPool == NULL) create new pool where low = ip = high\r
+        if (lPool == null && hPool == null)\r
+            allocationPools.add(new NeutronSubnet_IPAllocationPool(ipAddress,ipAddress));\r
+        //if (lPool == NULL and hPool != NULL) change low address of hPool to ipAddr\r
+        if (lPool == null && hPool != null)\r
+            hPool.setPoolStart(ipAddress);\r
+        //if (lPool != NULL and hPool == NULL) change high address of lPool to ipAddr\r
+        if (lPool != null && hPool == null)\r
+            lPool.setPoolEnd(ipAddress);\r
+        //if (lPool != NULL and hPool != NULL) remove lPool and hPool and create new pool\r
+        //        where low address = lPool.low address and high address = hPool.high Address\r
+        if (lPool != null && hPool != null) {\r
+            allocationPools.remove(lPool);\r
+            allocationPools.remove(hPool);\r
+            allocationPools.add(new NeutronSubnet_IPAllocationPool(\r
+                    lPool.getPoolStart(), hPool.getPoolEnd()));\r
+        }\r
+    }\r
+\r
+    public void setGatewayIPAllocated() {\r
+        gatewayIPAssigned = true;\r
+    }\r
+\r
+    public void resetGatewayIPAllocated() {\r
+        gatewayIPAssigned = false;\r
+    }\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_HostRoute.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_HostRoute.java
new file mode 100644 (file)
index 0000000..c108429
--- /dev/null
@@ -0,0 +1,29 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+public class NeutronSubnet_HostRoute {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement(name="destination")\r
+    String destination;\r
+\r
+    @XmlElement(name="nexthop")\r
+    String nextHop;\r
+\r
+    public NeutronSubnet_HostRoute() { }\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java
new file mode 100644 (file)
index 0000000..15401b7
--- /dev/null
@@ -0,0 +1,171 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+public class NeutronSubnet_IPAllocationPool {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement(name="start")\r
+    String poolStart;\r
+\r
+    @XmlElement(name="end")\r
+    String poolEnd;\r
+\r
+    public NeutronSubnet_IPAllocationPool() { }\r
+\r
+    public NeutronSubnet_IPAllocationPool(String lowAddress, String highAddress) {\r
+        poolStart = lowAddress;\r
+        poolEnd = highAddress;\r
+    }\r
+\r
+    public String getPoolStart() {\r
+        return poolStart;\r
+    }\r
+\r
+    public void setPoolStart(String poolStart) {\r
+        this.poolStart = poolStart;\r
+    }\r
+\r
+    public String getPoolEnd() {\r
+        return poolEnd;\r
+    }\r
+\r
+    public void setPoolEnd(String poolEnd) {\r
+        this.poolEnd = poolEnd;\r
+    }\r
+\r
+    /**\r
+     * This method determines if this allocation pool contains the\r
+     * input IPv4 address\r
+     *\r
+     * @param inputString\r
+     *            IPv4 address in dotted decimal format\r
+     * @returns a boolean on whether the pool contains the address or not\r
+     */\r
+\r
+    public boolean contains(String inputString) {\r
+        long inputIP = convert(inputString);\r
+        long startIP = convert(poolStart);\r
+        long endIP = convert(poolEnd);\r
+        return (inputIP >= startIP && inputIP <= endIP);\r
+    }\r
+\r
+    /**\r
+     * This static method converts the supplied IPv4 address to a long\r
+     * integer for comparison\r
+     *\r
+     * @param inputString\r
+     *            IPv4 address in dotted decimal format\r
+     * @returns high-endian representation of the IPv4 address as a long\r
+     */\r
+\r
+    static long convert(String inputString) {\r
+        long ans = 0;\r
+        String[] parts = inputString.split("\\.");\r
+        for (String part: parts) {\r
+            ans <<= 8;\r
+            ans |= Integer.parseInt(part);\r
+        }\r
+        return ans;\r
+    }\r
+\r
+    /**\r
+     * This static method converts the supplied high-ending long back\r
+     * into a dotted decimal representation of an IPv4 address\r
+     *\r
+     * @param l\r
+     *            high-endian representation of the IPv4 address as a long\r
+     * @returns IPv4 address in dotted decimal format\r
+     */\r
+    static String longtoIP(long l) {\r
+        int i;\r
+        String[] parts = new String[4];\r
+        for (i=0; i<4; i++) {\r
+            parts[3-i] = String.valueOf(l & 255);\r
+            l >>= 8;\r
+        }\r
+        return join(parts,".");\r
+    }\r
+\r
+    /*\r
+     * helper routine used by longtoIP\r
+     */\r
+    public static String join(String r[],String d)\r
+    {\r
+        if (r.length == 0) return "";\r
+        StringBuilder sb = new StringBuilder();\r
+        int i;\r
+        for(i=0;i<r.length-1;i++)\r
+            sb.append(r[i]+d);\r
+        return sb.toString()+r[i];\r
+    }\r
+\r
+    /*\r
+     * This method splits the current instance by removing the supplied\r
+     * parameter.\r
+     *\r
+     * If the parameter is either the low or high address,\r
+     * then that member is adjusted and a list containing just this instance\r
+     * is returned.\r
+     *\r
+     * If the parameter is in the middle of the pool, then\r
+     * create two new instances, one ranging from low to parameter-1\r
+     * the other ranging from parameter+1 to high\r
+     */\r
+    public List<NeutronSubnet_IPAllocationPool> splitPool(String ipAddress) {\r
+        List<NeutronSubnet_IPAllocationPool> ans = new ArrayList<NeutronSubnet_IPAllocationPool>();\r
+        long gIP = NeutronSubnet_IPAllocationPool.convert(ipAddress);\r
+        long sIP = NeutronSubnet_IPAllocationPool.convert(poolStart);\r
+        long eIP = NeutronSubnet_IPAllocationPool.convert(poolEnd);\r
+        long i;\r
+        NeutronSubnet_IPAllocationPool p = new NeutronSubnet_IPAllocationPool();\r
+        boolean poolStarted = false;\r
+        for (i=sIP; i<=eIP; i++) {\r
+            if (i == sIP) {\r
+                if (i != gIP) {\r
+                    p.setPoolStart(poolStart);\r
+                    poolStarted = true;\r
+                }\r
+            }\r
+            if (i == eIP) {\r
+                if (i != gIP) {\r
+                    p.setPoolEnd(poolEnd);\r
+                } else {\r
+                    p.setPoolEnd(NeutronSubnet_IPAllocationPool.longtoIP(i-1));\r
+                }\r
+                ans.add(p);\r
+            }\r
+            if (i != sIP && i != eIP) {\r
+                if (i != gIP) {\r
+                    if (!poolStarted) {\r
+                        p.setPoolStart(NeutronSubnet_IPAllocationPool.longtoIP(i));\r
+                        poolStarted = true;\r
+                    }\r
+                } else {\r
+                    p.setPoolEnd(NeutronSubnet_IPAllocationPool.longtoIP(i-1));\r
+                    poolStarted = false;\r
+                    ans.add(p);\r
+                    p = new NeutronSubnet_IPAllocationPool();\r
+                }\r
+            }\r
+        }\r
+        return ans;\r
+    }\r
+}\r
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java
new file mode 100644 (file)
index 0000000..7309479
--- /dev/null
@@ -0,0 +1,49 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron;\r
+\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+public class Neutron_IPs {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement(name="ip_address")\r
+    String ipAddress;\r
+\r
+    @XmlElement(name="subnet_id")\r
+    String subnetUUID;\r
+\r
+    public Neutron_IPs() { }\r
+\r
+    public Neutron_IPs(String uuid) {\r
+        this.subnetUUID = uuid;\r
+    }\r
+\r
+    public String getIpAddress() {\r
+        return ipAddress;\r
+    }\r
+\r
+    public void setIpAddress(String ipAddress) {\r
+        this.ipAddress = ipAddress;\r
+    }\r
+\r
+    public String getSubnetUUID() {\r
+        return subnetUUID;\r
+    }\r
+\r
+    public void setSubnetUUID(String subnetUUID) {\r
+        this.subnetUUID = subnetUUID;\r
+    }\r
+}\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/enunciate.xml b/opendaylight/northbound/networkconfiguration/neutron/enunciate.xml
new file mode 100644 (file)
index 0000000..b9e4f7e
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>\r
+<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">\r
+\r
+  <services>\r
+    <rest defaultRestSubcontext="/controller/nb/v2/neutron"/>\r
+  </services>\r
+\r
+  <modules>\r
+    <docs docsDir="rest" title="OpenStack Neutron REST API" includeExampleXml="false" includeExampleJson="true"/>\r
+  </modules>\r
+</enunciate>\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/pom.xml b/opendaylight/northbound/networkconfiguration/neutron/pom.xml
new file mode 100644 (file)
index 0000000..6a143d9
--- /dev/null
@@ -0,0 +1,120 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <parent>\r
+        <groupId>org.opendaylight.controller</groupId>\r
+        <artifactId>commons.opendaylight</artifactId>\r
+        <version>1.4.0-SNAPSHOT</version>\r
+        <relativePath>../../../commons/opendaylight</relativePath>\r
+    </parent>\r
+    <properties>\r
+        <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>\r
+        <enunciate.version>1.26.2</enunciate.version>\r
+    </properties>\r
+\r
+    <distributionManagement>\r
+        <!-- OpenDayLight Released artifact -->\r
+        <repository>\r
+            <id>opendaylight-release</id>\r
+            <url>${nexusproxy}/repositories/opendaylight.release/</url>\r
+        </repository>\r
+        <!-- OpenDayLight Snapshot artifact -->\r
+        <snapshotRepository>\r
+            <id>opendaylight-snapshot</id>\r
+            <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>\r
+        </snapshotRepository>\r
+        <!-- Site deployment -->\r
+        <site>\r
+            <id>website</id>\r
+            <url>${sitedeploy}</url>\r
+        </site>\r
+    </distributionManagement>\r
+    <groupId>org.opendaylight.controller</groupId>\r
+    <artifactId>networkconfig.neutron.northbound</artifactId>\r
+    <version>0.4.0-SNAPSHOT</version>\r
+    <packaging>bundle</packaging>\r
+\r
+    <build>\r
+        <plugins>\r
+            <plugin>\r
+                <groupId>org.codehaus.enunciate</groupId>\r
+                <artifactId>maven-enunciate-plugin</artifactId>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.apache.felix</groupId>\r
+                <artifactId>maven-bundle-plugin</artifactId>\r
+                <version>2.3.6</version>\r
+                <extensions>true</extensions>\r
+                <configuration>\r
+                    <instructions>\r
+                        <Import-Package>\r
+                            org.opendaylight.controller.sal.utils,\r
+                            org.opendaylight.controller.containermanager,\r
+                            org.opendaylight.controller.northbound.commons,\r
+                            org.opendaylight.controller.northbound.commons.exception,\r
+                            org.opendaylight.controller.northbound.commons.utils,\r
+                            org.opendaylight.controller.networkconfig.neutron,\r
+                            org.eclipse.persistence.jaxb.rs,\r
+                            com.sun.jersey.spi.container.servlet,\r
+                            javax.ws.rs,\r
+                            javax.ws.rs.core,\r
+                            javax.xml.bind.annotation,\r
+                            javax.xml.bind,\r
+                            org.slf4j,\r
+                            !org.codehaus.enunciate.jaxrs\r
+                        </Import-Package>\r
+                        <Web-ContextPath>/controller/nb/v2/neutron</Web-ContextPath>\r
+                    </instructions>\r
+                    <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>\r
+                </configuration>\r
+            </plugin>\r
+        </plugins>\r
+    </build>\r
+    <dependencies>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller.thirdparty</groupId>\r
+            <artifactId>com.sun.jersey.jersey-servlet</artifactId>\r
+            <version>1.17-SNAPSHOT</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller</groupId>\r
+            <artifactId>containermanager</artifactId>\r
+            <version>0.4.0-SNAPSHOT</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller</groupId>\r
+            <artifactId>sal</artifactId>\r
+            <version>0.5.0-SNAPSHOT</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller</groupId>\r
+            <artifactId>commons.northbound</artifactId>\r
+            <version>0.4.0-SNAPSHOT</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller</groupId>\r
+            <artifactId>networkconfig.neutron</artifactId>\r
+            <version>0.4.0-SNAPSHOT</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.codehaus.enunciate</groupId>\r
+            <artifactId>enunciate-core-annotations</artifactId>\r
+            <version>${enunciate.version}</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.eclipse.persistence</groupId>\r
+            <artifactId>org.eclipse.persistence.moxy</artifactId>\r
+            <version>2.5.0</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.eclipse.persistence</groupId>\r
+            <artifactId>org.eclipse.persistence.core</artifactId>\r
+            <version>2.5.0</version>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.eclipse.persistence</groupId>\r
+            <artifactId>org.eclipse.persistence.antlr</artifactId>\r
+            <version>2.5.0</version>\r
+        </dependency>\r
+    </dependencies>\r
+</project>
\ No newline at end of file
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPRequest.java
new file mode 100644 (file)
index 0000000..ca1389c
--- /dev/null
@@ -0,0 +1,52 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.northbound;\r
+\r
+import java.util.List;\r
+\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+public class NeutronFloatingIPRequest {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement(name="floatingip")\r
+    NeutronFloatingIP singletonFloatingIP;\r
+\r
+    @XmlElement(name="floatingips")\r
+    List<NeutronFloatingIP> bulkRequest;\r
+\r
+    NeutronFloatingIPRequest() {\r
+    }\r
+\r
+    NeutronFloatingIPRequest(List<NeutronFloatingIP> bulk) {\r
+        bulkRequest = bulk;\r
+        singletonFloatingIP = null;\r
+    }\r
+\r
+    NeutronFloatingIPRequest(NeutronFloatingIP singleton) {\r
+        bulkRequest = null;\r
+        singletonFloatingIP = singleton;\r
+    }\r
+\r
+    public NeutronFloatingIP getSingleton() {\r
+        return singletonFloatingIP;\r
+    }\r
+\r
+    public boolean isSingleton() {\r
+        return (singletonFloatingIP != null);\r
+    }\r
+}\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPsNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPsNorthbound.java
new file mode 100644 (file)
index 0000000..14eaedd
--- /dev/null
@@ -0,0 +1,427 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.northbound;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import javax.ws.rs.Consumes;\r
+import javax.ws.rs.DELETE;\r
+import javax.ws.rs.GET;\r
+import javax.ws.rs.POST;\r
+import javax.ws.rs.PUT;\r
+import javax.ws.rs.Path;\r
+import javax.ws.rs.PathParam;\r
+import javax.ws.rs.Produces;\r
+import javax.ws.rs.QueryParam;\r
+import javax.ws.rs.core.MediaType;\r
+import javax.ws.rs.core.Response;\r
+\r
+import org.codehaus.enunciate.jaxrs.ResponseCode;\r
+import org.codehaus.enunciate.jaxrs.StatusCodes;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPAware;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortAware;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
+import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;\r
+import org.opendaylight.controller.northbound.commons.RestMessages;\r
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
+import org.opendaylight.controller.sal.utils.ServiceHelper;\r
+\r
+/**\r
+ * Open DOVE Northbound REST APIs.<br>\r
+ * This class provides REST APIs for managing the open DOVE\r
+ *\r
+ * <br>\r
+ * <br>\r
+ * Authentication scheme : <b>HTTP Basic</b><br>\r
+ * Authentication realm : <b>opendaylight</b><br>\r
+ * Transport : <b>HTTP and HTTPS</b><br>\r
+ * <br>\r
+ * HTTPS Authentication is disabled by default. Administrator can enable it in\r
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
+ * trusted authority.<br>\r
+ * More info :\r
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
+ *\r
+ */\r
+\r
+@Path("/floatingips")\r
+public class NeutronFloatingIPsNorthbound {\r
+\r
+    private NeutronFloatingIP extractFields(NeutronFloatingIP o, List<String> fields) {\r
+        return o.extractFields(fields);\r
+    }\r
+\r
+    /**\r
+     * Returns a list of all FloatingIPs */\r
+\r
+    @GET\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response listFloatingIPs(\r
+            // return fields\r
+            @QueryParam("fields") List<String> fields,\r
+            // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
+            @QueryParam("id") String queryID,\r
+            @QueryParam("floating_network_id") String queryFloatingNetworkId,\r
+            @QueryParam("port_id") String queryPortId,\r
+            @QueryParam("fixed_ip_address") String queryFixedIPAddress,\r
+            @QueryParam("floating_ip_address") String queryFloatingIPAddress,\r
+            @QueryParam("tenant_id") String queryTenantID,\r
+            // pagination\r
+            @QueryParam("limit") String limit,\r
+            @QueryParam("marker") String marker,\r
+            @QueryParam("page_reverse") String pageReverse\r
+            // sorting not supported\r
+            ) {\r
+        INeutronFloatingIPCRUD floatingIPInterface = NeutronNBInterfaces.getIfNBFloatingIPCRUD("default",this);\r
+        if (floatingIPInterface == null) {\r
+            throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        List<NeutronFloatingIP> allFloatingIPs = floatingIPInterface.getAllFloatingIPs();\r
+        List<NeutronFloatingIP> ans = new ArrayList<NeutronFloatingIP>();\r
+        Iterator<NeutronFloatingIP> i = allFloatingIPs.iterator();\r
+        while (i.hasNext()) {\r
+            NeutronFloatingIP oSS = i.next();\r
+            //match filters: TODO provider extension and router extension\r
+            if ((queryID == null || queryID.equals(oSS.getID())) &&\r
+                    (queryFloatingNetworkId == null || queryFloatingNetworkId.equals(oSS.getFloatingNetworkUUID())) &&\r
+                    (queryPortId == null || queryPortId.equals(oSS.getPortUUID())) &&\r
+                    (queryFixedIPAddress == null || queryFixedIPAddress.equals(oSS.getFixedIPAddress())) &&\r
+                    (queryFloatingIPAddress == null || queryFloatingIPAddress.equals(oSS.getFloatingIPAddress())) &&\r
+                    (queryTenantID == null || queryTenantID.equals(oSS.getTenantUUID()))) {\r
+                if (fields.size() > 0)\r
+                    ans.add(extractFields(oSS,fields));\r
+                else\r
+                    ans.add(oSS);\r
+            }\r
+        }\r
+        //TODO: apply pagination to results\r
+        return Response.status(200).entity(\r
+                new NeutronFloatingIPRequest(ans)).build();\r
+    }\r
+\r
+    /**\r
+     * Returns a specific FloatingIP */\r
+\r
+    @Path("{floatingipUUID}")\r
+    @GET\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response showFloatingIP(\r
+            @PathParam("floatingipUUID") String floatingipUUID,\r
+            // return fields\r
+            @QueryParam("fields") List<String> fields ) {\r
+        INeutronFloatingIPCRUD floatingIPInterface = NeutronNBInterfaces.getIfNBFloatingIPCRUD("default",this);\r
+        if (floatingIPInterface == null) {\r
+            throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        if (!floatingIPInterface.floatingIPExists(floatingipUUID))\r
+            return Response.status(404).build();\r
+        if (fields.size() > 0) {\r
+            NeutronFloatingIP ans = floatingIPInterface.getFloatingIP(floatingipUUID);\r
+            return Response.status(200).entity(\r
+                    new NeutronFloatingIPRequest(extractFields(ans, fields))).build();\r
+        } else\r
+            return Response.status(200).entity(\r
+                    new NeutronFloatingIPRequest(floatingIPInterface.getFloatingIP(floatingipUUID))).build();\r
+\r
+    }\r
+\r
+    /**\r
+     * Creates new FloatingIPs */\r
+\r
+    @POST\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    @Consumes({ MediaType.APPLICATION_JSON })\r
+    @StatusCodes({\r
+        @ResponseCode(code = 201, condition = "Created"),\r
+        @ResponseCode(code = 400, condition = "Bad Request"),\r
+        @ResponseCode(code = 401, condition = "Unauthorized"),\r
+        @ResponseCode(code = 409, condition = "Conflict"),\r
+        @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response createFloatingIPs(final NeutronFloatingIPRequest input) {\r
+        INeutronFloatingIPCRUD floatingIPInterface = NeutronNBInterfaces.getIfNBFloatingIPCRUD("default",this);\r
+        if (floatingIPInterface == null) {\r
+            throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronNetworkCRUD networkInterface = NeutronNBInterfaces.getIfNBNetworkCRUD("default", this);\r
+        if (networkInterface == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronSubnetCRUD subnetInterface = NeutronNBInterfaces.getIfNBSubnetCRUD("default", this);\r
+        if (subnetInterface == null) {\r
+            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronPortCRUD portInterface = NeutronNBInterfaces.getIfNBPortCRUD("default", this);\r
+        if (portInterface == null) {\r
+            throw new ServiceUnavailableException("Port CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        if (input.isSingleton()) {\r
+            NeutronFloatingIP singleton = input.getSingleton();\r
+            // check existence of id in cache and return badrequest if exists\r
+            if (floatingIPInterface.floatingIPExists(singleton.getID()))\r
+                return Response.status(400).build();\r
+            // check if the external network is specified, exists, and is an external network\r
+            String externalNetworkUUID = singleton.getFloatingNetworkUUID();\r
+            if (externalNetworkUUID == null)\r
+                return Response.status(400).build();\r
+            if (!networkInterface.networkExists(externalNetworkUUID))\r
+                return Response.status(400).build();\r
+            NeutronNetwork externNetwork = networkInterface.getNetwork(externalNetworkUUID);\r
+            if (!externNetwork.isRouterExternal())\r
+                return Response.status(400).build();\r
+            // if floating IP is specified, make sure it can come from the network\r
+            String floatingIP = singleton.getFloatingIPAddress();\r
+            if (floatingIP != null) {\r
+                if (externNetwork.getSubnets().size() > 1)\r
+                    return Response.status(400).build();\r
+                NeutronSubnet externSubnet = subnetInterface.getSubnet(externNetwork.getSubnets().get(0));\r
+                if (!externSubnet.isValidIP(floatingIP))\r
+                    return Response.status(400).build();\r
+                if (externSubnet.isIPInUse(floatingIP))\r
+                    return Response.status(409).build();\r
+            }\r
+            // if port_id is specified, then check that the port exists and has at least one IP\r
+            String port_id = singleton.getPortUUID();\r
+            if (port_id != null) {\r
+                String fixedIP = null;        // used for the fixedIP calculation\r
+                if (!portInterface.portExists(port_id))\r
+                    return Response.status(404).build();\r
+                NeutronPort port = portInterface.getPort(port_id);\r
+                if (port.getFixedIPs().size() < 1)\r
+                    return Response.status(400).build();\r
+                // if there is more than one fixed IP then check for fixed_ip_address\r
+                // and that it is in the list of port addresses\r
+                if (port.getFixedIPs().size() > 1) {\r
+                    fixedIP = singleton.getFixedIPAddress();\r
+                    if (fixedIP == null)\r
+                        return Response.status(400).build();\r
+                    Iterator<Neutron_IPs> i = port.getFixedIPs().iterator();\r
+                    boolean validFixedIP = false;\r
+                    while (i.hasNext() && !validFixedIP) {\r
+                        Neutron_IPs ip = i.next();\r
+                        if (ip.getIpAddress().equals(fixedIP))\r
+                            validFixedIP = true;\r
+                    }\r
+                    if (!validFixedIP)\r
+                        return Response.status(400).build();\r
+                } else {\r
+                    fixedIP = port.getFixedIPs().get(0).getIpAddress();\r
+                    if (singleton.getFixedIPAddress() != null && !fixedIP.equalsIgnoreCase(singleton.getFixedIPAddress()))\r
+                        return Response.status(400).build();\r
+                }\r
+                //lastly check that this fixed IP address isn't already used\r
+                if (port.isBoundToFloatingIP(fixedIP))\r
+                    return Response.status(409).build();\r
+                singleton.setFixedIPAddress(fixedIP);\r
+            }\r
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);\r
+            if (instances != null) {\r
+                for (Object instance : instances) {\r
+                    INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
+                    int status = service.canCreateFloatingIP(singleton);\r
+                    if (status < 200 || status > 299)\r
+                        return Response.status(status).build();\r
+                }\r
+            }\r
+            floatingIPInterface.addFloatingIP(singleton);\r
+            if (instances != null) {\r
+                for (Object instance : instances) {\r
+                    INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
+                    service.neutronFloatingIPCreated(singleton);\r
+                }\r
+            }\r
+        } else {\r
+            return Response.status(400).build();\r
+        }\r
+        return Response.status(201).entity(input).build();\r
+    }\r
+\r
+    /**\r
+     * Updates a FloatingIP */\r
+\r
+    @Path("{floatingipUUID}")\r
+    @PUT\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    @Consumes({ MediaType.APPLICATION_JSON })\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 400, condition = "Bad Request"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 409, condition = "Conflict"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response updateFloatingIP(\r
+            @PathParam("floatingipUUID") String floatingipUUID,\r
+            NeutronFloatingIPRequest input\r
+            ) {\r
+        INeutronFloatingIPCRUD floatingIPInterface = NeutronNBInterfaces.getIfNBFloatingIPCRUD("default",this);\r
+        if (floatingIPInterface == null) {\r
+            throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronNetworkCRUD networkInterface = NeutronNBInterfaces.getIfNBNetworkCRUD("default", this);\r
+        if (networkInterface == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronSubnetCRUD subnetInterface = NeutronNBInterfaces.getIfNBSubnetCRUD("default", this);\r
+        if (subnetInterface == null) {\r
+            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronPortCRUD portInterface = NeutronNBInterfaces.getIfNBPortCRUD("default", this);\r
+        if (portInterface == null) {\r
+            throw new ServiceUnavailableException("Port CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        if (!floatingIPInterface.floatingIPExists(floatingipUUID))\r
+            return Response.status(404).build();\r
+\r
+        NeutronFloatingIP sourceFloatingIP = floatingIPInterface.getFloatingIP(floatingipUUID);\r
+        if (!input.isSingleton())\r
+            return Response.status(400).build();\r
+        NeutronFloatingIP singleton = input.getSingleton();\r
+        if (singleton.getID() != null)\r
+            return Response.status(400).build();\r
+\r
+        NeutronNetwork externNetwork = networkInterface.getNetwork(\r
+                sourceFloatingIP.getFloatingNetworkUUID());\r
+\r
+        // if floating IP is specified, make sure it can come from the network\r
+        String floatingIP = singleton.getFloatingIPAddress();\r
+        if (floatingIP != null) {\r
+            if (externNetwork.getSubnets().size() > 1)\r
+                return Response.status(400).build();\r
+            NeutronSubnet externSubnet = subnetInterface.getSubnet(externNetwork.getSubnets().get(0));\r
+            if (!externSubnet.isValidIP(floatingIP))\r
+                return Response.status(400).build();\r
+            if (externSubnet.isIPInUse(floatingIP))\r
+                return Response.status(409).build();\r
+        }\r
+\r
+        // if port_id is specified, then check that the port exists and has at least one IP\r
+        String port_id = singleton.getPortUUID();\r
+        if (port_id != null) {\r
+            String fixedIP = null;        // used for the fixedIP calculation\r
+            if (!portInterface.portExists(port_id))\r
+                return Response.status(404).build();\r
+            NeutronPort port = portInterface.getPort(port_id);\r
+            if (port.getFixedIPs().size() < 1)\r
+                return Response.status(400).build();\r
+            // if there is more than one fixed IP then check for fixed_ip_address\r
+            // and that it is in the list of port addresses\r
+            if (port.getFixedIPs().size() > 1) {\r
+                fixedIP = singleton.getFixedIPAddress();\r
+                if (fixedIP == null)\r
+                    return Response.status(400).build();\r
+                Iterator<Neutron_IPs> i = port.getFixedIPs().iterator();\r
+                boolean validFixedIP = false;\r
+                while (i.hasNext() && !validFixedIP) {\r
+                    Neutron_IPs ip = i.next();\r
+                    if (ip.getIpAddress().equals(fixedIP))\r
+                        validFixedIP = true;\r
+                }\r
+                if (!validFixedIP)\r
+                    return Response.status(400).build();\r
+            } else {\r
+                fixedIP = port.getFixedIPs().get(0).getIpAddress();\r
+                if (singleton.getFixedIPAddress() != null &&\r
+                        !fixedIP.equalsIgnoreCase(singleton.getFixedIPAddress()))\r
+                    return Response.status(400).build();\r
+            }\r
+            //lastly check that this fixed IP address isn't already used\r
+            if (port.isBoundToFloatingIP(fixedIP))\r
+                return Response.status(409).build();\r
+            singleton.setFixedIPAddress(fixedIP);\r
+        }\r
+        NeutronFloatingIP target = floatingIPInterface.getFloatingIP(floatingipUUID);\r
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
+                int status = service.canUpdateFloatingIP(singleton, target);\r
+                if (status < 200 || status > 299)\r
+                    return Response.status(status).build();\r
+            }\r
+        }\r
+        floatingIPInterface.updateFloatingIP(floatingipUUID, singleton);\r
+        target = floatingIPInterface.getFloatingIP(floatingipUUID);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
+                service.neutronFloatingIPUpdated(target);\r
+            }\r
+        }\r
+        return Response.status(200).entity(\r
+                new NeutronFloatingIPRequest(target)).build();\r
+\r
+    }\r
+\r
+    /**\r
+     * Deletes a FloatingIP */\r
+\r
+    @Path("{floatingipUUID}")\r
+    @DELETE\r
+    @StatusCodes({\r
+            @ResponseCode(code = 204, condition = "No Content"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response deleteFloatingIP(\r
+            @PathParam("floatingipUUID") String floatingipUUID) {\r
+        INeutronFloatingIPCRUD floatingIPInterface = NeutronNBInterfaces.getIfNBFloatingIPCRUD("default",this);\r
+        if (floatingIPInterface == null) {\r
+            throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        if (!floatingIPInterface.floatingIPExists(floatingipUUID))\r
+            return Response.status(404).build();\r
+        // TODO: need to undo port association if it exists\r
+        NeutronFloatingIP singleton = floatingIPInterface.getFloatingIP(floatingipUUID);\r
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
+                int status = service.canDeleteFloatingIP(singleton);\r
+                if (status < 200 || status > 299)\r
+                    return Response.status(status).build();\r
+            }\r
+        }\r
+        floatingIPInterface.removeFloatingIP(floatingipUUID);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
+                service.neutronFloatingIPDeleted(singleton);\r
+            }\r
+        }\r
+        return Response.status(204).build();\r
+    }\r
+}\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNBInterfaces.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNBInterfaces.java
new file mode 100644 (file)
index 0000000..730fe2c
--- /dev/null
@@ -0,0 +1,193 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.northbound;\r
+\r
+import java.util.List;\r
+\r
+import org.opendaylight.controller.containermanager.IContainerManager;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
+import org.opendaylight.controller.northbound.commons.RestMessages;\r
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;\r
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
+import org.opendaylight.controller.sal.utils.ServiceHelper;\r
+\r
+public class NeutronNBInterfaces {\r
+\r
+    // return a class that implements the IfNBNetworkCRUD interface\r
+    static INeutronNetworkCRUD getIfNBNetworkCRUD(String containerName, Object o) {\r
+ /*       IContainerManager containerManager = (IContainerManager) ServiceHelper\r
+                .getGlobalInstance(IContainerManager.class, o);\r
+        if (containerManager == null) {\r
+            throw new ServiceUnavailableException("Container "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        boolean found = false;\r
+        List<String> containerNames = containerManager.getContainerNames();\r
+        for (String cName : containerNames) {\r
+            if (cName.trim().equalsIgnoreCase(containerName.trim())) {\r
+                found = true;\r
+            }\r
+        }\r
+\r
+        if (found == false) {\r
+            throw new ResourceNotFoundException(containerName + " "\r
+                    + RestMessages.NOCONTAINER.toString());\r
+        }\r
+\r
+        IfNBNetworkCRUD answer = (IfNBNetworkCRUD) ServiceHelper.getInstance(\r
+                IfNBNetworkCRUD.class, containerName, o); */\r
+\r
+        INeutronNetworkCRUD answer = NeutronCRUDInterfaces.getINeutronNetworkCRUD(o);\r
+\r
+        if (answer == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Service "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        return answer;\r
+    }\r
+\r
+    // return a class that implements the IfNBSubnetCRUD interface\r
+    static INeutronSubnetCRUD getIfNBSubnetCRUD(String containerName, Object o) {\r
+        IContainerManager containerManager = (IContainerManager) ServiceHelper\r
+                .getGlobalInstance(IContainerManager.class, o);\r
+        if (containerManager == null) {\r
+            throw new ServiceUnavailableException("Container "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        boolean found = false;\r
+        List<String> containerNames = containerManager.getContainerNames();\r
+        for (String cName : containerNames) {\r
+            if (cName.trim().equalsIgnoreCase(containerName.trim())) {\r
+                found = true;\r
+            }\r
+        }\r
+\r
+        if (found == false) {\r
+            throw new ResourceNotFoundException(containerName + " "\r
+                    + RestMessages.NOCONTAINER.toString());\r
+        }\r
+\r
+        INeutronSubnetCRUD answer = (INeutronSubnetCRUD) ServiceHelper.getInstance(\r
+                INeutronSubnetCRUD.class, containerName, o);\r
+\r
+        if (answer == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Service "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        return answer;\r
+    }\r
+\r
+    // return a class that implements the IfNBPortCRUD interface\r
+    static INeutronPortCRUD getIfNBPortCRUD(String containerName, Object o) {\r
+        IContainerManager containerManager = (IContainerManager) ServiceHelper\r
+                .getGlobalInstance(IContainerManager.class, o);\r
+        if (containerManager == null) {\r
+            throw new ServiceUnavailableException("Container "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        boolean found = false;\r
+        List<String> containerNames = containerManager.getContainerNames();\r
+        for (String cName : containerNames) {\r
+            if (cName.trim().equalsIgnoreCase(containerName.trim())) {\r
+                found = true;\r
+            }\r
+        }\r
+\r
+        if (found == false) {\r
+            throw new ResourceNotFoundException(containerName + " "\r
+                    + RestMessages.NOCONTAINER.toString());\r
+        }\r
+\r
+        INeutronPortCRUD answer = (INeutronPortCRUD) ServiceHelper.getInstance(\r
+                INeutronPortCRUD.class, containerName, o);\r
+\r
+        if (answer == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Service "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        return answer;\r
+    }\r
+\r
+    // return a class that implements the IfNBRouterCRUD interface\r
+    static INeutronRouterCRUD getIfNBRouterCRUD(String containerName, Object o) {\r
+        IContainerManager containerManager = (IContainerManager) ServiceHelper\r
+                .getGlobalInstance(IContainerManager.class, o);\r
+        if (containerManager == null) {\r
+            throw new ServiceUnavailableException("Container "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        boolean found = false;\r
+        List<String> containerNames = containerManager.getContainerNames();\r
+        for (String cName : containerNames) {\r
+            if (cName.trim().equalsIgnoreCase(containerName.trim())) {\r
+                found = true;\r
+            }\r
+        }\r
+\r
+        if (found == false) {\r
+            throw new ResourceNotFoundException(containerName + " "\r
+                    + RestMessages.NOCONTAINER.toString());\r
+        }\r
+\r
+        INeutronRouterCRUD answer = (INeutronRouterCRUD) ServiceHelper.getInstance(\r
+                INeutronRouterCRUD.class, containerName, o);\r
+\r
+        if (answer == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Service "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        return answer;\r
+    }\r
+\r
+    // return a class that implements the IfNBFloatingIPCRUD interface\r
+    static INeutronFloatingIPCRUD getIfNBFloatingIPCRUD(String containerName, Object o) {\r
+        IContainerManager containerManager = (IContainerManager) ServiceHelper\r
+                .getGlobalInstance(IContainerManager.class, o);\r
+        if (containerManager == null) {\r
+            throw new ServiceUnavailableException("Container "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        boolean found = false;\r
+        List<String> containerNames = containerManager.getContainerNames();\r
+        for (String cName : containerNames) {\r
+            if (cName.trim().equalsIgnoreCase(containerName.trim())) {\r
+                found = true;\r
+            }\r
+        }\r
+\r
+        if (found == false) {\r
+            throw new ResourceNotFoundException(containerName + " "\r
+                    + RestMessages.NOCONTAINER.toString());\r
+        }\r
+\r
+        INeutronFloatingIPCRUD answer = (INeutronFloatingIPCRUD) ServiceHelper.getInstance(\r
+                INeutronFloatingIPCRUD.class, containerName, o);\r
+\r
+        if (answer == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Service "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        return answer;\r
+    }\r
+}\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworkRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworkRequest.java
new file mode 100644 (file)
index 0000000..9d44938
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.northbound;\r
+\r
+import java.util.List;\r
+\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+public class NeutronNetworkRequest {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement(name="network")\r
+    NeutronNetwork singletonNetwork;\r
+\r
+    @XmlElement(name="networks")\r
+    List<NeutronNetwork> bulkRequest;\r
+\r
+    NeutronNetworkRequest() {\r
+    }\r
+\r
+    NeutronNetworkRequest(List<NeutronNetwork> bulk) {\r
+        bulkRequest = bulk;\r
+        singletonNetwork = null;\r
+    }\r
+\r
+    NeutronNetworkRequest(NeutronNetwork net) {\r
+        singletonNetwork = net;\r
+    }\r
+\r
+    public NeutronNetwork getSingleton() {\r
+        return singletonNetwork;\r
+    }\r
+\r
+    public boolean isSingleton() {\r
+        return (singletonNetwork != null);\r
+    }\r
+\r
+    public List<NeutronNetwork> getBulk() {\r
+        return bulkRequest;\r
+    }\r
+}\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworksNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworksNorthbound.java
new file mode 100644 (file)
index 0000000..2505da6
--- /dev/null
@@ -0,0 +1,355 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.northbound;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import javax.ws.rs.Consumes;\r
+import javax.ws.rs.DELETE;\r
+import javax.ws.rs.GET;\r
+import javax.ws.rs.POST;\r
+import javax.ws.rs.PUT;\r
+import javax.ws.rs.Path;\r
+import javax.ws.rs.PathParam;\r
+import javax.ws.rs.Produces;\r
+import javax.ws.rs.QueryParam;\r
+import javax.ws.rs.core.MediaType;\r
+import javax.ws.rs.core.Response;\r
+\r
+import org.codehaus.enunciate.jaxrs.ResponseCode;\r
+import org.codehaus.enunciate.jaxrs.StatusCodes;\r
+import org.codehaus.enunciate.jaxrs.TypeHint;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkAware;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
+import org.opendaylight.controller.northbound.commons.RestMessages;\r
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
+import org.opendaylight.controller.sal.utils.ServiceHelper;\r
+\r
+/**\r
+ * Open DOVE Northbound REST APIs for Network.<br>\r
+ * This class provides REST APIs for managing open DOVE internals related to Networks\r
+ *\r
+ * <br>\r
+ * <br>\r
+ * Authentication scheme : <b>HTTP Basic</b><br>\r
+ * Authentication realm : <b>opendaylight</b><br>\r
+ * Transport : <b>HTTP and HTTPS</b><br>\r
+ * <br>\r
+ * HTTPS Authentication is disabled by default. Administrator can enable it in\r
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
+ * trusted authority.<br>\r
+ * More info :\r
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
+ *\r
+ */\r
+\r
+@Path("/networks")\r
+public class NeutronNetworksNorthbound {\r
+\r
+    private NeutronNetwork extractFields(NeutronNetwork o, List<String> fields) {\r
+        return o.extractFields(fields);\r
+    }\r
+\r
+    /**\r
+     * Returns a list of all Networks */\r
+\r
+    @GET\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackNetworks.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized") })\r
+    public Response listNetworks(\r
+            // return fields\r
+            @QueryParam("fields") List<String> fields,\r
+            // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
+            @QueryParam("id") String queryID,\r
+            @QueryParam("name") String queryName,\r
+            @QueryParam("admin_state_up") String queryAdminStateUp,\r
+            @QueryParam("status") String queryStatus,\r
+            @QueryParam("shared") String queryShared,\r
+            @QueryParam("tenant_id") String queryTenantID,\r
+            @QueryParam("router_external") String queryRouterExternal,\r
+            @QueryParam("provider_network_type") String queryProviderNetworkType,\r
+            @QueryParam("provider_physical_network") String queryProviderPhysicalNetwork,\r
+            @QueryParam("provider_segmentation_id") String queryProviderSegmentationID,\r
+            // pagination\r
+            @QueryParam("limit") String limit,\r
+            @QueryParam("marker") String marker,\r
+            @QueryParam("page_reverse") String pageReverse\r
+            // sorting not supported\r
+        ) {\r
+        INeutronNetworkCRUD networkInterface = NeutronNBInterfaces.getIfNBNetworkCRUD("default", this);\r
+        if (networkInterface == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        List<NeutronNetwork> allNetworks = networkInterface.getAllNetworks();\r
+        List<NeutronNetwork> ans = new ArrayList<NeutronNetwork>();\r
+        Iterator<NeutronNetwork> i = allNetworks.iterator();\r
+        while (i.hasNext()) {\r
+            NeutronNetwork oSN = i.next();\r
+            //match filters: TODO provider extension\r
+            Boolean bAdminStateUp = null;\r
+            Boolean bShared = null;\r
+            Boolean bRouterExternal = null;\r
+            if (queryAdminStateUp != null)\r
+                bAdminStateUp = new Boolean(queryAdminStateUp);\r
+            if (queryShared != null)\r
+                bShared = new Boolean(queryShared);\r
+            if (queryRouterExternal != null)\r
+                bRouterExternal = new Boolean(queryRouterExternal);\r
+            if ((queryID == null || queryID.equals(oSN.getID())) &&\r
+                    (queryName == null || queryName.equals(oSN.getNetworkName())) &&\r
+                    (bAdminStateUp == null || bAdminStateUp.booleanValue() == oSN.isAdminStateUp()) &&\r
+                    (queryStatus == null || queryStatus.equals(oSN.getStatus())) &&\r
+                    (bShared == null || bShared.booleanValue() == oSN.isShared()) &&\r
+                    (bRouterExternal == null || bRouterExternal.booleanValue() == oSN.isRouterExternal()) &&\r
+                    (queryTenantID == null || queryTenantID.equals(oSN.getTenantID()))) {\r
+                if (fields.size() > 0)\r
+                    ans.add(extractFields(oSN,fields));\r
+                else\r
+                    ans.add(oSN);\r
+            }\r
+        }\r
+        //TODO: apply pagination to results\r
+        return Response.status(200).entity(\r
+                new NeutronNetworkRequest(ans)).build();\r
+    }\r
+\r
+    /**\r
+     * Returns a specific Network */\r
+\r
+    @Path("{netUUID}")\r
+    @GET\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackNetworks.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 404, condition = "Not Found") })\r
+    public Response showNetwork(\r
+            @PathParam("netUUID") String netUUID,\r
+            // return fields\r
+            @QueryParam("fields") List<String> fields\r
+            ) {\r
+        INeutronNetworkCRUD networkInterface = NeutronNBInterfaces.getIfNBNetworkCRUD("default", this);\r
+        if (networkInterface == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        if (!networkInterface.networkExists(netUUID))\r
+            return Response.status(404).build();\r
+        if (fields.size() > 0) {\r
+            NeutronNetwork ans = networkInterface.getNetwork(netUUID);\r
+            return Response.status(200).entity(\r
+                    new NeutronNetworkRequest(extractFields(ans, fields))).build();\r
+        } else\r
+            return Response.status(200).entity(\r
+                    new NeutronNetworkRequest(networkInterface.getNetwork(netUUID))).build();\r
+    }\r
+\r
+    /**\r
+     * Creates new Networks */\r
+    @POST\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    @Consumes({ MediaType.APPLICATION_JSON })\r
+    @TypeHint(NeutronNetwork.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 201, condition = "Created"),\r
+            @ResponseCode(code = 400, condition = "Bad Request"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized") })\r
+    public Response createNetworks(final NeutronNetworkRequest input) {\r
+        INeutronNetworkCRUD networkInterface = NeutronNBInterfaces.getIfNBNetworkCRUD("default", this);\r
+        if (networkInterface == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        if (input.isSingleton()) {\r
+            NeutronNetwork singleton = input.getSingleton();\r
+\r
+            /*\r
+             * network ID can't already exist\r
+             */\r
+            if (networkInterface.networkExists(singleton.getID()))\r
+                return Response.status(400).build();\r
+\r
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);\r
+            if (instances != null) {\r
+                for (Object instance : instances) {\r
+                    INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
+                    int status = service.canCreateNetwork(singleton);\r
+                    if (status < 200 || status > 299)\r
+                        return Response.status(status).build();\r
+                }\r
+            }\r
+\r
+            // add network to cache\r
+            networkInterface.addNetwork(singleton);\r
+            if (instances != null) {\r
+                for (Object instance : instances) {\r
+                    INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
+                    service.neutronNetworkCreated(singleton);\r
+                }\r
+            }\r
+\r
+        } else {\r
+            List<NeutronNetwork> bulk = input.getBulk();\r
+            Iterator<NeutronNetwork> i = bulk.iterator();\r
+            HashMap<String, NeutronNetwork> testMap = new HashMap<String, NeutronNetwork>();\r
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);\r
+            while (i.hasNext()) {\r
+                NeutronNetwork test = i.next();\r
+\r
+                /*\r
+                 * network ID can't already exist, nor can there be an entry for this UUID\r
+                 * already in this bulk request\r
+                 */\r
+                if (networkInterface.networkExists(test.getID()))\r
+                    return Response.status(400).build();\r
+                if (testMap.containsKey(test.getID()))\r
+                    return Response.status(400).build();\r
+                if (instances != null) {\r
+                    for (Object instance: instances) {\r
+                        INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
+                        int status = service.canCreateNetwork(test);\r
+                        if (status < 200 || status > 299)\r
+                            return Response.status(status).build();\r
+                    }\r
+                }\r
+                testMap.put(test.getID(),test);\r
+            }\r
+\r
+            // now that everything passed, add items to the cache\r
+            i = bulk.iterator();\r
+            while (i.hasNext()) {\r
+                NeutronNetwork test = i.next();\r
+                test.initDefaults();\r
+                networkInterface.addNetwork(test);\r
+                if (instances != null) {\r
+                    for (Object instance: instances) {\r
+                        INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
+                        service.neutronNetworkCreated(test);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return Response.status(201).entity(input).build();\r
+    }\r
+\r
+    /**\r
+     * Updates a Network */\r
+    @Path("{netUUID}")\r
+    @PUT\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    @Consumes({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackNetworks.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 400, condition = "Bad Request"),\r
+            @ResponseCode(code = 403, condition = "Forbidden"),\r
+            @ResponseCode(code = 404, condition = "Not Found"), })\r
+    public Response updateNetwork(\r
+            @PathParam("netUUID") String netUUID, final NeutronNetworkRequest input\r
+            ) {\r
+        INeutronNetworkCRUD networkInterface = NeutronNBInterfaces.getIfNBNetworkCRUD("default", this);\r
+        if (networkInterface == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        /*\r
+         * network has to exist and only a single delta is supported\r
+         */\r
+        if (!networkInterface.networkExists(netUUID))\r
+            return Response.status(404).build();\r
+        if (!input.isSingleton())\r
+            return Response.status(400).build();\r
+        NeutronNetwork delta = input.getSingleton();\r
+\r
+        /*\r
+         * transitions forbidden by Neutron\r
+         */\r
+        if (delta.getID() != null || delta.getTenantID() != null ||\r
+                delta.getStatus() != null)\r
+            return Response.status(400).build();\r
+\r
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
+                NeutronNetwork original = networkInterface.getNetwork(netUUID);\r
+                int status = service.canUpdateNetwork(delta, original);\r
+                if (status < 200 || status > 299)\r
+                    return Response.status(status).build();\r
+            }\r
+        }\r
+\r
+        // update network object and return the modified object\r
+        networkInterface.updateNetwork(netUUID, delta);\r
+        NeutronNetwork updatedSingleton = networkInterface.getNetwork(netUUID);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
+                service.neutronNetworkUpdated(updatedSingleton);\r
+            }\r
+        }\r
+        return Response.status(200).entity(\r
+                new NeutronNetworkRequest(networkInterface.getNetwork(netUUID))).build();\r
+    }\r
+\r
+    /**\r
+     * Deletes a Network */\r
+\r
+    @Path("{netUUID}")\r
+    @DELETE\r
+    @StatusCodes({\r
+            @ResponseCode(code = 204, condition = "No Content"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 409, condition = "Network In Use") })\r
+    public Response deleteNetwork(\r
+            @PathParam("netUUID") String netUUID) {\r
+        INeutronNetworkCRUD networkInterface = NeutronNBInterfaces.getIfNBNetworkCRUD("default", this);\r
+        if (networkInterface == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        /*\r
+         * network has to exist and not be in use before it can be removed\r
+         */\r
+        if (!networkInterface.networkExists(netUUID))\r
+            return Response.status(404).build();\r
+        if (networkInterface.networkInUse(netUUID))\r
+            return Response.status(409).build();\r
+\r
+        NeutronNetwork singleton = networkInterface.getNetwork(netUUID);\r
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
+                int status = service.canDeleteNetwork(singleton);\r
+                if (status < 200 || status > 299)\r
+                    return Response.status(status).build();\r
+            }\r
+        }\r
+        networkInterface.removeNetwork(netUUID);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
+                service.neutronNetworkDeleted(singleton);\r
+            }\r
+        }\r
+        return Response.status(204).build();\r
+    }\r
+}\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java
new file mode 100644 (file)
index 0000000..020104f
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.northbound;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import javax.ws.rs.core.Application;\r
+import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;\r
+import org.opendaylight.controller.networkconfig.neutron.northbound.NeutronFloatingIPsNorthbound;\r
+import org.opendaylight.controller.networkconfig.neutron.northbound.NeutronNetworksNorthbound;\r
+import org.opendaylight.controller.networkconfig.neutron.northbound.NeutronPortsNorthbound;\r
+import org.opendaylight.controller.networkconfig.neutron.northbound.NeutronRoutersNorthbound;\r
+import org.opendaylight.controller.networkconfig.neutron.northbound.NeutronSubnetsNorthbound;\r
+\r
+\r
+/**\r
+ * This class is an instance of javax.ws.rs.core.Application and is used to return the classes\r
+ * that will be instantiated for JAXRS processing. This is necessary\r
+ * because package scanning in jersey doesn't yet work in OSGi environment.\r
+ *\r
+ */\r
+public class NeutronNorthboundRSApplication extends Application {\r
+    @Override\r
+    public Set<Class<?>> getClasses() {\r
+        Set<Class<?>> classes = new HashSet<Class<?>>();\r
+// northbound URIs\r
+        classes.add(NeutronNetworksNorthbound.class);\r
+        classes.add(NeutronSubnetsNorthbound.class);\r
+        classes.add(NeutronPortsNorthbound.class);\r
+        classes.add(NeutronRoutersNorthbound.class);\r
+        classes.add(NeutronFloatingIPsNorthbound.class);\r
+        return classes;\r
+    }\r
+\r
+    @Override\r
+    public Set<Object> getSingletons() {\r
+        MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider();\r
+\r
+        moxyJsonProvider.setAttributePrefix("@");\r
+        moxyJsonProvider.setFormattedOutput(true);\r
+        moxyJsonProvider.setIncludeRoot(false);\r
+        moxyJsonProvider.setMarshalEmptyCollections(true);\r
+        moxyJsonProvider.setValueWrapper("$");\r
+\r
+        Map<String, String> namespacePrefixMapper = new HashMap<String, String>(1);\r
+        namespacePrefixMapper.put("router", "router");        // FIXME: fill in with XSD\r
+        namespacePrefixMapper.put("provider", "provider");    // FIXME: fill in with XSD\r
+        moxyJsonProvider.setNamespacePrefixMapper(namespacePrefixMapper);\r
+        moxyJsonProvider.setNamespaceSeparator(':');\r
+\r
+        HashSet<Object> set = new HashSet<Object>(1);\r
+        set.add(moxyJsonProvider);\r
+        return set;\r
+    }\r
+}\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortRequest.java
new file mode 100644 (file)
index 0000000..f6765fb
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.northbound;\r
+\r
+import java.util.List;\r
+\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+public class NeutronPortRequest {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement(name="port")\r
+    NeutronPort singletonPort;\r
+\r
+    @XmlElement(name="ports")\r
+    List<NeutronPort> bulkRequest;\r
+\r
+    NeutronPortRequest() {\r
+    }\r
+\r
+    NeutronPortRequest(List<NeutronPort> bulk) {\r
+        bulkRequest = bulk;\r
+        singletonPort = null;\r
+    }\r
+\r
+    NeutronPortRequest(NeutronPort port) {\r
+        singletonPort = port;\r
+    }\r
+\r
+    public NeutronPort getSingleton() {\r
+        return singletonPort;\r
+    }\r
+\r
+    public boolean isSingleton() {\r
+        return (singletonPort != null);\r
+    }\r
+\r
+    public List<NeutronPort> getBulk() {\r
+        return bulkRequest;\r
+    }\r
+}\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java
new file mode 100644 (file)
index 0000000..78646a6
--- /dev/null
@@ -0,0 +1,476 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.northbound;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import javax.ws.rs.Consumes;\r
+import javax.ws.rs.DELETE;\r
+import javax.ws.rs.GET;\r
+import javax.ws.rs.POST;\r
+import javax.ws.rs.PUT;\r
+import javax.ws.rs.Path;\r
+import javax.ws.rs.PathParam;\r
+import javax.ws.rs.Produces;\r
+import javax.ws.rs.QueryParam;\r
+import javax.ws.rs.core.MediaType;\r
+import javax.ws.rs.core.Response;\r
+\r
+import org.codehaus.enunciate.jaxrs.ResponseCode;\r
+import org.codehaus.enunciate.jaxrs.StatusCodes;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortAware;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
+import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;\r
+import org.opendaylight.controller.northbound.commons.RestMessages;\r
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
+import org.opendaylight.controller.sal.utils.ServiceHelper;\r
+\r
+/**\r
+ * Open DOVE Northbound REST APIs.<br>\r
+ * This class provides REST APIs for managing the open DOVE\r
+ *\r
+ * <br>\r
+ * <br>\r
+ * Authentication scheme : <b>HTTP Basic</b><br>\r
+ * Authentication realm : <b>opendaylight</b><br>\r
+ * Transport : <b>HTTP and HTTPS</b><br>\r
+ * <br>\r
+ * HTTPS Authentication is disabled by default. Administrator can enable it in\r
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
+ * trusted authority.<br>\r
+ * More info :\r
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
+ *\r
+ */\r
+\r
+@Path("/ports")\r
+public class NeutronPortsNorthbound {\r
+\r
+    private NeutronPort extractFields(NeutronPort o, List<String> fields) {\r
+        return o.extractFields(fields);\r
+    }\r
+\r
+    /**\r
+     * Returns a list of all Ports */\r
+\r
+    @GET\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackPorts.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response listPorts(\r
+            // return fields\r
+            @QueryParam("fields") List<String> fields,\r
+            // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
+            @QueryParam("id") String queryID,\r
+            @QueryParam("network_id") String queryNetworkID,\r
+            @QueryParam("name") String queryName,\r
+            @QueryParam("admin_state_up") String queryAdminStateUp,\r
+            @QueryParam("status") String queryStatus,\r
+            @QueryParam("mac_address") String queryMACAddress,\r
+            @QueryParam("device_id") String queryDeviceID,\r
+            @QueryParam("device_owner") String queryDeviceOwner,\r
+            @QueryParam("tenant_id") String queryTenantID,\r
+            // pagination\r
+            @QueryParam("limit") String limit,\r
+            @QueryParam("marker") String marker,\r
+            @QueryParam("page_reverse") String pageReverse\r
+            // sorting not supported\r
+            ) {\r
+        INeutronPortCRUD portInterface = NeutronNBInterfaces.getIfNBPortCRUD("default",this);\r
+        if (portInterface == null) {\r
+            throw new ServiceUnavailableException("Port CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        List<NeutronPort> allPorts = portInterface.getAllPorts();\r
+        List<NeutronPort> ans = new ArrayList<NeutronPort>();\r
+        Iterator<NeutronPort> i = allPorts.iterator();\r
+        while (i.hasNext()) {\r
+            NeutronPort oSS = i.next();\r
+            if ((queryID == null || queryID.equals(oSS.getID())) &&\r
+                    (queryNetworkID == null || queryNetworkID.equals(oSS.getNetworkUUID())) &&\r
+                    (queryName == null || queryName.equals(oSS.getName())) &&\r
+                    (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&\r
+                    (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&\r
+                    (queryMACAddress == null || queryMACAddress.equals(oSS.getMacAddress())) &&\r
+                    (queryDeviceID == null || queryDeviceID.equals(oSS.getDeviceID())) &&\r
+                    (queryDeviceOwner == null || queryDeviceOwner.equals(oSS.getDeviceOwner())) &&\r
+                    (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {\r
+                if (fields.size() > 0)\r
+                    ans.add(extractFields(oSS,fields));\r
+                else\r
+                    ans.add(oSS);\r
+            }\r
+        }\r
+        //TODO: apply pagination to results\r
+        return Response.status(200).entity(\r
+                new NeutronPortRequest(ans)).build();\r
+    }\r
+\r
+    /**\r
+     * Returns a specific Port */\r
+\r
+    @Path("{portUUID}")\r
+    @GET\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackPorts.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response showPort(\r
+            @PathParam("portUUID") String portUUID,\r
+            // return fields\r
+            @QueryParam("fields") List<String> fields ) {\r
+        INeutronPortCRUD portInterface = NeutronNBInterfaces.getIfNBPortCRUD("default",this);\r
+        if (portInterface == null) {\r
+            throw new ServiceUnavailableException("Port CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        if (!portInterface.portExists(portUUID))\r
+            return Response.status(404).build();\r
+        if (fields.size() > 0) {\r
+            NeutronPort ans = portInterface.getPort(portUUID);\r
+            return Response.status(200).entity(\r
+                    new NeutronPortRequest(extractFields(ans, fields))).build();\r
+        } else\r
+            return Response.status(200).entity(\r
+                    new NeutronPortRequest(portInterface.getPort(portUUID))).build();\r
+    }\r
+\r
+    /**\r
+     * Creates new Ports */\r
+\r
+    @POST\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    @Consumes({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackPorts.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 201, condition = "Created"),\r
+            @ResponseCode(code = 400, condition = "Bad Request"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 403, condition = "Forbidden"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 409, condition = "Conflict"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented"),\r
+            @ResponseCode(code = 503, condition = "MAC generation failure") })\r
+    public Response createPorts(final NeutronPortRequest input) {\r
+        INeutronPortCRUD portInterface = NeutronNBInterfaces.getIfNBPortCRUD("default",this);\r
+        if (portInterface == null) {\r
+            throw new ServiceUnavailableException("Port CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronNetworkCRUD networkInterface = NeutronNBInterfaces.getIfNBNetworkCRUD("default", this);\r
+        if (networkInterface == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronSubnetCRUD subnetInterface = NeutronNBInterfaces.getIfNBSubnetCRUD("default", this);\r
+        if (subnetInterface == null) {\r
+            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        if (input.isSingleton()) {\r
+            NeutronPort singleton = input.getSingleton();\r
+\r
+            /*\r
+             * the port must be part of an existing network, must not already exist,\r
+             * have a valid MAC and the MAC not be in use\r
+             */\r
+            if (singleton.getNetworkUUID() == null)\r
+                return Response.status(400).build();\r
+            if (portInterface.portExists(singleton.getID()))\r
+                return Response.status(400).build();\r
+            if (!networkInterface.networkExists(singleton.getNetworkUUID()))\r
+                return Response.status(404).build();\r
+            if (singleton.getMacAddress() == null ||\r
+                    !singleton.getMacAddress().matches("^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$"))\r
+                return Response.status(400).build();\r
+            if (portInterface.macInUse(singleton.getMacAddress()))\r
+                return Response.status(409).build();\r
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);\r
+            if (instances != null) {\r
+                for (Object instance : instances) {\r
+                    INeutronPortAware service = (INeutronPortAware) instance;\r
+                    int status = service.canCreatePort(singleton);\r
+                    if (status < 200 || status > 299)\r
+                        return Response.status(status).build();\r
+                }\r
+            }\r
+            /*\r
+             * if fixed IPs are specified, each one has to have an existing subnet ID\r
+             * that is in the same scoping network as the port.  In addition, if an IP\r
+             * address is specified it has to be a valid address for the subnet and not\r
+             * already in use\r
+             */\r
+            List<Neutron_IPs> fixedIPs = singleton.getFixedIPs();\r
+            if (fixedIPs != null && fixedIPs.size() > 0) {\r
+                Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();\r
+                while (fixedIPIterator.hasNext()) {\r
+                    Neutron_IPs ip = fixedIPIterator.next();\r
+                    if (ip.getSubnetUUID() == null)\r
+                        return Response.status(400).build();\r
+                    if (!subnetInterface.subnetExists(ip.getSubnetUUID()))\r
+                        return Response.status(400).build();\r
+                    NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());\r
+                    if (!singleton.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))\r
+                        return Response.status(400).build();\r
+                    if (ip.getIpAddress() != null) {\r
+                        if (!subnet.isValidIP(ip.getIpAddress()))\r
+                            return Response.status(400).build();\r
+                        if (subnet.isIPInUse(ip.getIpAddress()))\r
+                            return Response.status(409).build();\r
+                    }\r
+                }\r
+            }\r
+\r
+            // add the port to the cache\r
+            portInterface.addPort(singleton);\r
+            if (instances != null) {\r
+                for (Object instance : instances) {\r
+                    INeutronPortAware service = (INeutronPortAware) instance;\r
+                    service.neutronPortCreated(singleton);\r
+                }\r
+            }\r
+        } else {\r
+            List<NeutronPort> bulk = input.getBulk();\r
+            Iterator<NeutronPort> i = bulk.iterator();\r
+            HashMap<String, NeutronPort> testMap = new HashMap<String, NeutronPort>();\r
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
+            while (i.hasNext()) {\r
+                NeutronPort test = i.next();\r
+\r
+                /*\r
+                 * the port must be part of an existing network, must not already exist,\r
+                 * have a valid MAC and the MAC not be in use.  Further the bulk request\r
+                 * can't already contain a new port with the same UUID\r
+                 */\r
+                if (portInterface.portExists(test.getID()))\r
+                    return Response.status(400).build();\r
+                if (testMap.containsKey(test.getID()))\r
+                    return Response.status(400).build();\r
+                for (NeutronPort check : testMap.values()) {\r
+                    if (test.getMacAddress().equalsIgnoreCase(check.getMacAddress()))\r
+                        return Response.status(409).build();\r
+                    for (Neutron_IPs test_fixedIP : test.getFixedIPs()) {\r
+                        for (Neutron_IPs check_fixedIP : check.getFixedIPs()) {\r
+                            if (test_fixedIP.getIpAddress().equals(check_fixedIP.getIpAddress()))\r
+                                return Response.status(409).build();\r
+                        }\r
+                    }\r
+                }\r
+                testMap.put(test.getID(), test);\r
+                if (!networkInterface.networkExists(test.getNetworkUUID()))\r
+                    return Response.status(404).build();\r
+                if (!test.getMacAddress().matches("^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$"))\r
+                    return Response.status(400).build();\r
+                if (portInterface.macInUse(test.getMacAddress()))\r
+                    return Response.status(409).build();\r
+                if (instances != null) {\r
+                    for (Object instance : instances) {\r
+                        INeutronPortAware service = (INeutronPortAware) instance;\r
+                        int status = service.canCreatePort(test);\r
+                        if (status < 200 || status > 299)\r
+                            return Response.status(status).build();\r
+                    }\r
+                }\r
+                /*\r
+                 * if fixed IPs are specified, each one has to have an existing subnet ID\r
+                 * that is in the same scoping network as the port.  In addition, if an IP\r
+                 * address is specified it has to be a valid address for the subnet and not\r
+                 * already in use (or be the gateway IP address of the subnet)\r
+                 */\r
+                List<Neutron_IPs> fixedIPs = test.getFixedIPs();\r
+                if (fixedIPs != null && fixedIPs.size() > 0) {\r
+                    Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();\r
+                    while (fixedIPIterator.hasNext()) {\r
+                        Neutron_IPs ip = fixedIPIterator.next();\r
+                        if (ip.getSubnetUUID() == null)\r
+                            return Response.status(400).build();\r
+                        if (!subnetInterface.subnetExists(ip.getSubnetUUID()))\r
+                            return Response.status(400).build();\r
+                        NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());\r
+                        if (!test.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))\r
+                            return Response.status(400).build();\r
+                        if (ip.getIpAddress() != null) {\r
+                            if (!subnet.isValidIP(ip.getIpAddress()))\r
+                                return Response.status(400).build();\r
+                            //TODO: need to add consideration for a fixed IP being assigned the same address as a allocated IP in the\r
+                            //same bulk create\r
+                            if (subnet.isIPInUse(ip.getIpAddress()))\r
+                                return Response.status(409).build();\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+\r
+            //once everything has passed, then we can add to the cache\r
+            i = bulk.iterator();\r
+            while (i.hasNext()) {\r
+                NeutronPort test = i.next();\r
+                portInterface.addPort(test);\r
+                if (instances != null) {\r
+                    for (Object instance : instances) {\r
+                        INeutronPortAware service = (INeutronPortAware) instance;\r
+                        service.neutronPortCreated(test);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return Response.status(201).entity(input).build();\r
+    }\r
+\r
+    /**\r
+     * Updates a Port */\r
+\r
+    @Path("{portUUID}")\r
+    @PUT\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    @Consumes({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackPorts.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 400, condition = "Bad Request"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 403, condition = "Forbidden"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 409, condition = "Conflict"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response updatePort(\r
+            @PathParam("portUUID") String portUUID,\r
+            NeutronPortRequest input\r
+            ) {\r
+        INeutronPortCRUD portInterface = NeutronNBInterfaces.getIfNBPortCRUD("default",this);\r
+        if (portInterface == null) {\r
+            throw new ServiceUnavailableException("Port CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronSubnetCRUD subnetInterface = NeutronNBInterfaces.getIfNBSubnetCRUD("default", this);\r
+        if (subnetInterface == null) {\r
+            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        // port has to exist and only a single delta is supported\r
+        if (!portInterface.portExists(portUUID))\r
+            return Response.status(404).build();\r
+        NeutronPort target = portInterface.getPort(portUUID);\r
+        if (!input.isSingleton())\r
+            return Response.status(400).build();\r
+        NeutronPort singleton = input.getSingleton();\r
+        NeutronPort original = portInterface.getPort(portUUID);\r
+\r
+        // deltas restricted by Neutron\r
+        if (singleton.getID() != null || singleton.getTenantID() != null ||\r
+                singleton.getStatus() != null)\r
+            return Response.status(400).build();\r
+\r
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronPortAware service = (INeutronPortAware) instance;\r
+                int status = service.canUpdatePort(singleton, original);\r
+                if (status < 200 || status > 299)\r
+                    return Response.status(status).build();\r
+            }\r
+        }\r
+\r
+        // Verify the new fixed ips are valid\r
+        List<Neutron_IPs> fixedIPs = singleton.getFixedIPs();\r
+        if (fixedIPs != null && fixedIPs.size() > 0) {\r
+            Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();\r
+            while (fixedIPIterator.hasNext()) {\r
+                Neutron_IPs ip = fixedIPIterator.next();\r
+                if (ip.getSubnetUUID() == null)\r
+                    return Response.status(400).build();\r
+                if (!subnetInterface.subnetExists(ip.getSubnetUUID()))\r
+                    return Response.status(400).build();\r
+                NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());\r
+                if (!target.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))\r
+                    return Response.status(400).build();\r
+                if (ip.getIpAddress() != null) {\r
+                    if (!subnet.isValidIP(ip.getIpAddress()))\r
+                        return Response.status(400).build();\r
+                    if (subnet.isIPInUse(ip.getIpAddress()))\r
+                        return Response.status(409).build();\r
+                }\r
+            }\r
+        }\r
+\r
+//        TODO: Support change of security groups\r
+        // update the port and return the modified object\r
+        portInterface.updatePort(portUUID, singleton);\r
+        NeutronPort updatedPort = portInterface.getPort(portUUID);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronPortAware service = (INeutronPortAware) instance;\r
+                service.neutronPortUpdated(updatedPort);\r
+            }\r
+        }\r
+        return Response.status(200).entity(\r
+                new NeutronPortRequest(updatedPort)).build();\r
+\r
+    }\r
+\r
+    /**\r
+     * Deletes a Port */\r
+\r
+    @Path("{portUUID}")\r
+    @DELETE\r
+    @StatusCodes({\r
+        @ResponseCode(code = 204, condition = "No Content"),\r
+        @ResponseCode(code = 401, condition = "Unauthorized"),\r
+        @ResponseCode(code = 403, condition = "Forbidden"),\r
+        @ResponseCode(code = 404, condition = "Not Found"),\r
+        @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response deletePort(\r
+            @PathParam("portUUID") String portUUID) {\r
+        INeutronPortCRUD portInterface = NeutronNBInterfaces.getIfNBPortCRUD("default",this);\r
+        if (portInterface == null) {\r
+            throw new ServiceUnavailableException("Port CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        // port has to exist and not be owned by anyone.  then it can be removed from the cache\r
+        if (!portInterface.portExists(portUUID))\r
+            return Response.status(404).build();\r
+        NeutronPort port = portInterface.getPort(portUUID);\r
+        if (port.getDeviceID() != null ||\r
+                port.getDeviceOwner() != null)\r
+            Response.status(403).build();\r
+        NeutronPort singleton = portInterface.getPort(portUUID);\r
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronPortAware service = (INeutronPortAware) instance;\r
+                int status = service.canDeletePort(singleton);\r
+                if (status < 200 || status > 299)\r
+                    return Response.status(status).build();\r
+            }\r
+        }\r
+        portInterface.removePort(portUUID);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronPortAware service = (INeutronPortAware) instance;\r
+                service.neutronPortDeleted(singleton);\r
+            }\r
+        }\r
+        return Response.status(204).build();\r
+    }\r
+}\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRouterRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRouterRequest.java
new file mode 100644 (file)
index 0000000..1fcc9a9
--- /dev/null
@@ -0,0 +1,57 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.northbound;\r
+\r
+import java.util.List;\r
+\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;\r
+\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+\r
+public class NeutronRouterRequest {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement(name="router")\r
+    NeutronRouter singletonRouter;\r
+\r
+    @XmlElement(name="routers")\r
+    List<NeutronRouter> bulkRequest;\r
+\r
+    NeutronRouterRequest() {\r
+    }\r
+\r
+    NeutronRouterRequest(List<NeutronRouter> bulk) {\r
+        bulkRequest = bulk;\r
+        singletonRouter = null;\r
+    }\r
+\r
+    NeutronRouterRequest(NeutronRouter router) {\r
+        singletonRouter = router;\r
+    }\r
+\r
+    public List<NeutronRouter> getBulk() {\r
+        return bulkRequest;\r
+    }\r
+\r
+    public NeutronRouter getSingleton() {\r
+        return singletonRouter;\r
+    }\r
+\r
+    public boolean isSingleton() {\r
+        return (singletonRouter != null);\r
+    }\r
+}\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRoutersNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRoutersNorthbound.java
new file mode 100644 (file)
index 0000000..0ffb085
--- /dev/null
@@ -0,0 +1,552 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.northbound;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import javax.ws.rs.Consumes;\r
+import javax.ws.rs.DELETE;\r
+import javax.ws.rs.GET;\r
+import javax.ws.rs.POST;\r
+import javax.ws.rs.PUT;\r
+import javax.ws.rs.Path;\r
+import javax.ws.rs.PathParam;\r
+import javax.ws.rs.Produces;\r
+import javax.ws.rs.QueryParam;\r
+import javax.ws.rs.core.MediaType;\r
+import javax.ws.rs.core.Response;\r
+\r
+import org.codehaus.enunciate.jaxrs.ResponseCode;\r
+import org.codehaus.enunciate.jaxrs.StatusCodes;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortAware;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronRouterAware;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter_Interface;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
+import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;\r
+import org.opendaylight.controller.northbound.commons.RestMessages;\r
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
+import org.opendaylight.controller.sal.utils.ServiceHelper;\r
+\r
+\r
+/**\r
+ * Open DOVE Northbound REST APIs.<br>\r
+ * This class provides REST APIs for managing the open DOVE\r
+ *\r
+ * <br>\r
+ * <br>\r
+ * Authentication scheme : <b>HTTP Basic</b><br>\r
+ * Authentication realm : <b>opendaylight</b><br>\r
+ * Transport : <b>HTTP and HTTPS</b><br>\r
+ * <br>\r
+ * HTTPS Authentication is disabled by default. Administrator can enable it in\r
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
+ * trusted authority.<br>\r
+ * More info :\r
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
+ *\r
+ */\r
+\r
+@Path("/routers")\r
+public class NeutronRoutersNorthbound {\r
+\r
+    private NeutronRouter extractFields(NeutronRouter o, List<String> fields) {\r
+        return o.extractFields(fields);\r
+    }\r
+\r
+    /**\r
+     * Returns a list of all Routers */\r
+\r
+    @GET\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackRouters.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response listRouters(\r
+            // return fields\r
+            @QueryParam("fields") List<String> fields,\r
+            // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
+            @QueryParam("id") String queryID,\r
+            @QueryParam("name") String queryName,\r
+            @QueryParam("admin_state_up") String queryAdminStateUp,\r
+            @QueryParam("status") String queryStatus,\r
+            @QueryParam("tenant_id") String queryTenantID,\r
+            @QueryParam("external_gateway_info") String queryExternalGatewayInfo,\r
+            // pagination\r
+            @QueryParam("limit") String limit,\r
+            @QueryParam("marker") String marker,\r
+            @QueryParam("page_reverse") String pageReverse\r
+            // sorting not supported\r
+            ) {\r
+        INeutronRouterCRUD routerInterface = NeutronNBInterfaces.getIfNBRouterCRUD("default",this);\r
+        if (routerInterface == null) {\r
+            throw new ServiceUnavailableException("Router CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        List<NeutronRouter> allRouters = routerInterface.getAllRouters();\r
+        List<NeutronRouter> ans = new ArrayList<NeutronRouter>();\r
+        Iterator<NeutronRouter> i = allRouters.iterator();\r
+        while (i.hasNext()) {\r
+            NeutronRouter oSS = i.next();\r
+            if ((queryID == null || queryID.equals(oSS.getID())) &&\r
+                    (queryName == null || queryName.equals(oSS.getName())) &&\r
+                    (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&\r
+                    (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&\r
+                    (queryExternalGatewayInfo == null || queryExternalGatewayInfo.equals(oSS.getExternalGatewayInfo())) &&\r
+                    (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {\r
+                if (fields.size() > 0)\r
+                    ans.add(extractFields(oSS,fields));\r
+                else\r
+                    ans.add(oSS);\r
+            }\r
+        }\r
+        //TODO: apply pagination to results\r
+        return Response.status(200).entity(\r
+                new NeutronRouterRequest(ans)).build();\r
+    }\r
+\r
+    /**\r
+     * Returns a specific Router */\r
+\r
+    @Path("{routerUUID}")\r
+    @GET\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackRouters.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 403, condition = "Forbidden"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response showRouter(\r
+            @PathParam("routerUUID") String routerUUID,\r
+            // return fields\r
+            @QueryParam("fields") List<String> fields) {\r
+        INeutronRouterCRUD routerInterface = NeutronNBInterfaces.getIfNBRouterCRUD("default",this);\r
+        if (routerInterface == null) {\r
+            throw new ServiceUnavailableException("Router CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        if (!routerInterface.routerExists(routerUUID))\r
+            return Response.status(404).build();\r
+        if (fields.size() > 0) {\r
+            NeutronRouter ans = routerInterface.getRouter(routerUUID);\r
+            return Response.status(200).entity(\r
+                    new NeutronRouterRequest(extractFields(ans, fields))).build();\r
+        } else\r
+            return Response.status(200).entity(\r
+                    new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();\r
+    }\r
+\r
+    /**\r
+     * Creates new Routers */\r
+\r
+    @POST\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    @Consumes({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackRouters.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 201, condition = "Created"),\r
+            @ResponseCode(code = 400, condition = "Bad Request"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response createRouters(final NeutronRouterRequest input) {\r
+        INeutronRouterCRUD routerInterface = NeutronNBInterfaces.getIfNBRouterCRUD("default",this);\r
+        if (routerInterface == null) {\r
+            throw new ServiceUnavailableException("Router CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronNetworkCRUD networkInterface = NeutronNBInterfaces.getIfNBNetworkCRUD("default", this);\r
+        if (networkInterface == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        if (input.isSingleton()) {\r
+            NeutronRouter singleton = input.getSingleton();\r
+\r
+            /*\r
+             * verify that the router doesn't already exist (issue: is deeper inspection necessary?)\r
+             * if there is external gateway information provided, verify that the specified network\r
+             * exists and has been designated as "router:external"\r
+             */\r
+            if (routerInterface.routerExists(singleton.getID()))\r
+                return Response.status(400).build();\r
+            if (singleton.getExternalGatewayInfo() != null) {\r
+                String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();\r
+                if (!networkInterface.networkExists(externNetworkPtr))\r
+                    return Response.status(400).build();\r
+                NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);\r
+                if (!externNetwork.isRouterExternal())\r
+                    return Response.status(400).build();\r
+            }\r
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
+            if (instances != null) {\r
+                for (Object instance : instances) {\r
+                    INeutronRouterAware service = (INeutronRouterAware) instance;\r
+                    int status = service.canCreateRouter(singleton);\r
+                    if (status < 200 || status > 299)\r
+                        return Response.status(status).build();\r
+                }\r
+            }\r
+\r
+            /*\r
+             * add router to the cache\r
+             */\r
+            routerInterface.addRouter(singleton);\r
+            if (instances != null) {\r
+                for (Object instance : instances) {\r
+                    INeutronRouterAware service = (INeutronRouterAware) instance;\r
+                    service.neutronRouterCreated(singleton);\r
+                }\r
+            }\r
+        } else {\r
+\r
+            /*\r
+             * only singleton router creates supported\r
+             */\r
+            return Response.status(400).build();\r
+        }\r
+        return Response.status(201).entity(input).build();\r
+    }\r
+\r
+    /**\r
+     * Updates a Router */\r
+\r
+    @Path("{routerUUID}")\r
+    @PUT\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    @Consumes({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackRouters.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 400, condition = "Bad Request"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response updateRouter(\r
+            @PathParam("routerUUID") String routerUUID,\r
+            NeutronRouterRequest input\r
+            ) {\r
+        INeutronRouterCRUD routerInterface = NeutronNBInterfaces.getIfNBRouterCRUD("default",this);\r
+        if (routerInterface == null) {\r
+            throw new ServiceUnavailableException("Router CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronNetworkCRUD networkInterface = NeutronNBInterfaces.getIfNBNetworkCRUD("default", this);\r
+        if (networkInterface == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        /*\r
+         * router has to exist and only a single delta can be supplied\r
+         */\r
+        if (!routerInterface.routerExists(routerUUID))\r
+            return Response.status(404).build();\r
+        if (!input.isSingleton())\r
+            return Response.status(400).build();\r
+        NeutronRouter singleton = input.getSingleton();\r
+        NeutronRouter original = routerInterface.getRouter(routerUUID);\r
+\r
+        /*\r
+         * attribute changes blocked by Neutron\r
+         */\r
+        if (singleton.getID() != null || singleton.getTenantID() != null ||\r
+                singleton.getStatus() != null)\r
+            return Response.status(400).build();\r
+\r
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronRouterAware service = (INeutronRouterAware) instance;\r
+                int status = service.canUpdateRouter(singleton, original);\r
+                if (status < 200 || status > 299)\r
+                    return Response.status(status).build();\r
+            }\r
+        }\r
+        /*\r
+         * if the external gateway info is being changed, verify that the new network\r
+         * exists and has been designated as an external network\r
+         */\r
+        if (singleton.getExternalGatewayInfo() != null) {\r
+            String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();\r
+            if (!networkInterface.networkExists(externNetworkPtr))\r
+                return Response.status(400).build();\r
+            NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);\r
+            if (!externNetwork.isRouterExternal())\r
+                return Response.status(400).build();\r
+        }\r
+\r
+        /*\r
+         * update the router entry and return the modified object\r
+         */\r
+        routerInterface.updateRouter(routerUUID, singleton);\r
+        NeutronRouter updatedRouter = routerInterface.getRouter(routerUUID);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronRouterAware service = (INeutronRouterAware) instance;\r
+                service.neutronRouterUpdated(updatedRouter);\r
+            }\r
+        }\r
+        return Response.status(200).entity(\r
+                new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();\r
+\r
+    }\r
+\r
+    /**\r
+     * Deletes a Router */\r
+\r
+    @Path("{routerUUID}")\r
+    @DELETE\r
+    @StatusCodes({\r
+            @ResponseCode(code = 204, condition = "No Content"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 409, condition = "Conflict"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response deleteRouter(\r
+            @PathParam("routerUUID") String routerUUID) {\r
+        INeutronRouterCRUD routerInterface = NeutronNBInterfaces.getIfNBRouterCRUD("default",this);\r
+        if (routerInterface == null) {\r
+            throw new ServiceUnavailableException("Router CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        /*\r
+         * verify that the router exists and is not in use before removing it\r
+         */\r
+        if (!routerInterface.routerExists(routerUUID))\r
+            return Response.status(404).build();\r
+        if (routerInterface.routerInUse(routerUUID))\r
+            return Response.status(409).build();\r
+        NeutronRouter singleton = routerInterface.getRouter(routerUUID);\r
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronRouterAware service = (INeutronRouterAware) instance;\r
+                int status = service.canDeleteRouter(singleton);\r
+                if (status < 200 || status > 299)\r
+                    return Response.status(status).build();\r
+            }\r
+        }\r
+        routerInterface.removeRouter(routerUUID);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronRouterAware service = (INeutronRouterAware) instance;\r
+                service.neutronRouterDeleted(singleton);\r
+            }\r
+        }\r
+        return Response.status(204).build();\r
+    }\r
+\r
+    /**\r
+     * Adds an interface to a router */\r
+\r
+    @Path("{routerUUID}/add_router_interface")\r
+    @PUT\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    @Consumes({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackRouterInterfaces.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 400, condition = "Bad Request"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 409, condition = "Conflict"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response addRouterInterface(\r
+            @PathParam("routerUUID") String routerUUID,\r
+            NeutronRouter_Interface input\r
+            ) {\r
+        INeutronRouterCRUD routerInterface = NeutronNBInterfaces.getIfNBRouterCRUD("default",this);\r
+        if (routerInterface == null) {\r
+            throw new ServiceUnavailableException("Router CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronPortCRUD portInterface = NeutronNBInterfaces.getIfNBPortCRUD("default",this);\r
+        if (portInterface == null) {\r
+            throw new ServiceUnavailableException("Port CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronSubnetCRUD subnetInterface = NeutronNBInterfaces.getIfNBSubnetCRUD("default",this);\r
+        if (subnetInterface == null) {\r
+            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        /*\r
+         *  While the Neutron specification says that the router has to exist and the input can only specify either a subnet id\r
+         *  or a port id, but not both, this code assumes that the plugin has filled everything in for us and so both must be present\r
+         */\r
+        if (!routerInterface.routerExists(routerUUID))\r
+            return Response.status(400).build();\r
+        NeutronRouter target = routerInterface.getRouter(routerUUID);\r
+        if (input.getSubnetUUID() == null ||\r
+                    input.getPortUUID() == null)\r
+                return Response.status(400).build();\r
+\r
+        // check that the port is part of the subnet\r
+        NeutronSubnet targetSubnet = subnetInterface.getSubnet(input.getSubnetUUID());\r
+        if (targetSubnet == null)\r
+            return Response.status(400).build();\r
+        NeutronPort targetPort = portInterface.getPort(input.getPortUUID());\r
+        if (targetPort == null)\r
+            return Response.status(400).build();\r
+        if (!targetSubnet.getPortsInSubnet().contains(targetPort))\r
+            return Response.status(400).build();\r
+\r
+        if (targetPort.getFixedIPs().size() != 1)\r
+            return Response.status(400).build();\r
+        if (targetPort.getDeviceID() != null ||\r
+                targetPort.getDeviceOwner() != null)\r
+            return Response.status(409).build();\r
+\r
+        //mark the port device id and device owner fields\r
+        targetPort.setDeviceOwner("network:router_interface");\r
+        targetPort.setDeviceID(routerUUID);\r
+\r
+        target.addInterface(input.getPortUUID(), input);\r
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronRouterAware service = (INeutronRouterAware) instance;\r
+                service.neutronRouterInterfaceAttached(target, input);\r
+            }\r
+        }\r
+\r
+        return Response.status(200).entity(input).build();\r
+    }\r
+\r
+    /**\r
+     * Removes an interface to a router */\r
+\r
+    @Path("{routerUUID}/remove_router_interface")\r
+    @PUT\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    @Consumes({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackRouterInterfaces.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 400, condition = "Bad Request"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 409, condition = "Conflict"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response removeRouterInterface(\r
+            @PathParam("routerUUID") String routerUUID,\r
+            NeutronRouter_Interface input\r
+            ) {\r
+        INeutronRouterCRUD routerInterface = NeutronNBInterfaces.getIfNBRouterCRUD("default",this);\r
+        if (routerInterface == null) {\r
+            throw new ServiceUnavailableException("Router CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronPortCRUD portInterface = NeutronNBInterfaces.getIfNBPortCRUD("default",this);\r
+        if (portInterface == null) {\r
+            throw new ServiceUnavailableException("Port CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronSubnetCRUD subnetInterface = NeutronNBInterfaces.getIfNBSubnetCRUD("default",this);\r
+        if (subnetInterface == null) {\r
+            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        // verify the router exists\r
+        if (!routerInterface.routerExists(routerUUID))\r
+            return Response.status(400).build();\r
+        NeutronRouter target = routerInterface.getRouter(routerUUID);\r
+\r
+        /*\r
+         * remove by subnet id.  Collect information about the impacted router for the response and\r
+         * remove the port corresponding to the gateway IP address of the subnet\r
+         */\r
+        if (input.getPortUUID() == null &&\r
+                input.getSubnetUUID() != null) {\r
+            NeutronPort port = portInterface.getGatewayPort(input.getSubnetUUID());\r
+            if (port == null)\r
+                return Response.status(404).build();\r
+            input.setPortUUID(port.getID());\r
+            input.setID(target.getID());\r
+            input.setTenantID(target.getTenantID());\r
+\r
+            // reset the port ownership\r
+            port.setDeviceID(null);\r
+            port.setDeviceOwner(null);\r
+\r
+            target.removeInterface(input.getPortUUID());\r
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
+            if (instances != null) {\r
+                for (Object instance : instances) {\r
+                    INeutronRouterAware service = (INeutronRouterAware) instance;\r
+                    service.neutronRouterInterfaceDetached(target, input);\r
+                }\r
+            }\r
+            return Response.status(200).entity(input).build();\r
+        }\r
+\r
+        /*\r
+         * remove by port id. collect information about the impacted router for the response\r
+         * remove the interface and reset the port ownership\r
+         */\r
+        if (input.getPortUUID() != null &&\r
+                input.getSubnetUUID() == null) {\r
+            NeutronRouter_Interface targetInterface = target.getInterfaces().get(input.getPortUUID());\r
+            input.setSubnetUUID(targetInterface.getSubnetUUID());\r
+            input.setID(target.getID());\r
+            input.setTenantID(target.getTenantID());\r
+            NeutronPort port = portInterface.getPort(input.getPortUUID());\r
+            port.setDeviceID(null);\r
+            port.setDeviceOwner(null);\r
+            target.removeInterface(input.getPortUUID());\r
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
+            for (Object instance : instances) {\r
+                INeutronRouterAware service = (INeutronRouterAware) instance;\r
+                service.neutronRouterInterfaceDetached(target, input);\r
+            }\r
+            return Response.status(200).entity(input).build();\r
+        }\r
+\r
+        /*\r
+         * remove by both port and subnet ID.  Verify that the first fixed IP of the port is a valid\r
+         * IP address for the subnet, and then remove the interface, collecting information about the\r
+         * impacted router for the response and reset port ownership\r
+         */\r
+        if (input.getPortUUID() != null &&\r
+                input.getSubnetUUID() != null) {\r
+            NeutronPort port = portInterface.getPort(input.getPortUUID());\r
+            NeutronSubnet subnet = subnetInterface.getSubnet(input.getSubnetUUID());\r
+            if (!subnet.isValidIP(port.getFixedIPs().get(0).getIpAddress()))\r
+                return Response.status(409).build();\r
+            input.setID(target.getID());\r
+            input.setTenantID(target.getTenantID());\r
+            port.setDeviceID(null);\r
+            port.setDeviceOwner(null);\r
+            target.removeInterface(input.getPortUUID());\r
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
+            for (Object instance : instances) {\r
+                INeutronRouterAware service = (INeutronRouterAware) instance;\r
+                service.neutronRouterInterfaceDetached(target, input);\r
+            }\r
+            return Response.status(200).entity(input).build();\r
+        }\r
+\r
+        // have to specify either a port ID or a subnet ID\r
+        return Response.status(400).build();\r
+    }\r
+}\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetRequest.java
new file mode 100644 (file)
index 0000000..ab91399
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.northbound;\r
+\r
+import java.util.List;\r
+\r
+import javax.xml.bind.annotation.XmlAccessType;\r
+import javax.xml.bind.annotation.XmlAccessorType;\r
+import javax.xml.bind.annotation.XmlElement;\r
+import javax.xml.bind.annotation.XmlRootElement;\r
+\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
+\r
+@XmlRootElement\r
+@XmlAccessorType(XmlAccessType.NONE)\r
+\r
+public class NeutronSubnetRequest {\r
+    // See OpenStack Network API v2.0 Reference for description of\r
+    // annotated attributes\r
+\r
+    @XmlElement(name="subnet")\r
+    NeutronSubnet singletonSubnet;\r
+\r
+    @XmlElement(name="subnets")\r
+    List<NeutronSubnet> bulkRequest;\r
+\r
+    NeutronSubnetRequest() {\r
+    }\r
+\r
+    NeutronSubnetRequest(List<NeutronSubnet> bulk) {\r
+        bulkRequest = bulk;\r
+        singletonSubnet = null;\r
+    }\r
+\r
+    NeutronSubnetRequest(NeutronSubnet subnet) {\r
+        singletonSubnet = subnet;\r
+    }\r
+\r
+    public NeutronSubnet getSingleton() {\r
+        return singletonSubnet;\r
+    }\r
+\r
+    public List<NeutronSubnet> getBulk() {\r
+        return bulkRequest;\r
+    }\r
+\r
+    public boolean isSingleton() {\r
+        return (singletonSubnet != null);\r
+    }\r
+}\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetsNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetsNorthbound.java
new file mode 100644 (file)
index 0000000..1aaee93
--- /dev/null
@@ -0,0 +1,385 @@
+/*\r
+ * Copyright IBM Corporation, 2013.  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.controller.networkconfig.neutron.northbound;\r
+\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import javax.ws.rs.Consumes;\r
+import javax.ws.rs.DELETE;\r
+import javax.ws.rs.GET;\r
+import javax.ws.rs.POST;\r
+import javax.ws.rs.PUT;\r
+import javax.ws.rs.Path;\r
+import javax.ws.rs.PathParam;\r
+import javax.ws.rs.Produces;\r
+import javax.ws.rs.QueryParam;\r
+import javax.ws.rs.core.MediaType;\r
+import javax.ws.rs.core.Response;\r
+\r
+import org.codehaus.enunciate.jaxrs.ResponseCode;\r
+import org.codehaus.enunciate.jaxrs.StatusCodes;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkAware;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;\r
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
+import org.opendaylight.controller.northbound.commons.RestMessages;\r
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
+import org.opendaylight.controller.sal.utils.ServiceHelper;\r
+\r
+/**\r
+ * Open DOVE Northbound REST APIs.<br>\r
+ * This class provides REST APIs for managing open DOVE internals related to Subnets\r
+ *\r
+ * <br>\r
+ * <br>\r
+ * Authentication scheme : <b>HTTP Basic</b><br>\r
+ * Authentication realm : <b>opendaylight</b><br>\r
+ * Transport : <b>HTTP and HTTPS</b><br>\r
+ * <br>\r
+ * HTTPS Authentication is disabled by default. Administrator can enable it in\r
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
+ * trusted authority.<br>\r
+ * More info :\r
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
+ *\r
+ */\r
+\r
+@Path("/subnets")\r
+public class NeutronSubnetsNorthbound {\r
+\r
+    private NeutronSubnet extractFields(NeutronSubnet o, List<String> fields) {\r
+        return o.extractFields(fields);\r
+    }\r
+\r
+\r
+    /**\r
+     * Returns a list of all Subnets */\r
+    @GET\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackSubnets.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response listSubnets(\r
+            // return fields\r
+            @QueryParam("fields") List<String> fields,\r
+            // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
+            @QueryParam("id") String queryID,\r
+            @QueryParam("network_id") String queryNetworkID,\r
+            @QueryParam("name") String queryName,\r
+            @QueryParam("ip_version") String queryIPVersion,\r
+            @QueryParam("cidr") String queryCIDR,\r
+            @QueryParam("gateway_ip") String queryGatewayIP,\r
+            @QueryParam("enable_dhcp") String queryEnableDHCP,\r
+            @QueryParam("tenant_id") String queryTenantID,\r
+            // pagination\r
+            @QueryParam("limit") String limit,\r
+            @QueryParam("marker") String marker,\r
+            @QueryParam("page_reverse") String pageReverse\r
+            // sorting not supported\r
+            ) {\r
+        INeutronSubnetCRUD subnetInterface = NeutronNBInterfaces.getIfNBSubnetCRUD("default", this);\r
+        if (subnetInterface == null) {\r
+            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        List<NeutronSubnet> allNetworks = subnetInterface.getAllSubnets();\r
+        List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();\r
+        Iterator<NeutronSubnet> i = allNetworks.iterator();\r
+        while (i.hasNext()) {\r
+            NeutronSubnet oSS = i.next();\r
+            if ((queryID == null || queryID.equals(oSS.getID())) &&\r
+                    (queryNetworkID == null || queryNetworkID.equals(oSS.getNetworkUUID())) &&\r
+                    (queryName == null || queryName.equals(oSS.getName())) &&\r
+                    (queryIPVersion == null || queryIPVersion.equals(oSS.getIpVersion())) &&\r
+                    (queryCIDR == null || queryCIDR.equals(oSS.getCidr())) &&\r
+                    (queryGatewayIP == null || queryGatewayIP.equals(oSS.getGatewayIP())) &&\r
+                    (queryEnableDHCP == null || queryEnableDHCP.equals(oSS.getEnableDHCP())) &&\r
+                    (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {\r
+                if (fields.size() > 0)\r
+                    ans.add(extractFields(oSS,fields));\r
+                else\r
+                    ans.add(oSS);\r
+            }\r
+        }\r
+        //TODO: apply pagination to results\r
+        return Response.status(200).entity(\r
+                new NeutronSubnetRequest(ans)).build();\r
+    }\r
+\r
+    /**\r
+     * Returns a specific Subnet */\r
+\r
+    @Path("{subnetUUID}")\r
+    @GET\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackSubnets.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response showSubnet(\r
+            @PathParam("subnetUUID") String subnetUUID,\r
+            // return fields\r
+            @QueryParam("fields") List<String> fields) {\r
+        INeutronSubnetCRUD subnetInterface = NeutronNBInterfaces.getIfNBSubnetCRUD("default",this);\r
+        if (subnetInterface == null) {\r
+            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        if (!subnetInterface.subnetExists(subnetUUID))\r
+            return Response.status(404).build();\r
+        if (fields.size() > 0) {\r
+            NeutronSubnet ans = subnetInterface.getSubnet(subnetUUID);\r
+            return Response.status(200).entity(\r
+                    new NeutronSubnetRequest(extractFields(ans, fields))).build();\r
+        } else\r
+            return Response.status(200).entity(\r
+                    new NeutronSubnetRequest(subnetInterface.getSubnet(subnetUUID))).build();\r
+    }\r
+\r
+    /**\r
+     * Creates new Subnets */\r
+\r
+    @POST\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    @Consumes({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackSubnets.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 201, condition = "Created"),\r
+            @ResponseCode(code = 400, condition = "Bad Request"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 403, condition = "Forbidden"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 409, condition = "Conflict"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response createSubnets(final NeutronSubnetRequest input) {\r
+        INeutronSubnetCRUD subnetInterface = NeutronNBInterfaces.getIfNBSubnetCRUD("default",this);\r
+        if (subnetInterface == null) {\r
+            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        INeutronNetworkCRUD networkInterface = NeutronNBInterfaces.getIfNBNetworkCRUD("default", this);\r
+        if (networkInterface == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+        if (input.isSingleton()) {\r
+            NeutronSubnet singleton = input.getSingleton();\r
+\r
+            /*\r
+             *  Verify that the subnet doesn't already exist (Issue: is a deeper check necessary?)\r
+             *  the specified network exists, the subnet has a valid network address,\r
+             *  and that the gateway IP doesn't overlap with the allocation pools\r
+             *  *then* add the subnet to the cache\r
+             */\r
+            if (subnetInterface.subnetExists(singleton.getID()))\r
+                return Response.status(400).build();\r
+            if (!networkInterface.networkExists(singleton.getNetworkUUID()))\r
+                return Response.status(404).build();\r
+            if (!singleton.isValidCIDR())\r
+                return Response.status(400).build();\r
+            singleton.initDefaults();\r
+            if (singleton.gatewayIP_Pool_overlap())\r
+                return Response.status(409).build();\r
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
+            if (instances != null) {\r
+                for (Object instance : instances) {\r
+                    INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
+                    int status = service.canCreateSubnet(singleton);\r
+                    if (status < 200 || status > 299)\r
+                        return Response.status(status).build();\r
+                }\r
+            }\r
+            subnetInterface.addSubnet(singleton);\r
+            if (instances != null) {\r
+                for (Object instance : instances) {\r
+                    INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
+                    service.neutronSubnetCreated(singleton);\r
+                }\r
+            }\r
+        } else {\r
+            List<NeutronSubnet> bulk = input.getBulk();\r
+            Iterator<NeutronSubnet> i = bulk.iterator();\r
+            HashMap<String, NeutronSubnet> testMap = new HashMap<String, NeutronSubnet>();\r
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
+            while (i.hasNext()) {\r
+                NeutronSubnet test = i.next();\r
+\r
+                /*\r
+                 *  Verify that the subnet doesn't already exist (Issue: is a deeper check necessary?)\r
+                 *  the specified network exists, the subnet has a valid network address,\r
+                 *  and that the gateway IP doesn't overlap with the allocation pools,\r
+                 *  and that the bulk request doesn't already contain a subnet with this id\r
+                 */\r
+\r
+                test.initDefaults();\r
+                if (subnetInterface.subnetExists(test.getID()))\r
+                    return Response.status(400).build();\r
+                if (testMap.containsKey(test.getID()))\r
+                    return Response.status(400).build();\r
+                testMap.put(test.getID(), test);\r
+                if (!networkInterface.networkExists(test.getNetworkUUID()))\r
+                    return Response.status(404).build();\r
+                if (!test.isValidCIDR())\r
+                    return Response.status(400).build();\r
+                if (test.gatewayIP_Pool_overlap())\r
+                    return Response.status(409).build();\r
+                if (instances != null) {\r
+                    for (Object instance : instances) {\r
+                        INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
+                        int status = service.canCreateSubnet(test);\r
+                        if (status < 200 || status > 299)\r
+                            return Response.status(status).build();\r
+                    }\r
+                }\r
+            }\r
+\r
+            /*\r
+             * now, each element of the bulk request can be added to the cache\r
+             */\r
+            i = bulk.iterator();\r
+            while (i.hasNext()) {\r
+                NeutronSubnet test = i.next();\r
+                subnetInterface.addSubnet(test);\r
+                if (instances != null) {\r
+                    for (Object instance : instances) {\r
+                        INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
+                        service.neutronSubnetCreated(test);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return Response.status(201).entity(input).build();\r
+    }\r
+\r
+    /**\r
+     * Updates a Subnet */\r
+\r
+    @Path("{subnetUUID}")\r
+    @PUT\r
+    @Produces({ MediaType.APPLICATION_JSON })\r
+    @Consumes({ MediaType.APPLICATION_JSON })\r
+    //@TypeHint(OpenStackSubnets.class)\r
+    @StatusCodes({\r
+            @ResponseCode(code = 200, condition = "Operation successful"),\r
+            @ResponseCode(code = 400, condition = "Bad Request"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 403, condition = "Forbidden"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response updateSubnet(\r
+            @PathParam("subnetUUID") String subnetUUID, final NeutronSubnetRequest input\r
+            ) {\r
+        INeutronSubnetCRUD subnetInterface = NeutronNBInterfaces.getIfNBSubnetCRUD("default", this);\r
+        if (subnetInterface == null) {\r
+            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        /*\r
+         * verify the subnet exists and there is only one delta provided\r
+         */\r
+        if (!subnetInterface.subnetExists(subnetUUID))\r
+            return Response.status(404).build();\r
+        if (!input.isSingleton())\r
+            return Response.status(400).build();\r
+        NeutronSubnet delta = input.getSingleton();\r
+        NeutronSubnet original = subnetInterface.getSubnet(subnetUUID);\r
+\r
+        /*\r
+         * updates restricted by Neutron\r
+         */\r
+        if (delta.getID() != null || delta.getTenantID() != null ||\r
+                delta.getIpVersion() != null || delta.getCidr() != null ||\r
+                delta.getAllocationPools() != null)\r
+            return Response.status(400).build();\r
+\r
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
+                int status = service.canUpdateSubnet(delta, original);\r
+                if (status < 200 || status > 299)\r
+                    return Response.status(status).build();\r
+            }\r
+        }\r
+\r
+        /*\r
+         * update the object and return it\r
+         */\r
+        subnetInterface.updateSubnet(subnetUUID, delta);\r
+        NeutronSubnet updatedSubnet = subnetInterface.getSubnet(subnetUUID);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
+                service.neutronSubnetUpdated(updatedSubnet);\r
+            }\r
+        }\r
+        return Response.status(200).entity(\r
+                new NeutronSubnetRequest(subnetInterface.getSubnet(subnetUUID))).build();\r
+    }\r
+\r
+    /**\r
+     * Deletes a Subnet */\r
+\r
+    @Path("{subnetUUID}")\r
+    @DELETE\r
+    @StatusCodes({\r
+            @ResponseCode(code = 204, condition = "No Content"),\r
+            @ResponseCode(code = 401, condition = "Unauthorized"),\r
+            @ResponseCode(code = 404, condition = "Not Found"),\r
+            @ResponseCode(code = 409, condition = "Conflict"),\r
+            @ResponseCode(code = 501, condition = "Not Implemented") })\r
+    public Response deleteSubnet(\r
+            @PathParam("subnetUUID") String subnetUUID) {\r
+        INeutronSubnetCRUD subnetInterface = NeutronNBInterfaces.getIfNBSubnetCRUD("default", this);\r
+        if (subnetInterface == null) {\r
+            throw new ServiceUnavailableException("Network CRUD Interface "\r
+                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
+        }\r
+\r
+        /*\r
+         * verify the subnet exists and it isn't currently in use\r
+         */\r
+        if (!subnetInterface.subnetExists(subnetUUID))\r
+            return Response.status(404).build();\r
+        if (subnetInterface.subnetInUse(subnetUUID))\r
+            return Response.status(409).build();\r
+        NeutronSubnet singleton = subnetInterface.getSubnet(subnetUUID);\r
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
+                int status = service.canDeleteSubnet(singleton);\r
+                if (status < 200 || status > 299)\r
+                    return Response.status(status).build();\r
+            }\r
+        }\r
+\r
+        /*\r
+         * remove it and return 204 status\r
+         */\r
+        subnetInterface.removeSubnet(subnetUUID);\r
+        if (instances != null) {\r
+            for (Object instance : instances) {\r
+                INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
+                service.neutronSubnetDeleted(singleton);\r
+            }\r
+        }\r
+        return Response.status(204).build();\r
+    }\r
+}\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/resources/WEB-INF/web.xml b/opendaylight/northbound/networkconfiguration/neutron/src/main/resources/WEB-INF/web.xml
new file mode 100644 (file)
index 0000000..dccd133
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>\r
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"\r
+        version="3.0">\r
+  <servlet>\r
+    <servlet-name>JAXRSNeutron</servlet-name>\r
+    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>\r
+    <init-param>\r
+      <param-name>javax.ws.rs.Application</param-name>\r
+      <param-value>org.opendaylight.controller.networkconfig.neutron.northbound.NeutronNorthboundRSApplication</param-value>\r
+    </init-param>\r
+    <load-on-startup>1</load-on-startup>\r
+  </servlet>\r
+\r
+  <servlet-mapping>\r
+    <servlet-name>JAXRSNeutron</servlet-name>\r
+    <url-pattern>/*</url-pattern>\r
+  </servlet-mapping>\r
+        <security-constraint>\r
+                <web-resource-collection>\r
+                        <web-resource-name>NB api</web-resource-name>\r
+                        <url-pattern>/*</url-pattern>\r
+                </web-resource-collection>\r
+                <auth-constraint>\r
+                        <role-name>System-Admin</role-name>\r
+                        <role-name>Network-Admin</role-name>\r
+                        <role-name>Network-Operator</role-name>\r
+                        <role-name>Container-User</role-name>\r
+                </auth-constraint>\r
+        </security-constraint>\r
+\r
+        <security-role>\r
+                <role-name>System-Admin</role-name>\r
+        </security-role>\r
+        <security-role>\r
+                <role-name>Network-Admin</role-name>\r
+        </security-role>\r
+        <security-role>\r
+                <role-name>Network-Operator</role-name>\r
+        </security-role>\r
+        <security-role>\r
+                <role-name>Container-User</role-name>\r
+        </security-role>\r
+\r
+        <login-config>\r
+                <auth-method>BASIC</auth-method>\r
+                <realm-name>opendaylight</realm-name>\r
+        </login-config>\r
+</web-app>\r
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/resources/org/opendaylight/controller/networkconfig/neutron/northbound/jaxb.properties b/opendaylight/northbound/networkconfiguration/neutron/src/main/resources/org/opendaylight/controller/networkconfig/neutron/northbound/jaxb.properties
new file mode 100644 (file)
index 0000000..5837a4c
--- /dev/null
@@ -0,0 +1 @@
+javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
\ No newline at end of file