From ae9ef45ceff09b2ce7943e3be569ea217464b8bd Mon Sep 17 00:00:00 2001 From: Ryan Moats Date: Fri, 8 Nov 2013 11:42:23 -0600 Subject: [PATCH] Convert neutron northbound classes to unix line delimiters Replace original Windows line delimiters. Change-Id: I4dada1270d6d0e656a5b899ef8337c545c57c7ea Signed-off-by: Ryan Moats --- .../northbound/NeutronFloatingIPRequest.java | 104 +- .../NeutronFloatingIPsNorthbound.java | 854 ++++++------ .../northbound/NeutronNetworkRequest.java | 110 +- .../northbound/NeutronNetworksNorthbound.java | 712 +++++----- .../NeutronNorthboundRSApplication.java | 116 +- .../northbound/NeutronPortRequest.java | 110 +- .../northbound/NeutronPortsNorthbound.java | 954 +++++++------- .../northbound/NeutronRouterRequest.java | 114 +- .../northbound/NeutronRoutersNorthbound.java | 1142 ++++++++--------- .../northbound/NeutronSubnetRequest.java | 112 +- .../northbound/NeutronSubnetsNorthbound.java | 820 ++++++------ 11 files changed, 2574 insertions(+), 2574 deletions(-) diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPRequest.java index ca1389c724..efb86e0542 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPRequest.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPRequest.java @@ -1,52 +1,52 @@ -/* - * 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 bulkRequest; - - NeutronFloatingIPRequest() { - } - - NeutronFloatingIPRequest(List bulk) { - bulkRequest = bulk; - singletonFloatingIP = null; - } - - NeutronFloatingIPRequest(NeutronFloatingIP singleton) { - bulkRequest = null; - singletonFloatingIP = singleton; - } - - public NeutronFloatingIP getSingleton() { - return singletonFloatingIP; - } - - public boolean isSingleton() { - return (singletonFloatingIP != null); - } -} +/* + * 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 bulkRequest; + + NeutronFloatingIPRequest() { + } + + NeutronFloatingIPRequest(List bulk) { + bulkRequest = bulk; + singletonFloatingIP = null; + } + + NeutronFloatingIPRequest(NeutronFloatingIP singleton) { + bulkRequest = null; + singletonFloatingIP = singleton; + } + + public NeutronFloatingIP getSingleton() { + return singletonFloatingIP; + } + + public boolean isSingleton() { + return (singletonFloatingIP != null); + } +} diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPsNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPsNorthbound.java index 2b0ad45629..680b028f9a 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPsNorthbound.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPsNorthbound.java @@ -1,427 +1,427 @@ -/* - * 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.
- * This class provides REST APIs for managing the open DOVE - * - *
- *
- * Authentication scheme : HTTP Basic
- * Authentication realm : opendaylight
- * Transport : HTTP and HTTPS
- *
- * 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.
- * 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 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 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 allFloatingIPs = floatingIPInterface.getAllFloatingIPs(); - List ans = new ArrayList(); - Iterator 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 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 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 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(); - } -} +/* + * 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.
+ * This class provides REST APIs for managing the open DOVE + * + *
+ *
+ * Authentication scheme : HTTP Basic
+ * Authentication realm : opendaylight
+ * Transport : HTTP and HTTPS
+ *
+ * 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.
+ * 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 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 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 allFloatingIPs = floatingIPInterface.getAllFloatingIPs(); + List ans = new ArrayList(); + Iterator 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 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 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 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(); + } +} diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworkRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworkRequest.java index 9d449380a5..cebd3c267d 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworkRequest.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworkRequest.java @@ -1,55 +1,55 @@ -/* - * 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 bulkRequest; - - NeutronNetworkRequest() { - } - - NeutronNetworkRequest(List bulk) { - bulkRequest = bulk; - singletonNetwork = null; - } - - NeutronNetworkRequest(NeutronNetwork net) { - singletonNetwork = net; - } - - public NeutronNetwork getSingleton() { - return singletonNetwork; - } - - public boolean isSingleton() { - return (singletonNetwork != null); - } - - public List getBulk() { - return bulkRequest; - } -} +/* + * 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 bulkRequest; + + NeutronNetworkRequest() { + } + + NeutronNetworkRequest(List bulk) { + bulkRequest = bulk; + singletonNetwork = null; + } + + NeutronNetworkRequest(NeutronNetwork net) { + singletonNetwork = net; + } + + public NeutronNetwork getSingleton() { + return singletonNetwork; + } + + public boolean isSingleton() { + return (singletonNetwork != null); + } + + public List getBulk() { + return bulkRequest; + } +} diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworksNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworksNorthbound.java index 383009b9d5..e8690aa889 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworksNorthbound.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworksNorthbound.java @@ -1,356 +1,356 @@ -/* - * 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.
- * This class provides REST APIs for managing open DOVE internals related to Networks - * - *
- *
- * Authentication scheme : HTTP Basic
- * Authentication realm : opendaylight
- * Transport : HTTP and HTTPS
- *
- * 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.
- * 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 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 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 allNetworks = networkInterface.getAllNetworks(); - List ans = new ArrayList(); - Iterator 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 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 bulk = input.getBulk(); - Iterator i = bulk.iterator(); - HashMap testMap = new HashMap(); - 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(); - } -} +/* + * 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.
+ * This class provides REST APIs for managing open DOVE internals related to Networks + * + *
+ *
+ * Authentication scheme : HTTP Basic
+ * Authentication realm : opendaylight
+ * Transport : HTTP and HTTPS
+ *
+ * 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.
+ * 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 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 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 allNetworks = networkInterface.getAllNetworks(); + List ans = new ArrayList(); + Iterator 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 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 bulk = input.getBulk(); + Iterator i = bulk.iterator(); + HashMap testMap = new HashMap(); + 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(); + } +} diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java index 7e2a06be59..76c39e4294 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java @@ -1,58 +1,58 @@ -/* - * 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> getClasses() { - Set> classes = new HashSet>(); -// 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 getSingletons() { - MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider(); - - moxyJsonProvider.setAttributePrefix("@"); - moxyJsonProvider.setFormattedOutput(true); - moxyJsonProvider.setIncludeRoot(false); - moxyJsonProvider.setMarshalEmptyCollections(true); - moxyJsonProvider.setValueWrapper("$"); - - Map namespacePrefixMapper = new HashMap(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 set = new HashSet(1); - set.add(moxyJsonProvider); - return set; - } -} +/* + * 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> getClasses() { + Set> classes = new HashSet>(); +// 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 getSingletons() { + MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider(); + + moxyJsonProvider.setAttributePrefix("@"); + moxyJsonProvider.setFormattedOutput(true); + moxyJsonProvider.setIncludeRoot(false); + moxyJsonProvider.setMarshalEmptyCollections(true); + moxyJsonProvider.setValueWrapper("$"); + + Map namespacePrefixMapper = new HashMap(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 set = new HashSet(1); + set.add(moxyJsonProvider); + return set; + } +} diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortRequest.java index f6765fb221..9b3399d9a8 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortRequest.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortRequest.java @@ -1,55 +1,55 @@ -/* - * 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 bulkRequest; - - NeutronPortRequest() { - } - - NeutronPortRequest(List bulk) { - bulkRequest = bulk; - singletonPort = null; - } - - NeutronPortRequest(NeutronPort port) { - singletonPort = port; - } - - public NeutronPort getSingleton() { - return singletonPort; - } - - public boolean isSingleton() { - return (singletonPort != null); - } - - public List getBulk() { - return bulkRequest; - } -} +/* + * 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 bulkRequest; + + NeutronPortRequest() { + } + + NeutronPortRequest(List bulk) { + bulkRequest = bulk; + singletonPort = null; + } + + NeutronPortRequest(NeutronPort port) { + singletonPort = port; + } + + public NeutronPort getSingleton() { + return singletonPort; + } + + public boolean isSingleton() { + return (singletonPort != null); + } + + public List getBulk() { + return bulkRequest; + } +} diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java index f48a70d9d7..08e5dfbb36 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java @@ -1,477 +1,477 @@ -/* - * 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.
- * This class provides REST APIs for managing the open DOVE - * - *
- *
- * Authentication scheme : HTTP Basic
- * Authentication realm : opendaylight
- * Transport : HTTP and HTTPS
- *
- * 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.
- * 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 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 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 allPorts = portInterface.getAllPorts(); - List ans = new ArrayList(); - Iterator 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 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 fixedIPs = singleton.getFixedIPs(); - if (fixedIPs != null && fixedIPs.size() > 0) { - Iterator 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 bulk = input.getBulk(); - Iterator i = bulk.iterator(); - HashMap testMap = new HashMap(); - 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 fixedIPs = test.getFixedIPs(); - if (fixedIPs != null && fixedIPs.size() > 0) { - Iterator 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 fixedIPs = singleton.getFixedIPs(); - if (fixedIPs != null && fixedIPs.size() > 0) { - Iterator 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(); - } -} +/* + * 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.
+ * This class provides REST APIs for managing the open DOVE + * + *
+ *
+ * Authentication scheme : HTTP Basic
+ * Authentication realm : opendaylight
+ * Transport : HTTP and HTTPS
+ *
+ * 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.
+ * 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 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 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 allPorts = portInterface.getAllPorts(); + List ans = new ArrayList(); + Iterator 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 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 fixedIPs = singleton.getFixedIPs(); + if (fixedIPs != null && fixedIPs.size() > 0) { + Iterator 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 bulk = input.getBulk(); + Iterator i = bulk.iterator(); + HashMap testMap = new HashMap(); + 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 fixedIPs = test.getFixedIPs(); + if (fixedIPs != null && fixedIPs.size() > 0) { + Iterator 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 fixedIPs = singleton.getFixedIPs(); + if (fixedIPs != null && fixedIPs.size() > 0) { + Iterator 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(); + } +} diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRouterRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRouterRequest.java index 1fcc9a9e91..806fd69e8a 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRouterRequest.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRouterRequest.java @@ -1,57 +1,57 @@ -/* - * 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 bulkRequest; - - NeutronRouterRequest() { - } - - NeutronRouterRequest(List bulk) { - bulkRequest = bulk; - singletonRouter = null; - } - - NeutronRouterRequest(NeutronRouter router) { - singletonRouter = router; - } - - public List getBulk() { - return bulkRequest; - } - - public NeutronRouter getSingleton() { - return singletonRouter; - } - - public boolean isSingleton() { - return (singletonRouter != null); - } -} +/* + * 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 bulkRequest; + + NeutronRouterRequest() { + } + + NeutronRouterRequest(List bulk) { + bulkRequest = bulk; + singletonRouter = null; + } + + NeutronRouterRequest(NeutronRouter router) { + singletonRouter = router; + } + + public List getBulk() { + return bulkRequest; + } + + public NeutronRouter getSingleton() { + return singletonRouter; + } + + public boolean isSingleton() { + return (singletonRouter != null); + } +} diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRoutersNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRoutersNorthbound.java index df2009ed2b..fc7e0f7efb 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRoutersNorthbound.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRoutersNorthbound.java @@ -1,571 +1,571 @@ -/* - * 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.
- * This class provides REST APIs for managing the open DOVE - * - *
- *
- * Authentication scheme : HTTP Basic
- * Authentication realm : opendaylight
- * Transport : HTTP and HTTPS
- *
- * 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.
- * 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 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 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 allRouters = routerInterface.getAllRouters(); - List ans = new ArrayList(); - Iterator 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 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(); - } -} +/* + * 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.
+ * This class provides REST APIs for managing the open DOVE + * + *
+ *
+ * Authentication scheme : HTTP Basic
+ * Authentication realm : opendaylight
+ * Transport : HTTP and HTTPS
+ *
+ * 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.
+ * 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 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 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 allRouters = routerInterface.getAllRouters(); + List ans = new ArrayList(); + Iterator 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 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(); + } +} diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetRequest.java index ab91399879..aed9db58bd 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetRequest.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetRequest.java @@ -1,56 +1,56 @@ -/* - * 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 bulkRequest; - - NeutronSubnetRequest() { - } - - NeutronSubnetRequest(List bulk) { - bulkRequest = bulk; - singletonSubnet = null; - } - - NeutronSubnetRequest(NeutronSubnet subnet) { - singletonSubnet = subnet; - } - - public NeutronSubnet getSingleton() { - return singletonSubnet; - } - - public List getBulk() { - return bulkRequest; - } - - public boolean isSingleton() { - return (singletonSubnet != null); - } -} +/* + * 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 bulkRequest; + + NeutronSubnetRequest() { + } + + NeutronSubnetRequest(List bulk) { + bulkRequest = bulk; + singletonSubnet = null; + } + + NeutronSubnetRequest(NeutronSubnet subnet) { + singletonSubnet = subnet; + } + + public NeutronSubnet getSingleton() { + return singletonSubnet; + } + + public List getBulk() { + return bulkRequest; + } + + public boolean isSingleton() { + return (singletonSubnet != null); + } +} diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetsNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetsNorthbound.java index 699aee9fc3..dffac55c50 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetsNorthbound.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetsNorthbound.java @@ -1,410 +1,410 @@ -/* - * 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.
- * This class provides REST APIs for managing open DOVE internals related to Subnets - * - *
- *
- * Authentication scheme : HTTP Basic
- * Authentication realm : opendaylight
- * Transport : HTTP and HTTPS
- *
- * 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.
- * 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 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 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 allNetworks = subnetInterface.getAllSubnets(); - List ans = new ArrayList(); - Iterator 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 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 bulk = input.getBulk(); - Iterator i = bulk.iterator(); - HashMap testMap = new HashMap(); - 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(); - } -} +/* + * 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.
+ * This class provides REST APIs for managing open DOVE internals related to Subnets + * + *
+ *
+ * Authentication scheme : HTTP Basic
+ * Authentication realm : opendaylight
+ * Transport : HTTP and HTTPS
+ *
+ * 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.
+ * 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 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 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 allNetworks = subnetInterface.getAllSubnets(); + List ans = new ArrayList(); + Iterator 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 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 bulk = input.getBulk(); + Iterator i = bulk.iterator(); + HashMap testMap = new HashMap(); + 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(); + } +} -- 2.36.6