Replace original Windows line delimiters.
Change-Id: I4dada1270d6d0e656a5b899ef8337c545c57c7ea
Signed-off-by: Ryan Moats <rmoats@us.ibm.com>
-/*\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
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronFloatingIPRequest {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="floatingip")
+ NeutronFloatingIP singletonFloatingIP;
+
+ @XmlElement(name="floatingips")
+ List<NeutronFloatingIP> bulkRequest;
+
+ NeutronFloatingIPRequest() {
+ }
+
+ NeutronFloatingIPRequest(List<NeutronFloatingIP> bulk) {
+ bulkRequest = bulk;
+ singletonFloatingIP = null;
+ }
+
+ NeutronFloatingIPRequest(NeutronFloatingIP singleton) {
+ bulkRequest = null;
+ singletonFloatingIP = singleton;
+ }
+
+ public NeutronFloatingIP getSingleton() {
+ return singletonFloatingIP;
+ }
+
+ public boolean isSingleton() {
+ return (singletonFloatingIP != null);
+ }
+}
-/*\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.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.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 = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(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 = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(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 = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);\r
- if (floatingIPInterface == null) {\r
- throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
- if (networkInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
- if (subnetInterface == null) {\r
- throw new ServiceUnavailableException("Subnet CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD( 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 = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);\r
- if (floatingIPInterface == null) {\r
- throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
- if (networkInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
- if (subnetInterface == null) {\r
- throw new ServiceUnavailableException("Subnet CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD( 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 = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(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
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Open DOVE Northbound REST APIs.<br>
+ * This class provides REST APIs for managing the open DOVE
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/floatingips")
+public class NeutronFloatingIPsNorthbound {
+
+ private NeutronFloatingIP extractFields(NeutronFloatingIP o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all FloatingIPs */
+
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response listFloatingIPs(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("floating_network_id") String queryFloatingNetworkId,
+ @QueryParam("port_id") String queryPortId,
+ @QueryParam("fixed_ip_address") String queryFixedIPAddress,
+ @QueryParam("floating_ip_address") String queryFloatingIPAddress,
+ @QueryParam("tenant_id") String queryTenantID,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+ if (floatingIPInterface == null) {
+ throw new ServiceUnavailableException("Floating IP CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronFloatingIP> allFloatingIPs = floatingIPInterface.getAllFloatingIPs();
+ List<NeutronFloatingIP> ans = new ArrayList<NeutronFloatingIP>();
+ Iterator<NeutronFloatingIP> i = allFloatingIPs.iterator();
+ while (i.hasNext()) {
+ NeutronFloatingIP oSS = i.next();
+ //match filters: TODO provider extension and router extension
+ if ((queryID == null || queryID.equals(oSS.getID())) &&
+ (queryFloatingNetworkId == null || queryFloatingNetworkId.equals(oSS.getFloatingNetworkUUID())) &&
+ (queryPortId == null || queryPortId.equals(oSS.getPortUUID())) &&
+ (queryFixedIPAddress == null || queryFixedIPAddress.equals(oSS.getFixedIPAddress())) &&
+ (queryFloatingIPAddress == null || queryFloatingIPAddress.equals(oSS.getFloatingIPAddress())) &&
+ (queryTenantID == null || queryTenantID.equals(oSS.getTenantUUID()))) {
+ if (fields.size() > 0)
+ ans.add(extractFields(oSS,fields));
+ else
+ ans.add(oSS);
+ }
+ }
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronFloatingIPRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific FloatingIP */
+
+ @Path("{floatingipUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response showFloatingIP(
+ @PathParam("floatingipUUID") String floatingipUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields ) {
+ INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+ if (floatingIPInterface == null) {
+ throw new ServiceUnavailableException("Floating IP CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!floatingIPInterface.floatingIPExists(floatingipUUID))
+ return Response.status(404).build();
+ if (fields.size() > 0) {
+ NeutronFloatingIP ans = floatingIPInterface.getFloatingIP(floatingipUUID);
+ return Response.status(200).entity(
+ new NeutronFloatingIPRequest(extractFields(ans, fields))).build();
+ } else
+ return Response.status(200).entity(
+ new NeutronFloatingIPRequest(floatingIPInterface.getFloatingIP(floatingipUUID))).build();
+
+ }
+
+ /**
+ * Creates new FloatingIPs */
+
+ @POST
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "Created"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response createFloatingIPs(final NeutronFloatingIPRequest input) {
+ INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+ if (floatingIPInterface == null) {
+ throw new ServiceUnavailableException("Floating IP CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD( this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronFloatingIP singleton = input.getSingleton();
+ // check existence of id in cache and return badrequest if exists
+ if (floatingIPInterface.floatingIPExists(singleton.getID()))
+ return Response.status(400).build();
+ // check if the external network is specified, exists, and is an external network
+ String externalNetworkUUID = singleton.getFloatingNetworkUUID();
+ if (externalNetworkUUID == null)
+ return Response.status(400).build();
+ if (!networkInterface.networkExists(externalNetworkUUID))
+ return Response.status(400).build();
+ NeutronNetwork externNetwork = networkInterface.getNetwork(externalNetworkUUID);
+ if (!externNetwork.isRouterExternal())
+ return Response.status(400).build();
+ // if floating IP is specified, make sure it can come from the network
+ String floatingIP = singleton.getFloatingIPAddress();
+ if (floatingIP != null) {
+ if (externNetwork.getSubnets().size() > 1)
+ return Response.status(400).build();
+ NeutronSubnet externSubnet = subnetInterface.getSubnet(externNetwork.getSubnets().get(0));
+ if (!externSubnet.isValidIP(floatingIP))
+ return Response.status(400).build();
+ if (externSubnet.isIPInUse(floatingIP))
+ return Response.status(409).build();
+ }
+ // if port_id is specified, then check that the port exists and has at least one IP
+ String port_id = singleton.getPortUUID();
+ if (port_id != null) {
+ String fixedIP = null; // used for the fixedIP calculation
+ if (!portInterface.portExists(port_id))
+ return Response.status(404).build();
+ NeutronPort port = portInterface.getPort(port_id);
+ if (port.getFixedIPs().size() < 1)
+ return Response.status(400).build();
+ // if there is more than one fixed IP then check for fixed_ip_address
+ // and that it is in the list of port addresses
+ if (port.getFixedIPs().size() > 1) {
+ fixedIP = singleton.getFixedIPAddress();
+ if (fixedIP == null)
+ return Response.status(400).build();
+ Iterator<Neutron_IPs> i = port.getFixedIPs().iterator();
+ boolean validFixedIP = false;
+ while (i.hasNext() && !validFixedIP) {
+ Neutron_IPs ip = i.next();
+ if (ip.getIpAddress().equals(fixedIP))
+ validFixedIP = true;
+ }
+ if (!validFixedIP)
+ return Response.status(400).build();
+ } else {
+ fixedIP = port.getFixedIPs().get(0).getIpAddress();
+ if (singleton.getFixedIPAddress() != null && !fixedIP.equalsIgnoreCase(singleton.getFixedIPAddress()))
+ return Response.status(400).build();
+ }
+ //lastly check that this fixed IP address isn't already used
+ if (port.isBoundToFloatingIP(fixedIP))
+ return Response.status(409).build();
+ singleton.setFixedIPAddress(fixedIP);
+ }
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ int status = service.canCreateFloatingIP(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ floatingIPInterface.addFloatingIP(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ service.neutronFloatingIPCreated(singleton);
+ }
+ }
+ } else {
+ return Response.status(400).build();
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a FloatingIP */
+
+ @Path("{floatingipUUID}")
+ @PUT
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response updateFloatingIP(
+ @PathParam("floatingipUUID") String floatingipUUID,
+ NeutronFloatingIPRequest input
+ ) {
+ INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+ if (floatingIPInterface == null) {
+ throw new ServiceUnavailableException("Floating IP CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD( this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!floatingIPInterface.floatingIPExists(floatingipUUID))
+ return Response.status(404).build();
+
+ NeutronFloatingIP sourceFloatingIP = floatingIPInterface.getFloatingIP(floatingipUUID);
+ if (!input.isSingleton())
+ return Response.status(400).build();
+ NeutronFloatingIP singleton = input.getSingleton();
+ if (singleton.getID() != null)
+ return Response.status(400).build();
+
+ NeutronNetwork externNetwork = networkInterface.getNetwork(
+ sourceFloatingIP.getFloatingNetworkUUID());
+
+ // if floating IP is specified, make sure it can come from the network
+ String floatingIP = singleton.getFloatingIPAddress();
+ if (floatingIP != null) {
+ if (externNetwork.getSubnets().size() > 1)
+ return Response.status(400).build();
+ NeutronSubnet externSubnet = subnetInterface.getSubnet(externNetwork.getSubnets().get(0));
+ if (!externSubnet.isValidIP(floatingIP))
+ return Response.status(400).build();
+ if (externSubnet.isIPInUse(floatingIP))
+ return Response.status(409).build();
+ }
+
+ // if port_id is specified, then check that the port exists and has at least one IP
+ String port_id = singleton.getPortUUID();
+ if (port_id != null) {
+ String fixedIP = null; // used for the fixedIP calculation
+ if (!portInterface.portExists(port_id))
+ return Response.status(404).build();
+ NeutronPort port = portInterface.getPort(port_id);
+ if (port.getFixedIPs().size() < 1)
+ return Response.status(400).build();
+ // if there is more than one fixed IP then check for fixed_ip_address
+ // and that it is in the list of port addresses
+ if (port.getFixedIPs().size() > 1) {
+ fixedIP = singleton.getFixedIPAddress();
+ if (fixedIP == null)
+ return Response.status(400).build();
+ Iterator<Neutron_IPs> i = port.getFixedIPs().iterator();
+ boolean validFixedIP = false;
+ while (i.hasNext() && !validFixedIP) {
+ Neutron_IPs ip = i.next();
+ if (ip.getIpAddress().equals(fixedIP))
+ validFixedIP = true;
+ }
+ if (!validFixedIP)
+ return Response.status(400).build();
+ } else {
+ fixedIP = port.getFixedIPs().get(0).getIpAddress();
+ if (singleton.getFixedIPAddress() != null &&
+ !fixedIP.equalsIgnoreCase(singleton.getFixedIPAddress()))
+ return Response.status(400).build();
+ }
+ //lastly check that this fixed IP address isn't already used
+ if (port.isBoundToFloatingIP(fixedIP))
+ return Response.status(409).build();
+ singleton.setFixedIPAddress(fixedIP);
+ }
+ NeutronFloatingIP target = floatingIPInterface.getFloatingIP(floatingipUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ int status = service.canUpdateFloatingIP(singleton, target);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ floatingIPInterface.updateFloatingIP(floatingipUUID, singleton);
+ target = floatingIPInterface.getFloatingIP(floatingipUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ service.neutronFloatingIPUpdated(target);
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronFloatingIPRequest(target)).build();
+
+ }
+
+ /**
+ * Deletes a FloatingIP */
+
+ @Path("{floatingipUUID}")
+ @DELETE
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "No Content"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response deleteFloatingIP(
+ @PathParam("floatingipUUID") String floatingipUUID) {
+ INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+ if (floatingIPInterface == null) {
+ throw new ServiceUnavailableException("Floating IP CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!floatingIPInterface.floatingIPExists(floatingipUUID))
+ return Response.status(404).build();
+ // TODO: need to undo port association if it exists
+ NeutronFloatingIP singleton = floatingIPInterface.getFloatingIP(floatingipUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ int status = service.canDeleteFloatingIP(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ floatingIPInterface.removeFloatingIP(floatingipUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+ service.neutronFloatingIPDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
-/*\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
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronNetworkRequest {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="network")
+ NeutronNetwork singletonNetwork;
+
+ @XmlElement(name="networks")
+ List<NeutronNetwork> bulkRequest;
+
+ NeutronNetworkRequest() {
+ }
+
+ NeutronNetworkRequest(List<NeutronNetwork> bulk) {
+ bulkRequest = bulk;
+ singletonNetwork = null;
+ }
+
+ NeutronNetworkRequest(NeutronNetwork net) {
+ singletonNetwork = net;
+ }
+
+ public NeutronNetwork getSingleton() {
+ return singletonNetwork;
+ }
+
+ public boolean isSingleton() {
+ return (singletonNetwork != null);
+ }
+
+ public List<NeutronNetwork> getBulk() {
+ return bulkRequest;
+ }
+}
-/*\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.NeutronCRUDInterfaces;\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 = NeutronCRUDInterfaces.getINeutronNetworkCRUD( 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 = Boolean.valueOf(queryAdminStateUp);\r
- if (queryShared != null)\r
- bShared = Boolean.valueOf(queryShared);\r
- if (queryRouterExternal != null)\r
- bRouterExternal = Boolean.valueOf(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 = NeutronCRUDInterfaces.getINeutronNetworkCRUD( 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 = NeutronCRUDInterfaces.getINeutronNetworkCRUD( 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 = NeutronCRUDInterfaces.getINeutronNetworkCRUD( 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 = NeutronCRUDInterfaces.getINeutronNetworkCRUD( 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
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.codehaus.enunciate.jaxrs.TypeHint;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Open DOVE Northbound REST APIs for Network.<br>
+ * This class provides REST APIs for managing open DOVE internals related to Networks
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/networks")
+public class NeutronNetworksNorthbound {
+
+ private NeutronNetwork extractFields(NeutronNetwork o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all Networks */
+
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackNetworks.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized") })
+ public Response listNetworks(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("name") String queryName,
+ @QueryParam("admin_state_up") String queryAdminStateUp,
+ @QueryParam("status") String queryStatus,
+ @QueryParam("shared") String queryShared,
+ @QueryParam("tenant_id") String queryTenantID,
+ @QueryParam("router_external") String queryRouterExternal,
+ @QueryParam("provider_network_type") String queryProviderNetworkType,
+ @QueryParam("provider_physical_network") String queryProviderPhysicalNetwork,
+ @QueryParam("provider_segmentation_id") String queryProviderSegmentationID,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronNetwork> allNetworks = networkInterface.getAllNetworks();
+ List<NeutronNetwork> ans = new ArrayList<NeutronNetwork>();
+ Iterator<NeutronNetwork> i = allNetworks.iterator();
+ while (i.hasNext()) {
+ NeutronNetwork oSN = i.next();
+ //match filters: TODO provider extension
+ Boolean bAdminStateUp = null;
+ Boolean bShared = null;
+ Boolean bRouterExternal = null;
+ if (queryAdminStateUp != null)
+ bAdminStateUp = Boolean.valueOf(queryAdminStateUp);
+ if (queryShared != null)
+ bShared = Boolean.valueOf(queryShared);
+ if (queryRouterExternal != null)
+ bRouterExternal = Boolean.valueOf(queryRouterExternal);
+ if ((queryID == null || queryID.equals(oSN.getID())) &&
+ (queryName == null || queryName.equals(oSN.getNetworkName())) &&
+ (bAdminStateUp == null || bAdminStateUp.booleanValue() == oSN.isAdminStateUp()) &&
+ (queryStatus == null || queryStatus.equals(oSN.getStatus())) &&
+ (bShared == null || bShared.booleanValue() == oSN.isShared()) &&
+ (bRouterExternal == null || bRouterExternal.booleanValue() == oSN.isRouterExternal()) &&
+ (queryTenantID == null || queryTenantID.equals(oSN.getTenantID()))) {
+ if (fields.size() > 0)
+ ans.add(extractFields(oSN,fields));
+ else
+ ans.add(oSN);
+ }
+ }
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronNetworkRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Network */
+
+ @Path("{netUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackNetworks.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found") })
+ public Response showNetwork(
+ @PathParam("netUUID") String netUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields
+ ) {
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!networkInterface.networkExists(netUUID))
+ return Response.status(404).build();
+ if (fields.size() > 0) {
+ NeutronNetwork ans = networkInterface.getNetwork(netUUID);
+ return Response.status(200).entity(
+ new NeutronNetworkRequest(extractFields(ans, fields))).build();
+ } else
+ return Response.status(200).entity(
+ new NeutronNetworkRequest(networkInterface.getNetwork(netUUID))).build();
+ }
+
+ /**
+ * Creates new Networks */
+ @POST
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ @TypeHint(NeutronNetwork.class)
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "Created"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized") })
+ public Response createNetworks(final NeutronNetworkRequest input) {
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronNetwork singleton = input.getSingleton();
+
+ /*
+ * network ID can't already exist
+ */
+ if (networkInterface.networkExists(singleton.getID()))
+ return Response.status(400).build();
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ int status = service.canCreateNetwork(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+
+ // add network to cache
+ networkInterface.addNetwork(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ service.neutronNetworkCreated(singleton);
+ }
+ }
+
+ } else {
+ List<NeutronNetwork> bulk = input.getBulk();
+ Iterator<NeutronNetwork> i = bulk.iterator();
+ HashMap<String, NeutronNetwork> testMap = new HashMap<String, NeutronNetwork>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronNetwork test = i.next();
+
+ /*
+ * network ID can't already exist, nor can there be an entry for this UUID
+ * already in this bulk request
+ */
+ if (networkInterface.networkExists(test.getID()))
+ return Response.status(400).build();
+ if (testMap.containsKey(test.getID()))
+ return Response.status(400).build();
+ if (instances != null) {
+ for (Object instance: instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ int status = service.canCreateNetwork(test);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ testMap.put(test.getID(),test);
+ }
+
+ // now that everything passed, add items to the cache
+ i = bulk.iterator();
+ while (i.hasNext()) {
+ NeutronNetwork test = i.next();
+ test.initDefaults();
+ networkInterface.addNetwork(test);
+ if (instances != null) {
+ for (Object instance: instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ service.neutronNetworkCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a Network */
+ @Path("{netUUID}")
+ @PUT
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackNetworks.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"), })
+ public Response updateNetwork(
+ @PathParam("netUUID") String netUUID, final NeutronNetworkRequest input
+ ) {
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * network has to exist and only a single delta is supported
+ */
+ if (!networkInterface.networkExists(netUUID))
+ return Response.status(404).build();
+ if (!input.isSingleton())
+ return Response.status(400).build();
+ NeutronNetwork delta = input.getSingleton();
+
+ /*
+ * transitions forbidden by Neutron
+ */
+ if (delta.getID() != null || delta.getTenantID() != null ||
+ delta.getStatus() != null)
+ return Response.status(400).build();
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ NeutronNetwork original = networkInterface.getNetwork(netUUID);
+ int status = service.canUpdateNetwork(delta, original);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+
+ // update network object and return the modified object
+ networkInterface.updateNetwork(netUUID, delta);
+ NeutronNetwork updatedSingleton = networkInterface.getNetwork(netUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ service.neutronNetworkUpdated(updatedSingleton);
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronNetworkRequest(networkInterface.getNetwork(netUUID))).build();
+ }
+
+ /**
+ * Deletes a Network */
+
+ @Path("{netUUID}")
+ @DELETE
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "No Content"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Network In Use") })
+ public Response deleteNetwork(
+ @PathParam("netUUID") String netUUID) {
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * network has to exist and not be in use before it can be removed
+ */
+ if (!networkInterface.networkExists(netUUID))
+ return Response.status(404).build();
+ if (networkInterface.networkInUse(netUUID))
+ return Response.status(409).build();
+
+ NeutronNetwork singleton = networkInterface.getNetwork(netUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ int status = service.canDeleteNetwork(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ networkInterface.removeNetwork(netUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ service.neutronNetworkDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
-/*\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
-\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
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.core.Application;
+import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;
+
+
+/**
+ * This class is an instance of javax.ws.rs.core.Application and is used to return the classes
+ * that will be instantiated for JAXRS processing. This is necessary
+ * because package scanning in jersey doesn't yet work in OSGi environment.
+ *
+ */
+public class NeutronNorthboundRSApplication extends Application {
+ @Override
+ public Set<Class<?>> getClasses() {
+ Set<Class<?>> classes = new HashSet<Class<?>>();
+// northbound URIs
+ classes.add(NeutronNetworksNorthbound.class);
+ classes.add(NeutronSubnetsNorthbound.class);
+ classes.add(NeutronPortsNorthbound.class);
+ classes.add(NeutronRoutersNorthbound.class);
+ classes.add(NeutronFloatingIPsNorthbound.class);
+ return classes;
+ }
+
+ @Override
+ public Set<Object> getSingletons() {
+ MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider();
+
+ moxyJsonProvider.setAttributePrefix("@");
+ moxyJsonProvider.setFormattedOutput(true);
+ moxyJsonProvider.setIncludeRoot(false);
+ moxyJsonProvider.setMarshalEmptyCollections(true);
+ moxyJsonProvider.setValueWrapper("$");
+
+ Map<String, String> namespacePrefixMapper = new HashMap<String, String>(1);
+ namespacePrefixMapper.put("router", "router"); // FIXME: fill in with XSD
+ namespacePrefixMapper.put("provider", "provider"); // FIXME: fill in with XSD
+ moxyJsonProvider.setNamespacePrefixMapper(namespacePrefixMapper);
+ moxyJsonProvider.setNamespaceSeparator(':');
+
+ HashSet<Object> set = new HashSet<Object>(1);
+ set.add(moxyJsonProvider);
+ return set;
+ }
+}
-/*\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
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronPortRequest {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="port")
+ NeutronPort singletonPort;
+
+ @XmlElement(name="ports")
+ List<NeutronPort> bulkRequest;
+
+ NeutronPortRequest() {
+ }
+
+ NeutronPortRequest(List<NeutronPort> bulk) {
+ bulkRequest = bulk;
+ singletonPort = null;
+ }
+
+ NeutronPortRequest(NeutronPort port) {
+ singletonPort = port;
+ }
+
+ public NeutronPort getSingleton() {
+ return singletonPort;
+ }
+
+ public boolean isSingleton() {
+ return (singletonPort != null);
+ }
+
+ public List<NeutronPort> getBulk() {
+ return bulkRequest;
+ }
+}
-/*\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.NeutronCRUDInterfaces;\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 = NeutronCRUDInterfaces.getINeutronPortCRUD(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 = NeutronCRUDInterfaces.getINeutronPortCRUD(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 = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
- if (portInterface == null) {\r
- throw new ServiceUnavailableException("Port CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
- if (networkInterface == null) {\r
- throw new ServiceUnavailableException("Network CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( 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 = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
- if (portInterface == null) {\r
- throw new ServiceUnavailableException("Port CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( 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 = NeutronCRUDInterfaces.getINeutronPortCRUD(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
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Open DOVE Northbound REST APIs.<br>
+ * This class provides REST APIs for managing the open DOVE
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/ports")
+public class NeutronPortsNorthbound {
+
+ private NeutronPort extractFields(NeutronPort o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all Ports */
+
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackPorts.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response listPorts(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("network_id") String queryNetworkID,
+ @QueryParam("name") String queryName,
+ @QueryParam("admin_state_up") String queryAdminStateUp,
+ @QueryParam("status") String queryStatus,
+ @QueryParam("mac_address") String queryMACAddress,
+ @QueryParam("device_id") String queryDeviceID,
+ @QueryParam("device_owner") String queryDeviceOwner,
+ @QueryParam("tenant_id") String queryTenantID,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronPort> allPorts = portInterface.getAllPorts();
+ List<NeutronPort> ans = new ArrayList<NeutronPort>();
+ Iterator<NeutronPort> i = allPorts.iterator();
+ while (i.hasNext()) {
+ NeutronPort oSS = i.next();
+ if ((queryID == null || queryID.equals(oSS.getID())) &&
+ (queryNetworkID == null || queryNetworkID.equals(oSS.getNetworkUUID())) &&
+ (queryName == null || queryName.equals(oSS.getName())) &&
+ (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&
+ (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&
+ (queryMACAddress == null || queryMACAddress.equals(oSS.getMacAddress())) &&
+ (queryDeviceID == null || queryDeviceID.equals(oSS.getDeviceID())) &&
+ (queryDeviceOwner == null || queryDeviceOwner.equals(oSS.getDeviceOwner())) &&
+ (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {
+ if (fields.size() > 0)
+ ans.add(extractFields(oSS,fields));
+ else
+ ans.add(oSS);
+ }
+ }
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronPortRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Port */
+
+ @Path("{portUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackPorts.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response showPort(
+ @PathParam("portUUID") String portUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields ) {
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!portInterface.portExists(portUUID))
+ return Response.status(404).build();
+ if (fields.size() > 0) {
+ NeutronPort ans = portInterface.getPort(portUUID);
+ return Response.status(200).entity(
+ new NeutronPortRequest(extractFields(ans, fields))).build();
+ } else
+ return Response.status(200).entity(
+ new NeutronPortRequest(portInterface.getPort(portUUID))).build();
+ }
+
+ /**
+ * Creates new Ports */
+
+ @POST
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackPorts.class)
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "Created"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented"),
+ @ResponseCode(code = 503, condition = "MAC generation failure") })
+ public Response createPorts(final NeutronPortRequest input) {
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronPort singleton = input.getSingleton();
+
+ /*
+ * the port must be part of an existing network, must not already exist,
+ * have a valid MAC and the MAC not be in use
+ */
+ if (singleton.getNetworkUUID() == null)
+ return Response.status(400).build();
+ if (portInterface.portExists(singleton.getID()))
+ return Response.status(400).build();
+ if (!networkInterface.networkExists(singleton.getNetworkUUID()))
+ return Response.status(404).build();
+ if (singleton.getMacAddress() == null ||
+ !singleton.getMacAddress().matches("^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$"))
+ return Response.status(400).build();
+ if (portInterface.macInUse(singleton.getMacAddress()))
+ return Response.status(409).build();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ int status = service.canCreatePort(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ /*
+ * if fixed IPs are specified, each one has to have an existing subnet ID
+ * that is in the same scoping network as the port. In addition, if an IP
+ * address is specified it has to be a valid address for the subnet and not
+ * already in use
+ */
+ List<Neutron_IPs> fixedIPs = singleton.getFixedIPs();
+ if (fixedIPs != null && fixedIPs.size() > 0) {
+ Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();
+ while (fixedIPIterator.hasNext()) {
+ Neutron_IPs ip = fixedIPIterator.next();
+ if (ip.getSubnetUUID() == null)
+ return Response.status(400).build();
+ if (!subnetInterface.subnetExists(ip.getSubnetUUID()))
+ return Response.status(400).build();
+ NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());
+ if (!singleton.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))
+ return Response.status(400).build();
+ if (ip.getIpAddress() != null) {
+ if (!subnet.isValidIP(ip.getIpAddress()))
+ return Response.status(400).build();
+ if (subnet.isIPInUse(ip.getIpAddress()))
+ return Response.status(409).build();
+ }
+ }
+ }
+
+ // add the port to the cache
+ portInterface.addPort(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ service.neutronPortCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronPort> bulk = input.getBulk();
+ Iterator<NeutronPort> i = bulk.iterator();
+ HashMap<String, NeutronPort> testMap = new HashMap<String, NeutronPort>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronPort test = i.next();
+
+ /*
+ * the port must be part of an existing network, must not already exist,
+ * have a valid MAC and the MAC not be in use. Further the bulk request
+ * can't already contain a new port with the same UUID
+ */
+ if (portInterface.portExists(test.getID()))
+ return Response.status(400).build();
+ if (testMap.containsKey(test.getID()))
+ return Response.status(400).build();
+ for (NeutronPort check : testMap.values()) {
+ if (test.getMacAddress().equalsIgnoreCase(check.getMacAddress()))
+ return Response.status(409).build();
+ for (Neutron_IPs test_fixedIP : test.getFixedIPs()) {
+ for (Neutron_IPs check_fixedIP : check.getFixedIPs()) {
+ if (test_fixedIP.getIpAddress().equals(check_fixedIP.getIpAddress()))
+ return Response.status(409).build();
+ }
+ }
+ }
+ testMap.put(test.getID(), test);
+ if (!networkInterface.networkExists(test.getNetworkUUID()))
+ return Response.status(404).build();
+ if (!test.getMacAddress().matches("^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$"))
+ return Response.status(400).build();
+ if (portInterface.macInUse(test.getMacAddress()))
+ return Response.status(409).build();
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ int status = service.canCreatePort(test);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ /*
+ * if fixed IPs are specified, each one has to have an existing subnet ID
+ * that is in the same scoping network as the port. In addition, if an IP
+ * address is specified it has to be a valid address for the subnet and not
+ * already in use (or be the gateway IP address of the subnet)
+ */
+ List<Neutron_IPs> fixedIPs = test.getFixedIPs();
+ if (fixedIPs != null && fixedIPs.size() > 0) {
+ Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();
+ while (fixedIPIterator.hasNext()) {
+ Neutron_IPs ip = fixedIPIterator.next();
+ if (ip.getSubnetUUID() == null)
+ return Response.status(400).build();
+ if (!subnetInterface.subnetExists(ip.getSubnetUUID()))
+ return Response.status(400).build();
+ NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());
+ if (!test.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))
+ return Response.status(400).build();
+ if (ip.getIpAddress() != null) {
+ if (!subnet.isValidIP(ip.getIpAddress()))
+ return Response.status(400).build();
+ //TODO: need to add consideration for a fixed IP being assigned the same address as a allocated IP in the
+ //same bulk create
+ if (subnet.isIPInUse(ip.getIpAddress()))
+ return Response.status(409).build();
+ }
+ }
+ }
+ }
+
+ //once everything has passed, then we can add to the cache
+ i = bulk.iterator();
+ while (i.hasNext()) {
+ NeutronPort test = i.next();
+ portInterface.addPort(test);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ service.neutronPortCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a Port */
+
+ @Path("{portUUID}")
+ @PUT
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackPorts.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response updatePort(
+ @PathParam("portUUID") String portUUID,
+ NeutronPortRequest input
+ ) {
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ // port has to exist and only a single delta is supported
+ if (!portInterface.portExists(portUUID))
+ return Response.status(404).build();
+ NeutronPort target = portInterface.getPort(portUUID);
+ if (!input.isSingleton())
+ return Response.status(400).build();
+ NeutronPort singleton = input.getSingleton();
+ NeutronPort original = portInterface.getPort(portUUID);
+
+ // deltas restricted by Neutron
+ if (singleton.getID() != null || singleton.getTenantID() != null ||
+ singleton.getStatus() != null)
+ return Response.status(400).build();
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ int status = service.canUpdatePort(singleton, original);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+
+ // Verify the new fixed ips are valid
+ List<Neutron_IPs> fixedIPs = singleton.getFixedIPs();
+ if (fixedIPs != null && fixedIPs.size() > 0) {
+ Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();
+ while (fixedIPIterator.hasNext()) {
+ Neutron_IPs ip = fixedIPIterator.next();
+ if (ip.getSubnetUUID() == null)
+ return Response.status(400).build();
+ if (!subnetInterface.subnetExists(ip.getSubnetUUID()))
+ return Response.status(400).build();
+ NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());
+ if (!target.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))
+ return Response.status(400).build();
+ if (ip.getIpAddress() != null) {
+ if (!subnet.isValidIP(ip.getIpAddress()))
+ return Response.status(400).build();
+ if (subnet.isIPInUse(ip.getIpAddress()))
+ return Response.status(409).build();
+ }
+ }
+ }
+
+// TODO: Support change of security groups
+ // update the port and return the modified object
+ portInterface.updatePort(portUUID, singleton);
+ NeutronPort updatedPort = portInterface.getPort(portUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ service.neutronPortUpdated(updatedPort);
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronPortRequest(updatedPort)).build();
+
+ }
+
+ /**
+ * Deletes a Port */
+
+ @Path("{portUUID}")
+ @DELETE
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "No Content"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response deletePort(
+ @PathParam("portUUID") String portUUID) {
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ // port has to exist and not be owned by anyone. then it can be removed from the cache
+ if (!portInterface.portExists(portUUID))
+ return Response.status(404).build();
+ NeutronPort port = portInterface.getPort(portUUID);
+ if (port.getDeviceID() != null ||
+ port.getDeviceOwner() != null)
+ Response.status(403).build();
+ NeutronPort singleton = portInterface.getPort(portUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ int status = service.canDeletePort(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ portInterface.removePort(portUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ service.neutronPortDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
-/*\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
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronRouterRequest {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="router")
+ NeutronRouter singletonRouter;
+
+ @XmlElement(name="routers")
+ List<NeutronRouter> bulkRequest;
+
+ NeutronRouterRequest() {
+ }
+
+ NeutronRouterRequest(List<NeutronRouter> bulk) {
+ bulkRequest = bulk;
+ singletonRouter = null;
+ }
+
+ NeutronRouterRequest(NeutronRouter router) {
+ singletonRouter = router;
+ }
+
+ public List<NeutronRouter> getBulk() {
+ return bulkRequest;
+ }
+
+ public NeutronRouter getSingleton() {
+ return singletonRouter;
+ }
+
+ public boolean isSingleton() {
+ return (singletonRouter != null);
+ }
+}
-/*\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.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.NeutronCRUDInterfaces;\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.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 = NeutronCRUDInterfaces.getINeutronRouterCRUD(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 = NeutronCRUDInterfaces.getINeutronRouterCRUD(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 = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
- if (routerInterface == null) {\r
- throw new ServiceUnavailableException("Router CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( 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 = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
- if (routerInterface == null) {\r
- throw new ServiceUnavailableException("Router CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( 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 = NeutronCRUDInterfaces.getINeutronRouterCRUD(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 = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
- if (routerInterface == null) {\r
- throw new ServiceUnavailableException("Router CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
- if (portInterface == null) {\r
- throw new ServiceUnavailableException("Port CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(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
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- service.canAttachInterface(target, input);\r
- }\r
- }\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
- 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 = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
- if (routerInterface == null) {\r
- throw new ServiceUnavailableException("Router CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
- if (portInterface == null) {\r
- throw new ServiceUnavailableException("Port CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(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
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- service.canDetachInterface(target, input);\r
- }\r
- }\r
-\r
- // reset the port ownership\r
- port.setDeviceID(null);\r
- port.setDeviceOwner(null);\r
-\r
- target.removeInterface(input.getPortUUID());\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
- Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
- if (instances != null) {\r
- for (Object instance : instances) {\r
- INeutronRouterAware service = (INeutronRouterAware) instance;\r
- service.canDetachInterface(target, input);\r
- }\r
- }\r
- port.setDeviceID(null);\r
- port.setDeviceOwner(null);\r
- target.removeInterface(input.getPortUUID());\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
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronRouterAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter_Interface;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+
+/**
+ * Open DOVE Northbound REST APIs.<br>
+ * This class provides REST APIs for managing the open DOVE
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/routers")
+public class NeutronRoutersNorthbound {
+
+ private NeutronRouter extractFields(NeutronRouter o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all Routers */
+
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackRouters.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response listRouters(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("name") String queryName,
+ @QueryParam("admin_state_up") String queryAdminStateUp,
+ @QueryParam("status") String queryStatus,
+ @QueryParam("tenant_id") String queryTenantID,
+ @QueryParam("external_gateway_info") String queryExternalGatewayInfo,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronRouter> allRouters = routerInterface.getAllRouters();
+ List<NeutronRouter> ans = new ArrayList<NeutronRouter>();
+ Iterator<NeutronRouter> i = allRouters.iterator();
+ while (i.hasNext()) {
+ NeutronRouter oSS = i.next();
+ if ((queryID == null || queryID.equals(oSS.getID())) &&
+ (queryName == null || queryName.equals(oSS.getName())) &&
+ (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&
+ (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&
+ (queryExternalGatewayInfo == null || queryExternalGatewayInfo.equals(oSS.getExternalGatewayInfo())) &&
+ (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {
+ if (fields.size() > 0)
+ ans.add(extractFields(oSS,fields));
+ else
+ ans.add(oSS);
+ }
+ }
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronRouterRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Router */
+
+ @Path("{routerUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackRouters.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response showRouter(
+ @PathParam("routerUUID") String routerUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!routerInterface.routerExists(routerUUID))
+ return Response.status(404).build();
+ if (fields.size() > 0) {
+ NeutronRouter ans = routerInterface.getRouter(routerUUID);
+ return Response.status(200).entity(
+ new NeutronRouterRequest(extractFields(ans, fields))).build();
+ } else
+ return Response.status(200).entity(
+ new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();
+ }
+
+ /**
+ * Creates new Routers */
+
+ @POST
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackRouters.class)
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "Created"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response createRouters(final NeutronRouterRequest input) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronRouter singleton = input.getSingleton();
+
+ /*
+ * verify that the router doesn't already exist (issue: is deeper inspection necessary?)
+ * if there is external gateway information provided, verify that the specified network
+ * exists and has been designated as "router:external"
+ */
+ if (routerInterface.routerExists(singleton.getID()))
+ return Response.status(400).build();
+ if (singleton.getExternalGatewayInfo() != null) {
+ String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();
+ if (!networkInterface.networkExists(externNetworkPtr))
+ return Response.status(400).build();
+ NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);
+ if (!externNetwork.isRouterExternal())
+ return Response.status(400).build();
+ }
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ int status = service.canCreateRouter(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+
+ /*
+ * add router to the cache
+ */
+ routerInterface.addRouter(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.neutronRouterCreated(singleton);
+ }
+ }
+ } else {
+
+ /*
+ * only singleton router creates supported
+ */
+ return Response.status(400).build();
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a Router */
+
+ @Path("{routerUUID}")
+ @PUT
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackRouters.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response updateRouter(
+ @PathParam("routerUUID") String routerUUID,
+ NeutronRouterRequest input
+ ) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * router has to exist and only a single delta can be supplied
+ */
+ if (!routerInterface.routerExists(routerUUID))
+ return Response.status(404).build();
+ if (!input.isSingleton())
+ return Response.status(400).build();
+ NeutronRouter singleton = input.getSingleton();
+ NeutronRouter original = routerInterface.getRouter(routerUUID);
+
+ /*
+ * attribute changes blocked by Neutron
+ */
+ if (singleton.getID() != null || singleton.getTenantID() != null ||
+ singleton.getStatus() != null)
+ return Response.status(400).build();
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ int status = service.canUpdateRouter(singleton, original);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ /*
+ * if the external gateway info is being changed, verify that the new network
+ * exists and has been designated as an external network
+ */
+ if (singleton.getExternalGatewayInfo() != null) {
+ String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();
+ if (!networkInterface.networkExists(externNetworkPtr))
+ return Response.status(400).build();
+ NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);
+ if (!externNetwork.isRouterExternal())
+ return Response.status(400).build();
+ }
+
+ /*
+ * update the router entry and return the modified object
+ */
+ routerInterface.updateRouter(routerUUID, singleton);
+ NeutronRouter updatedRouter = routerInterface.getRouter(routerUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.neutronRouterUpdated(updatedRouter);
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();
+
+ }
+
+ /**
+ * Deletes a Router */
+
+ @Path("{routerUUID}")
+ @DELETE
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "No Content"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response deleteRouter(
+ @PathParam("routerUUID") String routerUUID) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify that the router exists and is not in use before removing it
+ */
+ if (!routerInterface.routerExists(routerUUID))
+ return Response.status(404).build();
+ if (routerInterface.routerInUse(routerUUID))
+ return Response.status(409).build();
+ NeutronRouter singleton = routerInterface.getRouter(routerUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ int status = service.canDeleteRouter(singleton);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+ routerInterface.removeRouter(routerUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.neutronRouterDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+
+ /**
+ * Adds an interface to a router */
+
+ @Path("{routerUUID}/add_router_interface")
+ @PUT
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackRouterInterfaces.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response addRouterInterface(
+ @PathParam("routerUUID") String routerUUID,
+ NeutronRouter_Interface input
+ ) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * While the Neutron specification says that the router has to exist and the input can only specify either a subnet id
+ * 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
+ */
+ if (!routerInterface.routerExists(routerUUID))
+ return Response.status(400).build();
+ NeutronRouter target = routerInterface.getRouter(routerUUID);
+ if (input.getSubnetUUID() == null ||
+ input.getPortUUID() == null)
+ return Response.status(400).build();
+
+ // check that the port is part of the subnet
+ NeutronSubnet targetSubnet = subnetInterface.getSubnet(input.getSubnetUUID());
+ if (targetSubnet == null)
+ return Response.status(400).build();
+ NeutronPort targetPort = portInterface.getPort(input.getPortUUID());
+ if (targetPort == null)
+ return Response.status(400).build();
+ if (!targetSubnet.getPortsInSubnet().contains(targetPort))
+ return Response.status(400).build();
+
+ if (targetPort.getFixedIPs().size() != 1)
+ return Response.status(400).build();
+ if (targetPort.getDeviceID() != null ||
+ targetPort.getDeviceOwner() != null)
+ return Response.status(409).build();
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.canAttachInterface(target, input);
+ }
+ }
+
+ //mark the port device id and device owner fields
+ targetPort.setDeviceOwner("network:router_interface");
+ targetPort.setDeviceID(routerUUID);
+
+ target.addInterface(input.getPortUUID(), input);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.neutronRouterInterfaceAttached(target, input);
+ }
+ }
+
+ return Response.status(200).entity(input).build();
+ }
+
+ /**
+ * Removes an interface to a router */
+
+ @Path("{routerUUID}/remove_router_interface")
+ @PUT
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackRouterInterfaces.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response removeRouterInterface(
+ @PathParam("routerUUID") String routerUUID,
+ NeutronRouter_Interface input
+ ) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ // verify the router exists
+ if (!routerInterface.routerExists(routerUUID))
+ return Response.status(400).build();
+ NeutronRouter target = routerInterface.getRouter(routerUUID);
+
+ /*
+ * remove by subnet id. Collect information about the impacted router for the response and
+ * remove the port corresponding to the gateway IP address of the subnet
+ */
+ if (input.getPortUUID() == null &&
+ input.getSubnetUUID() != null) {
+ NeutronPort port = portInterface.getGatewayPort(input.getSubnetUUID());
+ if (port == null)
+ return Response.status(404).build();
+ input.setPortUUID(port.getID());
+ input.setID(target.getID());
+ input.setTenantID(target.getTenantID());
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.canDetachInterface(target, input);
+ }
+ }
+
+ // reset the port ownership
+ port.setDeviceID(null);
+ port.setDeviceOwner(null);
+
+ target.removeInterface(input.getPortUUID());
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.neutronRouterInterfaceDetached(target, input);
+ }
+ }
+ return Response.status(200).entity(input).build();
+ }
+
+ /*
+ * remove by port id. collect information about the impacted router for the response
+ * remove the interface and reset the port ownership
+ */
+ if (input.getPortUUID() != null &&
+ input.getSubnetUUID() == null) {
+ NeutronRouter_Interface targetInterface = target.getInterfaces().get(input.getPortUUID());
+ input.setSubnetUUID(targetInterface.getSubnetUUID());
+ input.setID(target.getID());
+ input.setTenantID(target.getTenantID());
+ NeutronPort port = portInterface.getPort(input.getPortUUID());
+ port.setDeviceID(null);
+ port.setDeviceOwner(null);
+ target.removeInterface(input.getPortUUID());
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.neutronRouterInterfaceDetached(target, input);
+ }
+ return Response.status(200).entity(input).build();
+ }
+
+ /*
+ * remove by both port and subnet ID. Verify that the first fixed IP of the port is a valid
+ * IP address for the subnet, and then remove the interface, collecting information about the
+ * impacted router for the response and reset port ownership
+ */
+ if (input.getPortUUID() != null &&
+ input.getSubnetUUID() != null) {
+ NeutronPort port = portInterface.getPort(input.getPortUUID());
+ NeutronSubnet subnet = subnetInterface.getSubnet(input.getSubnetUUID());
+ if (!subnet.isValidIP(port.getFixedIPs().get(0).getIpAddress()))
+ return Response.status(409).build();
+ input.setID(target.getID());
+ input.setTenantID(target.getTenantID());
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.canDetachInterface(target, input);
+ }
+ }
+ port.setDeviceID(null);
+ port.setDeviceOwner(null);
+ target.removeInterface(input.getPortUUID());
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ service.neutronRouterInterfaceDetached(target, input);
+ }
+ return Response.status(200).entity(input).build();
+ }
+
+ // have to specify either a port ID or a subnet ID
+ return Response.status(400).build();
+ }
+}
-/*\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
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronSubnetRequest {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="subnet")
+ NeutronSubnet singletonSubnet;
+
+ @XmlElement(name="subnets")
+ List<NeutronSubnet> bulkRequest;
+
+ NeutronSubnetRequest() {
+ }
+
+ NeutronSubnetRequest(List<NeutronSubnet> bulk) {
+ bulkRequest = bulk;
+ singletonSubnet = null;
+ }
+
+ NeutronSubnetRequest(NeutronSubnet subnet) {
+ singletonSubnet = subnet;
+ }
+
+ public NeutronSubnet getSingleton() {
+ return singletonSubnet;
+ }
+
+ public List<NeutronSubnet> getBulk() {
+ return bulkRequest;
+ }
+
+ public boolean isSingleton() {
+ return (singletonSubnet != null);
+ }
+}
-/*\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.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.opendaylight.controller.northbound.commons.RestMessages;\r
-import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;\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 = NeutronCRUDInterfaces.getINeutronSubnetCRUD( 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
- }\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 = NeutronCRUDInterfaces.getINeutronSubnetCRUD(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
- }\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
- /**\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 = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
- if (subnetInterface == null) {\r
- throw new ServiceUnavailableException("Subnet CRUD Interface "\r
- + RestMessages.SERVICEUNAVAILABLE.toString());\r
- }\r
- INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( 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
- }\r
- if (!networkInterface.networkExists(singleton.getNetworkUUID())) {\r
- return Response.status(404).build();\r
- }\r
- if (!singleton.isValidCIDR()) {\r
- return Response.status(400).build();\r
- }\r
- if (!singleton.initDefaults()) {\r
- throw new InternalServerErrorException("subnet object could not be initialized properly");\r
- }\r
- if (singleton.gatewayIP_Pool_overlap()) {\r
- return Response.status(409).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.canCreateSubnet(singleton);\r
- if (status < 200 || status > 299) {\r
- return Response.status(status).build();\r
- }\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
- if (!test.initDefaults()) {\r
- throw new InternalServerErrorException("subnet object could not be initialized properly");\r
- }\r
- if (subnetInterface.subnetExists(test.getID())) {\r
- return Response.status(400).build();\r
- }\r
- if (testMap.containsKey(test.getID())) {\r
- return Response.status(400).build();\r
- }\r
- testMap.put(test.getID(), test);\r
- if (!networkInterface.networkExists(test.getNetworkUUID())) {\r
- return Response.status(404).build();\r
- }\r
- if (!test.isValidCIDR()) {\r
- return Response.status(400).build();\r
- }\r
- if (test.gatewayIP_Pool_overlap()) {\r
- return Response.status(409).build();\r
- }\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
- /*\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 = NeutronCRUDInterfaces.getINeutronSubnetCRUD( 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
- }\r
- if (!input.isSingleton()) {\r
- return Response.status(400).build();\r
- }\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
-\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
- /*\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 = NeutronCRUDInterfaces.getINeutronSubnetCRUD( 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
- }\r
- if (subnetInterface.subnetInUse(subnetUUID)) {\r
- return Response.status(409).build();\r
- }\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
- /*\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
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Open DOVE Northbound REST APIs.<br>
+ * This class provides REST APIs for managing open DOVE internals related to Subnets
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/subnets")
+public class NeutronSubnetsNorthbound {
+
+ private NeutronSubnet extractFields(NeutronSubnet o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+
+ /**
+ * Returns a list of all Subnets */
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackSubnets.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response listSubnets(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("network_id") String queryNetworkID,
+ @QueryParam("name") String queryName,
+ @QueryParam("ip_version") String queryIPVersion,
+ @QueryParam("cidr") String queryCIDR,
+ @QueryParam("gateway_ip") String queryGatewayIP,
+ @QueryParam("enable_dhcp") String queryEnableDHCP,
+ @QueryParam("tenant_id") String queryTenantID,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronSubnet> allNetworks = subnetInterface.getAllSubnets();
+ List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();
+ Iterator<NeutronSubnet> i = allNetworks.iterator();
+ while (i.hasNext()) {
+ NeutronSubnet oSS = i.next();
+ if ((queryID == null || queryID.equals(oSS.getID())) &&
+ (queryNetworkID == null || queryNetworkID.equals(oSS.getNetworkUUID())) &&
+ (queryName == null || queryName.equals(oSS.getName())) &&
+ (queryIPVersion == null || queryIPVersion.equals(oSS.getIpVersion())) &&
+ (queryCIDR == null || queryCIDR.equals(oSS.getCidr())) &&
+ (queryGatewayIP == null || queryGatewayIP.equals(oSS.getGatewayIP())) &&
+ (queryEnableDHCP == null || queryEnableDHCP.equals(oSS.getEnableDHCP())) &&
+ (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {
+ if (fields.size() > 0) {
+ ans.add(extractFields(oSS,fields));
+ } else {
+ ans.add(oSS);
+ }
+ }
+ }
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronSubnetRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Subnet */
+
+ @Path("{subnetUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackSubnets.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response showSubnet(
+ @PathParam("subnetUUID") String subnetUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields) {
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!subnetInterface.subnetExists(subnetUUID)) {
+ return Response.status(404).build();
+ }
+ if (fields.size() > 0) {
+ NeutronSubnet ans = subnetInterface.getSubnet(subnetUUID);
+ return Response.status(200).entity(
+ new NeutronSubnetRequest(extractFields(ans, fields))).build();
+ } else {
+ return Response.status(200).entity(
+ new NeutronSubnetRequest(subnetInterface.getSubnet(subnetUUID))).build();
+ }
+ }
+
+ /**
+ * Creates new Subnets */
+
+ @POST
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackSubnets.class)
+ @StatusCodes({
+ @ResponseCode(code = 201, condition = "Created"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response createSubnets(final NeutronSubnetRequest input) {
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronSubnet singleton = input.getSingleton();
+
+ /*
+ * Verify that the subnet doesn't already exist (Issue: is a deeper check necessary?)
+ * the specified network exists, the subnet has a valid network address,
+ * and that the gateway IP doesn't overlap with the allocation pools
+ * *then* add the subnet to the cache
+ */
+ if (subnetInterface.subnetExists(singleton.getID())) {
+ return Response.status(400).build();
+ }
+ if (!networkInterface.networkExists(singleton.getNetworkUUID())) {
+ return Response.status(404).build();
+ }
+ if (!singleton.isValidCIDR()) {
+ return Response.status(400).build();
+ }
+ if (!singleton.initDefaults()) {
+ throw new InternalServerErrorException("subnet object could not be initialized properly");
+ }
+ if (singleton.gatewayIP_Pool_overlap()) {
+ return Response.status(409).build();
+ }
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ int status = service.canCreateSubnet(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ subnetInterface.addSubnet(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ service.neutronSubnetCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronSubnet> bulk = input.getBulk();
+ Iterator<NeutronSubnet> i = bulk.iterator();
+ HashMap<String, NeutronSubnet> testMap = new HashMap<String, NeutronSubnet>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronSubnet test = i.next();
+
+ /*
+ * Verify that the subnet doesn't already exist (Issue: is a deeper check necessary?)
+ * the specified network exists, the subnet has a valid network address,
+ * and that the gateway IP doesn't overlap with the allocation pools,
+ * and that the bulk request doesn't already contain a subnet with this id
+ */
+
+ if (!test.initDefaults()) {
+ throw new InternalServerErrorException("subnet object could not be initialized properly");
+ }
+ if (subnetInterface.subnetExists(test.getID())) {
+ return Response.status(400).build();
+ }
+ if (testMap.containsKey(test.getID())) {
+ return Response.status(400).build();
+ }
+ testMap.put(test.getID(), test);
+ if (!networkInterface.networkExists(test.getNetworkUUID())) {
+ return Response.status(404).build();
+ }
+ if (!test.isValidCIDR()) {
+ return Response.status(400).build();
+ }
+ if (test.gatewayIP_Pool_overlap()) {
+ return Response.status(409).build();
+ }
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ int status = service.canCreateSubnet(test);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ }
+
+ /*
+ * now, each element of the bulk request can be added to the cache
+ */
+ i = bulk.iterator();
+ while (i.hasNext()) {
+ NeutronSubnet test = i.next();
+ subnetInterface.addSubnet(test);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ service.neutronSubnetCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a Subnet */
+
+ @Path("{subnetUUID}")
+ @PUT
+ @Produces({ MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackSubnets.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 400, condition = "Bad Request"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response updateSubnet(
+ @PathParam("subnetUUID") String subnetUUID, final NeutronSubnetRequest input
+ ) {
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the subnet exists and there is only one delta provided
+ */
+ if (!subnetInterface.subnetExists(subnetUUID)) {
+ return Response.status(404).build();
+ }
+ if (!input.isSingleton()) {
+ return Response.status(400).build();
+ }
+ NeutronSubnet delta = input.getSingleton();
+ NeutronSubnet original = subnetInterface.getSubnet(subnetUUID);
+
+ /*
+ * updates restricted by Neutron
+ */
+ if (delta.getID() != null || delta.getTenantID() != null ||
+ delta.getIpVersion() != null || delta.getCidr() != null ||
+ delta.getAllocationPools() != null) {
+ return Response.status(400).build();
+ }
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ int status = service.canUpdateSubnet(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * update the object and return it
+ */
+ subnetInterface.updateSubnet(subnetUUID, delta);
+ NeutronSubnet updatedSubnet = subnetInterface.getSubnet(subnetUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ service.neutronSubnetUpdated(updatedSubnet);
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronSubnetRequest(subnetInterface.getSubnet(subnetUUID))).build();
+ }
+
+ /**
+ * Deletes a Subnet */
+
+ @Path("{subnetUUID}")
+ @DELETE
+ @StatusCodes({
+ @ResponseCode(code = 204, condition = "No Content"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response deleteSubnet(
+ @PathParam("subnetUUID") String subnetUUID) {
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the subnet exists and it isn't currently in use
+ */
+ if (!subnetInterface.subnetExists(subnetUUID)) {
+ return Response.status(404).build();
+ }
+ if (subnetInterface.subnetInUse(subnetUUID)) {
+ return Response.status(409).build();
+ }
+ NeutronSubnet singleton = subnetInterface.getSubnet(subnetUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ int status = service.canDeleteSubnet(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * remove it and return 204 status
+ */
+ subnetInterface.removeSubnet(subnetUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ service.neutronSubnetDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}