--- /dev/null
+<?xml version="1.0"?>
+<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.28.xsd">
+
+ <services>
+ <rest defaultRestSubcontext="/controller/nb/v2/neutron"/>
+ </services>
+
+ <modules>
+ <docs docsDir="rest" title="OpenStack Neutron REST API" includeExampleXml="false" includeExampleJson="true"/>
+ </modules>
+</enunciate>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>commons.opendaylight</artifactId>
+ <version>1.5.0-SNAPSHOT</version>
+ <relativePath>../../../commons/opendaylight</relativePath>
+ </parent>
+ <artifactId>networkconfig.neutron.northbound</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.enunciate</groupId>
+ <artifactId>enunciate-core-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.persistence</groupId>
+ <artifactId>org.eclipse.persistence.antlr</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.persistence</groupId>
+ <artifactId>org.eclipse.persistence.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.persistence</groupId>
+ <artifactId>org.eclipse.persistence.moxy</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>commons.northbound</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>containermanager</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>networkconfig.neutron</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>org.opendaylight.controller.sal.utils,
+ org.opendaylight.controller.containermanager,
+ org.opendaylight.controller.northbound.commons,
+ org.opendaylight.controller.northbound.commons.exception,
+ org.opendaylight.controller.northbound.commons.utils,
+ org.opendaylight.controller.networkconfig.neutron,
+ org.eclipse.persistence.jaxb.rs,
+ com.sun.jersey.spi.container.servlet,
+ javax.ws.rs,
+ javax.ws.rs.ext,
+ javax.ws.rs.core,
+ javax.xml.bind.annotation,
+ javax.xml.bind,
+ org.slf4j,
+ !org.codehaus.enunciate.jaxrs</Import-Package>
+ <Web-ContextPath>/controller/nb/v2/neutron</Web-ContextPath>
+ </instructions>
+ <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.enunciate</groupId>
+ <artifactId>maven-enunciate-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+ <tag>HEAD</tag>
+ <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
+ </scm>
+
+ <distributionManagement>
+ <!-- OpenDayLight Released artifact -->
+ <repository>
+ <id>opendaylight-release</id>
+ <url>${nexusproxy}/repositories/${nexus.repository.release}/</url>
+ </repository>
+ <!-- OpenDayLight Snapshot artifact -->
+ <snapshotRepository>
+ <id>opendaylight-snapshot</id>
+ <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
+ </snapshotRepository>
+ <!-- Site deployment -->
+ <site>
+ <id>website</id>
+ <url>${sitedeploy}</url>
+ </site>
+ </distributionManagement>
+</project>
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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
+ *
+ * Authors : Dave Tucker
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import org.opendaylight.controller.networkconfig.neutron.INeutronObject;
+
+import java.util.List;
+
+public interface INeutronRequest<T extends INeutronObject> {
+ public T getSingleton();
+ public boolean isSingleton();
+ public List<T> getBulk();
+}
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFirewallAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFirewallCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFirewallRuleCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronFirewall;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+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 java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Neutron Northbound REST APIs for Firewall.<br>
+ * This class provides REST APIs for managing neutron Firewall
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+@Path("/fw/firewalls")
+public class NeutronFirewallNorthbound {
+
+ private NeutronFirewall extractFields(NeutronFirewall o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all Firewalls */
+ @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 listGroups(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // OpenStack firewall attributes
+ @QueryParam("id") String queryFirewallUUID,
+ @QueryParam("tenant_id") String queryFirewallTenantID,
+ @QueryParam("name") String queryFirewallName,
+ @QueryParam("description") String queryFirewallDescription,
+ @QueryParam("shared") Boolean queryFirewallAdminStateIsUp,
+ @QueryParam("status") String queryFirewallStatus,
+ @QueryParam("shared") Boolean queryFirewallIsShared,
+ @QueryParam("firewall_policy_id") String queryFirewallPolicyID,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronFirewallCRUD firewallInterface = NeutronCRUDInterfaces.getINeutronFirewallCRUD(this);
+ INeutronFirewallRuleCRUD firewallRuleInterface = NeutronCRUDInterfaces.getINeutronFirewallRuleCRUD(this);
+
+ if (firewallInterface == null) {
+ throw new ServiceUnavailableException("Firewall CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronFirewall> allFirewalls = firewallInterface.getAllNeutronFirewalls();
+ List<NeutronFirewall> ans = new ArrayList<NeutronFirewall>();
+ Iterator<NeutronFirewall> i = allFirewalls.iterator();
+ while (i.hasNext()) {
+ NeutronFirewall nsg = i.next();
+ if ((queryFirewallUUID == null ||
+ queryFirewallUUID.equals(nsg.getFirewallUUID())) &&
+ (queryFirewallTenantID == null ||
+ queryFirewallTenantID.equals(nsg.getFirewallTenantID())) &&
+ (queryFirewallName == null ||
+ queryFirewallName.equals(nsg.getFirewallName())) &&
+ (queryFirewallDescription == null ||
+ queryFirewallDescription.equals(nsg.getFirewallDescription())) &&
+ (queryFirewallAdminStateIsUp == null ||
+ queryFirewallAdminStateIsUp.equals(nsg.getFirewallAdminStateIsUp())) &&
+ (queryFirewallStatus == null ||
+ queryFirewallStatus.equals(nsg.getFirewallStatus())) &&
+ (queryFirewallIsShared == null ||
+ queryFirewallIsShared.equals(nsg.getFirewallIsShared())) &&
+ (queryFirewallPolicyID == null ||
+ queryFirewallPolicyID.equals(nsg.getFirewallPolicyID()))) {
+ if (fields.size() > 0) {
+ ans.add(extractFields(nsg,fields));
+ } else {
+ ans.add(nsg);
+ }
+ }
+ }
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronFirewallRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Firewall */
+
+ @Path("{firewallUUID}")
+ @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 showFirewall(@PathParam("firewallUUID") String firewallUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields) {
+ INeutronFirewallCRUD firewallInterface = NeutronCRUDInterfaces.getINeutronFirewallCRUD(this);
+ if (firewallInterface == null) {
+ throw new ServiceUnavailableException("Firewall CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!firewallInterface.neutronFirewallExists(firewallUUID)) {
+ throw new ResourceNotFoundException("Firewall UUID does not exist.");
+ }
+ if (fields.size() > 0) {
+ NeutronFirewall ans = firewallInterface.getNeutronFirewall(firewallUUID);
+ return Response.status(200).entity(
+ new NeutronFirewallRequest(extractFields(ans, fields))).build();
+ } else {
+ return Response.status(200).entity(new NeutronFirewallRequest(firewallInterface.getNeutronFirewall(firewallUUID))).build();
+ }
+ }
+
+ /**
+ * Creates new Firewall */
+
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response createFirewalls(final NeutronFirewallRequest input) {
+ INeutronFirewallCRUD firewallInterface = NeutronCRUDInterfaces.getINeutronFirewallCRUD(this);
+ if (firewallInterface == null) {
+ throw new ServiceUnavailableException("Firewall CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronFirewall singleton = input.getSingleton();
+
+ /*
+ * Verify that the Firewall doesn't already exist.
+ */
+ if (firewallInterface.neutronFirewallExists(singleton.getFirewallUUID())) {
+ throw new BadRequestException("Firewall UUID already exists");
+ }
+ firewallInterface.addNeutronFirewall(singleton);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallAware service = (INeutronFirewallAware) instance;
+ int status = service.canCreateNeutronFirewall(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ firewallInterface.addNeutronFirewall(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallAware service = (INeutronFirewallAware) instance;
+ service.neutronFirewallCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronFirewall> bulk = input.getBulk();
+ Iterator<NeutronFirewall> i = bulk.iterator();
+ HashMap<String, NeutronFirewall> testMap = new HashMap<String, NeutronFirewall>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronFirewall test = i.next();
+
+ /*
+ * Verify that the secruity group doesn't already exist
+ */
+ if (firewallInterface.neutronFirewallExists(test.getFirewallUUID())) {
+ throw new BadRequestException("Firewall UUID already is already created");
+ }
+ if (testMap.containsKey(test.getFirewallUUID())) {
+ throw new BadRequestException("Firewall UUID already exists");
+ }
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallAware service = (INeutronFirewallAware) instance;
+ int status = service.canCreateNeutronFirewall(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()) {
+ NeutronFirewall test = i.next();
+ firewallInterface.addNeutronFirewall(test);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallAware service = (INeutronFirewallAware) instance;
+ service.neutronFirewallCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a Firewall */
+
+ @Path("{firewallUUID}")
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response updateFirewall(
+ @PathParam("firewallUUID") String firewallUUID, final NeutronFirewallRequest input) {
+ INeutronFirewallCRUD firewallInterface = NeutronCRUDInterfaces.getINeutronFirewallCRUD(this);
+ if (firewallInterface == null) {
+ throw new ServiceUnavailableException("Firewall CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the Firewall exists and there is only one delta provided
+ */
+ if (!firewallInterface.neutronFirewallExists(firewallUUID)) {
+ throw new ResourceNotFoundException("Firewall UUID does not exist.");
+ }
+ if (!input.isSingleton()) {
+ throw new BadRequestException("Only singleton edit supported");
+ }
+ NeutronFirewall delta = input.getSingleton();
+ NeutronFirewall original = firewallInterface.getNeutronFirewall(firewallUUID);
+
+ /*
+ * updates restricted by Neutron
+ */
+ if (delta.getFirewallUUID() != null ||
+ delta.getFirewallTenantID() != null ||
+ delta.getFirewallName() != null ||
+ delta.getFirewallDescription() != null ||
+ delta.getFirewallAdminStateIsUp() != null ||
+ delta.getFirewallStatus() != null ||
+ delta.getFirewallIsShared() != null ||
+ delta.getFirewallPolicyID() != null) {
+ throw new BadRequestException("Attribute edit blocked by Neutron");
+ }
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallAware service = (INeutronFirewallAware) instance;
+ int status = service.canUpdateNeutronFirewall(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * update the object and return it
+ */
+ firewallInterface.updateNeutronFirewall(firewallUUID, delta);
+ NeutronFirewall updatedFirewall = firewallInterface.getNeutronFirewall(firewallUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallAware service = (INeutronFirewallAware) instance;
+ service.neutronFirewallUpdated(updatedFirewall);
+ }
+ }
+ return Response.status(200).entity(new NeutronFirewallRequest(firewallInterface.getNeutronFirewall(firewallUUID))).build();
+ }
+
+ /**
+ * Deletes a Firewall */
+
+ @Path("{firewallUUID}")
+ @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 deleteFirewall(
+ @PathParam("firewallUUID") String firewallUUID) {
+ INeutronFirewallCRUD firewallInterface = NeutronCRUDInterfaces.getINeutronFirewallCRUD(this);
+ if (firewallInterface == null) {
+ throw new ServiceUnavailableException("Firewall CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the Firewall exists and it isn't currently in use
+ */
+ if (!firewallInterface.neutronFirewallExists(firewallUUID)) {
+ throw new ResourceNotFoundException("Firewall UUID does not exist.");
+ }
+ if (firewallInterface.neutronFirewallInUse(firewallUUID)) {
+ return Response.status(409).build();
+ }
+ NeutronFirewall singleton = firewallInterface.getNeutronFirewall(firewallUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallAware service = (INeutronFirewallAware) instance;
+ int status = service.canDeleteNeutronFirewall(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * remove it and return 204 status
+ */
+ firewallInterface.removeNeutronFirewall(firewallUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallAware service = (INeutronFirewallAware) instance;
+ service.neutronFirewallDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFirewallPolicyAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFirewallPolicyCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronFirewallPolicy;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+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 java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Neutron Northbound REST APIs for Firewall Policies.<br>
+ * This class provides REST APIs for managing neutron Firewall Policies
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+@Path("/fw/firewalls_policies")
+public class NeutronFirewallPolicyNorthbound {
+
+ private NeutronFirewallPolicy extractFields(NeutronFirewallPolicy o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all Firewall Policies */
+ @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 listGroups(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // OpenStack Firewall Policy attributes
+ @QueryParam("id") String queryFirewallPolicyUUID,
+ @QueryParam("tenant_id") String queryFirewallPolicyTenantID,
+ @QueryParam("name") String queryFirewallPolicyName,
+ @QueryParam("description") String querySecurityPolicyDescription,
+ @QueryParam("shared") String querySecurityPolicyIsShared,
+ @QueryParam("firewall_rules") List<String> querySecurityPolicyFirewallRules,
+ @QueryParam("audited") Boolean querySecurityPolicyIsAudited,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronFirewallPolicyCRUD firewallPolicyInterface = NeutronCRUDInterfaces.getINeutronFirewallPolicyCRUD(this);
+
+ if (firewallPolicyInterface == null) {
+ throw new ServiceUnavailableException("Firewall Policy CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronFirewallPolicy> allFirewallPolicies = firewallPolicyInterface.getAllNeutronFirewallPolicies();
+ List<NeutronFirewallPolicy> ans = new ArrayList<NeutronFirewallPolicy>();
+ Iterator<NeutronFirewallPolicy> i = allFirewallPolicies.iterator();
+ while (i.hasNext()) {
+ NeutronFirewallPolicy nsg = i.next();
+ if ((queryFirewallPolicyUUID == null ||
+ queryFirewallPolicyUUID.equals(nsg.getFirewallPolicyUUID())) &&
+ (queryFirewallPolicyTenantID == null ||
+ queryFirewallPolicyTenantID.equals(nsg.getFirewallPolicyTenantID())) &&
+ (queryFirewallPolicyName == null ||
+ queryFirewallPolicyName.equals(nsg.getFirewallPolicyName())) &&
+ (querySecurityPolicyDescription == null ||
+ querySecurityPolicyDescription.equals(nsg.getFirewallPolicyDescription())) &&
+ (querySecurityPolicyIsShared == null ||
+ querySecurityPolicyIsShared.equals(nsg.getFirewallPolicyIsShared())) &&
+ (querySecurityPolicyFirewallRules.size() == 0 ||
+ querySecurityPolicyFirewallRules.equals(nsg.getFirewallPolicyRules())) &&
+ (querySecurityPolicyIsAudited == null ||
+ querySecurityPolicyIsAudited.equals(nsg.getFirewallPolicyIsAudited()))) {
+ if (fields.size() > 0) {
+ ans.add(extractFields(nsg,fields));
+ } else {
+ ans.add(nsg);
+ }
+ }
+ } // ans.add((NeutronFirewallPolicy) rules);
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronFirewallPolicyRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Firewall Policy */
+
+ @Path("{firewallPolicyUUID}")
+ @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 showFirewallPolicy(@PathParam("firewallPolicyUUID") String firewallPolicyUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields) {
+ INeutronFirewallPolicyCRUD firewallPolicyInterface = NeutronCRUDInterfaces.getINeutronFirewallPolicyCRUD(this);
+ if (firewallPolicyInterface == null) {
+ throw new ServiceUnavailableException("Firewall Policy CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!firewallPolicyInterface.neutronFirewallPolicyExists(firewallPolicyUUID)) {
+ throw new ResourceNotFoundException("Firewall Policy UUID does not exist.");
+ }
+ if (fields.size() > 0) {
+ NeutronFirewallPolicy ans = firewallPolicyInterface.getNeutronFirewallPolicy(firewallPolicyUUID);
+ return Response.status(200).entity(
+ new NeutronFirewallPolicyRequest(extractFields(ans, fields))).build();
+ } else {
+ return Response.status(200).entity(new NeutronFirewallPolicyRequest(firewallPolicyInterface.getNeutronFirewallPolicy(firewallPolicyUUID))).build();
+ }
+ }
+
+ /**
+ * Creates new Firewall Policy
+ * */
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response createFirewallPolicies(final NeutronFirewallPolicyRequest input) {
+ INeutronFirewallPolicyCRUD firewallPolicyInterface = NeutronCRUDInterfaces.getINeutronFirewallPolicyCRUD(this);
+ if (firewallPolicyInterface == null) {
+ throw new ServiceUnavailableException("Firewall Policy CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronFirewallPolicy singleton = input.getSingleton();
+
+ /*
+ * Verify that the Firewall Policy doesn't already exist.
+ */
+ if (firewallPolicyInterface.neutronFirewallPolicyExists(singleton.getFirewallPolicyUUID())) {
+ throw new BadRequestException("Firewall Policy UUID already exists");
+ }
+ firewallPolicyInterface.addNeutronFirewallPolicy(singleton);
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallPolicyAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
+ int status = service.canCreateNeutronFirewallPolicy(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ firewallPolicyInterface.addNeutronFirewallPolicy(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
+ service.neutronFirewallPolicyCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronFirewallPolicy> bulk = input.getBulk();
+ Iterator<NeutronFirewallPolicy> i = bulk.iterator();
+ HashMap<String, NeutronFirewallPolicy> testMap = new HashMap<String, NeutronFirewallPolicy>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallPolicyAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronFirewallPolicy test = i.next();
+
+ /*
+ * Verify that the firewall policy doesn't already exist
+ */
+
+ if (firewallPolicyInterface.neutronFirewallPolicyExists(test.getFirewallPolicyUUID())) {
+ throw new BadRequestException("Firewall Policy UUID already is already created");
+ }
+ if (testMap.containsKey(test.getFirewallPolicyUUID())) {
+ throw new BadRequestException("Firewall Policy UUID already exists");
+ }
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
+ int status = service.canCreateNeutronFirewallPolicy(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()) {
+ NeutronFirewallPolicy test = i.next();
+ firewallPolicyInterface.addNeutronFirewallPolicy(test);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
+ service.neutronFirewallPolicyCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a Firewall Policy
+ */
+ @Path("{firewallPolicyUUID}")
+ @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 updateFirewallPolicy(
+ @PathParam("firewallPolicyUUID") String firewallPolicyUUID, final NeutronFirewallPolicyRequest input) {
+ INeutronFirewallPolicyCRUD firewallPolicyInterface = NeutronCRUDInterfaces.getINeutronFirewallPolicyCRUD(this);
+ if (firewallPolicyInterface == null) {
+ throw new ServiceUnavailableException("Firewall Policy CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the Firewall Policy exists and there is only one delta provided
+ */
+ if (!firewallPolicyInterface.neutronFirewallPolicyExists(firewallPolicyUUID)) {
+ throw new ResourceNotFoundException("Firewall Policy UUID does not exist.");
+ }
+ if (!input.isSingleton()) {
+ throw new BadRequestException("Only singleton edit supported");
+ }
+ NeutronFirewallPolicy delta = input.getSingleton();
+ NeutronFirewallPolicy original = firewallPolicyInterface.getNeutronFirewallPolicy(firewallPolicyUUID);
+
+ /*
+ * updates restricted by Neutron
+ */
+ if (delta.getFirewallPolicyUUID() != null ||
+ delta.getFirewallPolicyTenantID() != null ||
+ delta.getFirewallPolicyName() != null ||
+ delta.getFirewallPolicyDescription() != null ||
+ delta.getFirewallPolicyIsShared() != null ||
+ delta.getFirewallPolicyRules().size() > 0 ||
+ delta.getFirewallPolicyIsAudited() != null) {
+ throw new BadRequestException("Attribute edit blocked by Neutron");
+ }
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallPolicyAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
+ int status = service.canUpdateNeutronFirewallPolicy(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * update the object and return it
+ */
+ firewallPolicyInterface.updateNeutronFirewallPolicy(firewallPolicyUUID, delta);
+ NeutronFirewallPolicy updatedFirewallPolicy = firewallPolicyInterface.getNeutronFirewallPolicy(firewallPolicyUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
+ service.neutronFirewallPolicyUpdated(updatedFirewallPolicy);
+ }
+ }
+ return Response.status(200).entity(new NeutronFirewallPolicyRequest(firewallPolicyInterface.getNeutronFirewallPolicy(firewallPolicyUUID))).build();
+ }
+
+ /**
+ * Deletes a Firewall Policy */
+
+ @Path("{firewallPolicyUUID}")
+ @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 deleteFirewallPolicy(
+ @PathParam("firewallPolicyUUID") String firewallPolicyUUID) {
+ INeutronFirewallPolicyCRUD firewallPolicyInterface = NeutronCRUDInterfaces.getINeutronFirewallPolicyCRUD(this);
+ if (firewallPolicyInterface == null) {
+ throw new ServiceUnavailableException("Firewall Policy CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the Firewall Policy exists and it isn't currently in use
+ */
+ if (!firewallPolicyInterface.neutronFirewallPolicyExists(firewallPolicyUUID)) {
+ throw new ResourceNotFoundException("Firewall Policy UUID does not exist.");
+ }
+ if (firewallPolicyInterface.neutronFirewallPolicyInUse(firewallPolicyUUID)) {
+ return Response.status(409).build();
+ }
+ NeutronFirewallPolicy singleton = firewallPolicyInterface.getNeutronFirewallPolicy(firewallPolicyUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallPolicyAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
+ int status = service.canDeleteNeutronFirewallPolicy(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ firewallPolicyInterface.removeNeutronFirewallPolicy(firewallPolicyUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallPolicyAware service = (INeutronFirewallPolicyAware) instance;
+ service.neutronFirewallPolicyDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.opendaylight.controller.networkconfig.neutron.NeutronFirewallPolicy;
+
+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 java.util.List;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronFirewallPolicyRequest {
+ /**
+ * See OpenStack Network API v2.0 Reference for description of
+ * http://docs.openstack.org/api/openstack-network/2.0/content/
+ */
+
+ @XmlElement(name="firewall_policy")
+ NeutronFirewallPolicy singletonFirewallPolicy;
+
+ @XmlElement(name="firewall_policies")
+ List<NeutronFirewallPolicy> bulkRequest;
+
+ NeutronFirewallPolicyRequest() {
+ }
+
+ NeutronFirewallPolicyRequest(List<NeutronFirewallPolicy> bulk) {
+ bulkRequest = bulk;
+ singletonFirewallPolicy = null;
+ }
+
+ NeutronFirewallPolicyRequest(NeutronFirewallPolicy group) {
+ singletonFirewallPolicy = group;
+ }
+
+ public List<NeutronFirewallPolicy> getBulk() {
+ return bulkRequest;
+ }
+
+ public NeutronFirewallPolicy getSingleton() {
+ return singletonFirewallPolicy;
+ }
+
+ public boolean isSingleton() {
+ return (singletonFirewallPolicy != null);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.opendaylight.controller.networkconfig.neutron.NeutronFirewall;
+
+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 java.util.List;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronFirewallRequest {
+ /**
+ * See OpenStack Network API v2.0 Reference for description of
+ * http://docs.openstack.org/api/openstack-network/2.0/content/
+ */
+
+ @XmlElement(name="firewall")
+ NeutronFirewall singletonFirewall;
+
+ @XmlElement(name="firewalls")
+ List<NeutronFirewall> bulkRequest;
+
+ NeutronFirewallRequest() {
+ }
+
+ NeutronFirewallRequest(List<NeutronFirewall> bulk) {
+ bulkRequest = bulk;
+ singletonFirewall = null;
+ }
+
+ NeutronFirewallRequest(NeutronFirewall group) {
+ singletonFirewall = group;
+ }
+
+ public List<NeutronFirewall> getBulk() {
+ return bulkRequest;
+ }
+
+ public NeutronFirewall getSingleton() {
+ return singletonFirewall;
+ }
+
+ public boolean isSingleton() {
+ return (singletonFirewall != null);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.opendaylight.controller.networkconfig.neutron.NeutronFirewallRule;
+
+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 java.util.List;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronFirewallRuleRequest {
+ /**
+ * See OpenStack Network API v2.0 Reference for description of
+ * http://docs.openstack.org/api/openstack-network/2.0/content/
+ */
+
+ @XmlElement(name="firewall_rule")
+ NeutronFirewallRule singletonFirewallRule;
+
+ @XmlElement(name="firewall_rules")
+ List<NeutronFirewallRule> bulkRequest;
+
+ NeutronFirewallRuleRequest() {
+ }
+
+ NeutronFirewallRuleRequest(List<NeutronFirewallRule> bulk) {
+ bulkRequest = bulk;
+ singletonFirewallRule = null;
+ }
+
+ NeutronFirewallRuleRequest(NeutronFirewallRule group) {
+ singletonFirewallRule = group;
+ }
+
+ public List<NeutronFirewallRule> getBulk() {
+ return bulkRequest;
+ }
+
+ public NeutronFirewallRule getSingleton() {
+ return singletonFirewallRule;
+ }
+
+ public boolean isSingleton() {
+ return (singletonFirewallRule != null);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFirewallPolicyCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFirewallRuleAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFirewallRuleCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronFirewallRule;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+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 java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Neutron Northbound REST APIs for Firewall Rule.<br>
+ * This class provides REST APIs for managing neutron Firewall Rule
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ */
+
+@Path("fw/firewalls_rules")
+public class NeutronFirewallRulesNorthbound {
+
+ private NeutronFirewallRule extractFields(NeutronFirewallRule o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all Firewall Rules
+ */
+ @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 listRules(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // OpenStack firewall rule attributes
+ @QueryParam("id") String queryFirewallRuleUUID,
+ @QueryParam("tenant_id") String queryFirewallRuleTenantID,
+ @QueryParam("name") String queryFirewallRuleName,
+ @QueryParam("description") String queryFirewallRuleDescription,
+ @QueryParam("admin_state_up") Boolean queryFirewallRuleAdminStateIsUp,
+ @QueryParam("status") String queryFirewallRuleStatus,
+ @QueryParam("shared") Boolean queryFirewallRuleIsShared,
+ @QueryParam("firewall_policy_id") String queryFirewallRulePolicyID,
+ @QueryParam("protocol") String queryFirewallRuleProtocol,
+ @QueryParam("ip_version") Integer queryFirewallRuleIpVer,
+ @QueryParam("source_ip_address") String queryFirewallRuleSrcIpAddr,
+ @QueryParam("destination_ip_address") String queryFirewallRuleDstIpAddr,
+ @QueryParam("source_port") Integer queryFirewallRuleSrcPort,
+ @QueryParam("destination_port") Integer queryFirewallRuleDstPort,
+ @QueryParam("position") Integer queryFirewallRulePosition,
+ @QueryParam("action") String queryFirewallRuleAction,
+ @QueryParam("enabled") Boolean queryFirewallRuleIsEnabled,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronFirewallRuleCRUD firewallRuleInterface = NeutronCRUDInterfaces.getINeutronFirewallRuleCRUD(this);
+ if (firewallRuleInterface == null) {
+ throw new ServiceUnavailableException("Firewall Rule CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronFirewallRule> allFirewallRules = firewallRuleInterface.getAllNeutronFirewallRules();
+ List<NeutronFirewallRule> ans = new ArrayList<NeutronFirewallRule>();
+ Iterator<NeutronFirewallRule> i = allFirewallRules.iterator();
+ while (i.hasNext()) {
+ NeutronFirewallRule nsr = i.next();
+ if ((queryFirewallRuleUUID == null ||
+ queryFirewallRuleUUID.equals(nsr.getFirewallRuleUUID())) &&
+ (queryFirewallRuleTenantID == null ||
+ queryFirewallRuleTenantID.equals(nsr.getFirewallRuleTenantID())) &&
+ (queryFirewallRuleName == null ||
+ queryFirewallRuleName.equals(nsr.getFirewallRuleName())) &&
+ (queryFirewallRuleDescription == null ||
+ queryFirewallRuleDescription.equals(nsr.getFirewallRuleDescription())) &&
+ (queryFirewallRuleAdminStateIsUp == null ||
+ queryFirewallRuleAdminStateIsUp.equals(nsr.getFirewallRuleAdminStateIsUp())) &&
+ (queryFirewallRuleStatus == null ||
+ queryFirewallRuleStatus.equals(nsr.getFirewallRuleStatus())) &&
+ (queryFirewallRuleIsShared == null ||
+ queryFirewallRuleIsShared.equals(nsr.getFirewallRuleIsShared())) &&
+ (queryFirewallRulePolicyID == null ||
+ queryFirewallRulePolicyID.equals(nsr.getFirewallRulePolicyID())) &&
+ (queryFirewallRuleProtocol == null ||
+ queryFirewallRuleProtocol.equals(nsr.getFirewallRuleProtocol())) &&
+ (queryFirewallRuleIpVer == null ||
+ queryFirewallRuleIpVer.equals(nsr.getFirewallRuleIpVer())) &&
+ (queryFirewallRuleSrcIpAddr == null ||
+ queryFirewallRuleSrcIpAddr.equals(nsr.getFirewallRuleSrcIpAddr())) &&
+ (queryFirewallRuleDstIpAddr == null ||
+ queryFirewallRuleDstIpAddr.equals(nsr.getFirewallRuleDstIpAddr())) &&
+ (queryFirewallRuleSrcPort == null ||
+ queryFirewallRuleSrcPort.equals(nsr.getFirewallRuleSrcPort())) &&
+ (queryFirewallRuleDstPort == null ||
+ queryFirewallRuleDstPort.equals(nsr.getFirewallRuleDstPort())) &&
+ (queryFirewallRulePosition == null ||
+ queryFirewallRulePosition.equals(nsr.getFirewallRulePosition())) &&
+ (queryFirewallRuleAction == null ||
+ queryFirewallRuleAction.equals(nsr.getFirewallRuleAction())) &&
+ (queryFirewallRuleIsEnabled == null ||
+ queryFirewallRuleIsEnabled.equals(nsr.getFirewallRuleIsEnabled()))) {
+ if (fields.size() > 0) {
+ ans.add(extractFields(nsr, fields));
+ } else {
+ ans.add(nsr);
+ }
+ }
+ }
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronFirewallRuleRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Firewall Rule
+ */
+
+ @Path("{firewallRuleUUID}")
+ @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 showFirewallRule(@PathParam("firewallRuleUUID") String firewallRuleUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields) {
+ INeutronFirewallRuleCRUD firewallRuleInterface = NeutronCRUDInterfaces.getINeutronFirewallRuleCRUD(this);
+ if (firewallRuleInterface == null) {
+ throw new ServiceUnavailableException("Firewall Rule CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!firewallRuleInterface.neutronFirewallRuleExists(firewallRuleUUID)) {
+ throw new ResourceNotFoundException("Firewall Rule UUID does not exist.");
+ }
+ if (fields.size() > 0) {
+ NeutronFirewallRule ans = firewallRuleInterface.getNeutronFirewallRule(firewallRuleUUID);
+ return Response.status(200).entity(
+ new NeutronFirewallRuleRequest(extractFields(ans, fields))).build();
+ } else {
+ return Response.status(200)
+ .entity(new NeutronFirewallRuleRequest(
+ firewallRuleInterface.getNeutronFirewallRule(firewallRuleUUID)))
+ .build();
+ }
+ }
+
+ /**
+ * Creates new Firewall Rule
+ */
+
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented")})
+ public Response createFirewallRules(final NeutronFirewallRuleRequest input) {
+ INeutronFirewallRuleCRUD firewallRuleInterface = NeutronCRUDInterfaces.getINeutronFirewallRuleCRUD(this);
+ if (firewallRuleInterface == null) {
+ throw new ServiceUnavailableException("Firewall Rule CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronFirewallPolicyCRUD firewallPolicyInterface = NeutronCRUDInterfaces.getINeutronFirewallPolicyCRUD(this);
+ if (firewallPolicyInterface == null) {
+ throw new ServiceUnavailableException("Firewall Policy CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ if (input.isSingleton()) {
+ NeutronFirewallRule singleton = input.getSingleton();
+ if (firewallRuleInterface.neutronFirewallRuleExists(singleton.getFirewallRuleUUID())) {
+ throw new BadRequestException("Firewall Rule UUID already exists");
+ }
+ firewallRuleInterface.addNeutronFirewallRule(singleton);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallRuleAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
+ int status = service.canCreateNeutronFirewallRule(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ // add rule to cache
+ singleton.initDefaults();
+ firewallRuleInterface.addNeutronFirewallRule(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
+ service.neutronFirewallRuleCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronFirewallRule> bulk = input.getBulk();
+ Iterator<NeutronFirewallRule> i = bulk.iterator();
+ HashMap<String, NeutronFirewallRule> testMap = new HashMap<String, NeutronFirewallRule>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallRuleAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronFirewallRule test = i.next();
+
+ /*
+ * Verify that the Firewall rule doesn't already exist
+ */
+
+ if (firewallRuleInterface.neutronFirewallRuleExists(test.getFirewallRuleUUID())) {
+ throw new BadRequestException("Firewall Rule UUID already exists");
+ }
+ if (testMap.containsKey(test.getFirewallRuleUUID())) {
+ throw new BadRequestException("Firewall Rule UUID already exists");
+ }
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
+ int status = service.canCreateNeutronFirewallRule(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()) {
+ NeutronFirewallRule test = i.next();
+ firewallRuleInterface.addNeutronFirewallRule(test);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
+ service.neutronFirewallRuleCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a Firewall Rule
+ */
+ @Path("{firewallRuleUUID}")
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented")})
+ public Response updateFirewallRule(
+ @PathParam("firewallRuleUUID") String firewallRuleUUID, final NeutronFirewallRuleRequest input) {
+ INeutronFirewallRuleCRUD firewallRuleInterface = NeutronCRUDInterfaces.getINeutronFirewallRuleCRUD(this);
+ if (firewallRuleInterface == null) {
+ throw new ServiceUnavailableException("Firewall Rule CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ /*
+ * verify the Firewall Rule exists
+ */
+ if (!firewallRuleInterface.neutronFirewallRuleExists(firewallRuleUUID)) {
+ throw new ResourceNotFoundException("Firewall Rule UUID does not exist.");
+ }
+ if (!input.isSingleton()) {
+ throw new BadRequestException("Only singleton edit supported");
+ }
+ NeutronFirewallRule delta = input.getSingleton();
+ NeutronFirewallRule original = firewallRuleInterface.getNeutronFirewallRule(firewallRuleUUID);
+
+ /*
+ * updates restricted by Neutron
+ *
+ */
+ if (delta.getFirewallRuleUUID() != null ||
+ delta.getFirewallRuleTenantID() != null ||
+ delta.getFirewallRuleName() != null ||
+ delta.getFirewallRuleDescription() != null ||
+ delta.getFirewallRuleAdminStateIsUp() != null ||
+ delta.getFirewallRuleStatus() != null ||
+ delta.getFirewallRuleIsShared() != null ||
+ delta.getFirewallRulePolicyID() != null ||
+ delta.getFirewallRuleProtocol() != null ||
+ delta.getFirewallRuleIpVer() != null ||
+ delta.getFirewallRuleSrcIpAddr() != null ||
+ delta.getFirewallRuleDstIpAddr() != null ||
+ delta.getFirewallRuleSrcPort() != null ||
+ delta.getFirewallRuleDstPort() != null ||
+ delta.getFirewallRulePosition() != null ||
+ delta.getFirewallRuleAction() != null ||
+ delta.getFirewallRuleIsEnabled() != null) {
+ throw new BadRequestException("Attribute edit blocked by Neutron");
+ }
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallRuleAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
+ int status = service.canUpdateNeutronFirewallRule(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * update the object and return it
+ */
+ firewallRuleInterface.updateNeutronFirewallRule(firewallRuleUUID, delta);
+ NeutronFirewallRule updatedFirewallRule = firewallRuleInterface.getNeutronFirewallRule(firewallRuleUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
+ service.neutronFirewallRuleUpdated(updatedFirewallRule);
+ }
+ }
+ return Response.status(200)
+ .entity(new NeutronFirewallRuleRequest(firewallRuleInterface.getNeutronFirewallRule(firewallRuleUUID)))
+ .build();
+ }
+
+ /**
+ * Deletes a Firewall Rule
+ */
+
+ @Path("{firewallRuleUUID}")
+ @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 deleteFirewallRule(
+ @PathParam("firewallRuleUUID") String firewallRuleUUID) {
+ INeutronFirewallRuleCRUD firewallRuleInterface = NeutronCRUDInterfaces.getINeutronFirewallRuleCRUD(this);
+ if (firewallRuleInterface == null) {
+ throw new ServiceUnavailableException("Firewall Rule CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the Firewall Rule exists and it isn't currently in use
+ */
+ if (!firewallRuleInterface.neutronFirewallRuleExists(firewallRuleUUID)) {
+ throw new ResourceNotFoundException("Firewall Rule UUID does not exist.");
+ }
+ if (firewallRuleInterface.neutronFirewallRuleInUse(firewallRuleUUID)) {
+ return Response.status(409).build();
+ }
+ NeutronFirewallRule singleton = firewallRuleInterface.getNeutronFirewallRule(firewallRuleUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallRuleAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
+ int status = service.canDeleteNeutronFirewallRule(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * remove it and return 204 status
+ */
+ firewallRuleInterface.removeNeutronFirewallRule(firewallRuleUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronFirewallRuleAware service = (INeutronFirewallRuleAware) instance;
+ service.neutronFirewallRuleDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
--- /dev/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<NeutronFloatingIP> bulkRequest;
+
+ NeutronFloatingIPRequest() {
+ }
+
+ NeutronFloatingIPRequest(List<NeutronFloatingIP> bulk) {
+ bulkRequest = bulk;
+ singletonFloatingIP = null;
+ }
+
+ NeutronFloatingIPRequest(NeutronFloatingIP singleton) {
+ bulkRequest = null;
+ singletonFloatingIP = singleton;
+ }
+
+ public NeutronFloatingIP getSingleton() {
+ return singletonFloatingIP;
+ }
+
+ public boolean isSingleton() {
+ return (singletonFloatingIP != null);
+ }
+}
--- /dev/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.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.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Neutron Northbound REST APIs.<br>
+ * This class provides REST APIs for managing Neutron Floating IPs
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/floatingips")
+public class NeutronFloatingIPsNorthbound {
+
+ private NeutronFloatingIP extractFields(NeutronFloatingIP o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all FloatingIPs */
+
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response listFloatingIPs(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("floating_network_id") String queryFloatingNetworkId,
+ @QueryParam("port_id") String queryPortId,
+ @QueryParam("fixed_ip_address") String queryFixedIPAddress,
+ @QueryParam("floating_ip_address") String queryFloatingIPAddress,
+ @QueryParam("tenant_id") String queryTenantID,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+ if (floatingIPInterface == null) {
+ throw new ServiceUnavailableException("Floating IP CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronFloatingIP> allFloatingIPs = floatingIPInterface.getAllFloatingIPs();
+ List<NeutronFloatingIP> ans = new ArrayList<NeutronFloatingIP>();
+ Iterator<NeutronFloatingIP> i = allFloatingIPs.iterator();
+ while (i.hasNext()) {
+ NeutronFloatingIP oSS = i.next();
+ //match filters: TODO provider extension and router extension
+ if ((queryID == null || queryID.equals(oSS.getID())) &&
+ (queryFloatingNetworkId == null || queryFloatingNetworkId.equals(oSS.getFloatingNetworkUUID())) &&
+ (queryPortId == null || queryPortId.equals(oSS.getPortUUID())) &&
+ (queryFixedIPAddress == null || queryFixedIPAddress.equals(oSS.getFixedIPAddress())) &&
+ (queryFloatingIPAddress == null || queryFloatingIPAddress.equals(oSS.getFloatingIPAddress())) &&
+ (queryTenantID == null || queryTenantID.equals(oSS.getTenantUUID()))) {
+ if (fields.size() > 0)
+ ans.add(extractFields(oSS,fields));
+ else
+ ans.add(oSS);
+ }
+ }
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronFloatingIPRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific FloatingIP */
+
+ @Path("{floatingipUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response showFloatingIP(
+ @PathParam("floatingipUUID") String floatingipUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields ) {
+ INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+ if (floatingIPInterface == null) {
+ throw new ServiceUnavailableException("Floating IP CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!floatingIPInterface.floatingIPExists(floatingipUUID))
+ throw new ResourceNotFoundException("Floating IP UUID doesn't exist.");
+ 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()))
+ throw new BadRequestException("Floating IP UUID already exists.");
+ // check if the external network is specified, exists, and is an external network
+ String externalNetworkUUID = singleton.getFloatingNetworkUUID();
+ if (externalNetworkUUID == null)
+ throw new BadRequestException("external network UUID doesn't exist.");
+ if (!networkInterface.networkExists(externalNetworkUUID))
+ throw new BadRequestException("external network UUID doesn't exist.");
+ NeutronNetwork externNetwork = networkInterface.getNetwork(externalNetworkUUID);
+ if (!externNetwork.isRouterExternal())
+ throw new BadRequestException("external network isn't marked router:external");
+ // 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)
+ throw new BadRequestException("external network doesn't have a subnet");
+ NeutronSubnet externSubnet = subnetInterface.getSubnet(externNetwork.getSubnets().get(0));
+ if (!externSubnet.isValidIP(floatingIP))
+ throw new BadRequestException("external IP isn't valid for the specified subnet.");
+ if (externSubnet.isIPInUse(floatingIP))
+ throw new ResourceConflictException("floating IP is in use.");
+ }
+ // 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))
+ throw new ResourceNotFoundException("Port UUID doesn't exist.");
+ NeutronPort port = portInterface.getPort(port_id);
+ if (port.getFixedIPs().size() < 1)
+ throw new BadRequestException("port UUID doesn't have an IP address.");
+ // 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)
+ throw new BadRequestException("fixed IP address doesn't exist.");
+ Iterator<Neutron_IPs> i = port.getFixedIPs().iterator();
+ boolean validFixedIP = false;
+ while (i.hasNext() && !validFixedIP) {
+ Neutron_IPs ip = i.next();
+ if (ip.getIpAddress().equals(fixedIP))
+ validFixedIP = true;
+ }
+ if (!validFixedIP)
+ throw new BadRequestException("can't find a valid fixed IP address");
+ } else {
+ fixedIP = port.getFixedIPs().get(0).getIpAddress();
+ if (singleton.getFixedIPAddress() != null && !fixedIP.equalsIgnoreCase(singleton.getFixedIPAddress()))
+ throw new BadRequestException("mismatched fixed IP address in request");
+ }
+ //lastly check that this fixed IP address isn't already used
+ if (port.isBoundToFloatingIP(fixedIP))
+ throw new ResourceConflictException("fixed IP is in use.");
+ 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 {
+ throw new BadRequestException("only singleton requests allowed.");
+ }
+ 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))
+ throw new ResourceNotFoundException("Floating IP UUID doesn't exist.");
+
+ NeutronFloatingIP sourceFloatingIP = floatingIPInterface.getFloatingIP(floatingipUUID);
+ if (!input.isSingleton())
+ throw new BadRequestException("only singleton requests allowed.");
+ NeutronFloatingIP singleton = input.getSingleton();
+ if (singleton.getID() == null)
+ throw new BadRequestException("singleton UUID doesn't exist.");
+
+ 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)
+ throw new BadRequestException("external network doesn't have a subnet.");
+ NeutronSubnet externSubnet = subnetInterface.getSubnet(externNetwork.getSubnets().get(0));
+ if (!externSubnet.isValidIP(floatingIP))
+ throw new BadRequestException("floating IP not valid for external subnet");
+ if (externSubnet.isIPInUse(floatingIP))
+ throw new ResourceConflictException("floating IP is in use.");
+ }
+
+ // 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))
+ throw new ResourceNotFoundException("Port UUID doesn't exist.");
+ NeutronPort port = portInterface.getPort(port_id);
+ if (port.getFixedIPs().size() < 1)
+ throw new BadRequestException("port ID doesn't have a fixed IP address.");
+ // 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)
+ throw new BadRequestException("request doesn't have a fixed IP address");
+ Iterator<Neutron_IPs> i = port.getFixedIPs().iterator();
+ boolean validFixedIP = false;
+ while (i.hasNext() && !validFixedIP) {
+ Neutron_IPs ip = i.next();
+ if (ip.getIpAddress().equals(fixedIP))
+ validFixedIP = true;
+ }
+ if (!validFixedIP)
+ throw new BadRequestException("couldn't find a valid fixed IP address");
+ } else {
+ fixedIP = port.getFixedIPs().get(0).getIpAddress();
+ if (singleton.getFixedIPAddress() != null &&
+ !fixedIP.equalsIgnoreCase(singleton.getFixedIPAddress()))
+ throw new BadRequestException("mismatch in fixed IP addresses");
+ }
+ //lastly check that this fixed IP address isn't already used
+ if (port.isBoundToFloatingIP(fixedIP))
+ throw new ResourceConflictException("fixed IP is in use.");
+ 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))
+ throw new ResourceNotFoundException("Floating IP UUID doesn't exist.");
+ // 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();
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerHealthMonitorAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerHealthMonitorCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancer;
+import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerHealthMonitor;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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 java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Neutron Northbound REST APIs for Load Balancer HealthMonitor.<br>
+ * This class provides REST APIs for managing neutron LoadBalancerHealthMonitor
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+@Path("/healthmonitors")
+public class NeutronLoadBalancerHealthMonitorNorthbound {
+ private static final Logger logger = LoggerFactory.getLogger(NeutronLoadBalancer.class);
+
+ private NeutronLoadBalancerHealthMonitor extractFields(NeutronLoadBalancerHealthMonitor o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all LoadBalancerHealthMonitor */
+ @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 listGroups(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // OpenStack LoadBalancerHealthMonitor attributes
+ @QueryParam("id") String queryLoadBalancerHealthMonitorID,
+ @QueryParam("tenant_id") String queryLoadBalancerHealthMonitorTenantID,
+ // TODO "type" is being a property by the JSON parser.
+ @QueryParam("type") String queryLoadBalancerHealthMonitorType,
+ @QueryParam("delay") Integer queryLoadBalancerHealthMonitorDelay,
+ @QueryParam("timeout") Integer queryLoadBalancerHealthMonitorTimeout,
+ @QueryParam("max_retries") Integer queryLoadBalancerHealthMonitorMaxRetries,
+ @QueryParam("http_method") String queryLoadBalancerHealthMonitorHttpMethod,
+ @QueryParam("url_path") String queryLoadBalancerHealthMonitorUrlPath,
+ @QueryParam("expected_codes") String queryLoadBalancerHealthMonitorExpectedCodes,
+ @QueryParam("admin_state_up") Boolean queryLoadBalancerHealthMonitorIsAdminStateUp,
+ @QueryParam("status") String queryLoadBalancerHealthMonitorStatus,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronLoadBalancerHealthMonitorCRUD loadBalancerHealthMonitorInterface = NeutronCRUDInterfaces
+ .getINeutronLoadBalancerHealthMonitorCRUD(this);
+ if (loadBalancerHealthMonitorInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerHealthMonitor CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronLoadBalancerHealthMonitor> allLoadBalancerHealthMonitors = loadBalancerHealthMonitorInterface.getAllNeutronLoadBalancerHealthMonitors();
+ List<NeutronLoadBalancerHealthMonitor> ans = new ArrayList<NeutronLoadBalancerHealthMonitor>();
+ Iterator<NeutronLoadBalancerHealthMonitor> i = allLoadBalancerHealthMonitors.iterator();
+ while (i.hasNext()) {
+ NeutronLoadBalancerHealthMonitor nsg = i.next();
+ if ((queryLoadBalancerHealthMonitorID == null ||
+ queryLoadBalancerHealthMonitorID.equals(nsg.getLoadBalancerHealthMonitorID())) &&
+ (queryLoadBalancerHealthMonitorTenantID == null ||
+ queryLoadBalancerHealthMonitorTenantID.equals
+ (nsg.getLoadBalancerHealthMonitorTenantID())) &&
+ (queryLoadBalancerHealthMonitorType == null ||
+ queryLoadBalancerHealthMonitorType.equals
+ (nsg.getLoadBalancerHealthMonitorType())) &&
+ (queryLoadBalancerHealthMonitorDelay == null ||
+ queryLoadBalancerHealthMonitorDelay.equals
+ (nsg.getLoadBalancerHealthMonitorDelay())) &&
+ (queryLoadBalancerHealthMonitorTimeout == null ||
+ queryLoadBalancerHealthMonitorTimeout.equals
+ (nsg.getLoadBalancerHealthMonitorTimeout())) &&
+ (queryLoadBalancerHealthMonitorMaxRetries == null ||
+ queryLoadBalancerHealthMonitorMaxRetries.equals
+ (nsg.getLoadBalancerHealthMonitorMaxRetries())) &&
+ (queryLoadBalancerHealthMonitorHttpMethod == null ||
+ queryLoadBalancerHealthMonitorHttpMethod.equals
+ (nsg.getLoadBalancerHealthMonitorHttpMethod())) &&
+ (queryLoadBalancerHealthMonitorUrlPath == null ||
+ queryLoadBalancerHealthMonitorUrlPath.equals
+ (nsg.getLoadBalancerHealthMonitorUrlPath())) &&
+ (queryLoadBalancerHealthMonitorExpectedCodes == null ||
+ queryLoadBalancerHealthMonitorExpectedCodes.equals
+ (nsg.getLoadBalancerHealthMonitorExpectedCodes())) &&
+ (queryLoadBalancerHealthMonitorIsAdminStateUp == null ||
+ queryLoadBalancerHealthMonitorIsAdminStateUp.equals
+ (nsg.getLoadBalancerHealthMonitorAdminStateIsUp())) &&
+ (queryLoadBalancerHealthMonitorStatus == null ||
+ queryLoadBalancerHealthMonitorStatus.equals
+ (nsg.getLoadBalancerHealthMonitorStatus()))) {
+ if (fields.size() > 0) {
+ ans.add(extractFields(nsg,fields));
+ } else {
+ ans.add(nsg);
+ }
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronLoadBalancerHealthMonitorRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific LoadBalancerHealthMonitor */
+
+ @Path("{loadBalancerHealthMonitorID}")
+ @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 showLoadBalancerHealthMonitor(@PathParam("loadBalancerHealthMonitorID") String loadBalancerHealthMonitorID,
+ // return fields
+ @QueryParam("fields") List<String> fields) {
+ INeutronLoadBalancerHealthMonitorCRUD loadBalancerHealthMonitorInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerHealthMonitorCRUD(this);
+ if (loadBalancerHealthMonitorInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerHealthMonitor CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!loadBalancerHealthMonitorInterface.neutronLoadBalancerHealthMonitorExists(loadBalancerHealthMonitorID)) {
+ throw new ResourceNotFoundException("LoadBalancerHealthMonitor UUID does not exist.");
+ }
+ if (fields.size() > 0) {
+ NeutronLoadBalancerHealthMonitor ans = loadBalancerHealthMonitorInterface.getNeutronLoadBalancerHealthMonitor(loadBalancerHealthMonitorID);
+ return Response.status(200).entity(
+ new NeutronLoadBalancerHealthMonitorRequest(extractFields(ans, fields))).build();
+ } else {
+ return Response.status(200).entity(new NeutronLoadBalancerHealthMonitorRequest(loadBalancerHealthMonitorInterface.getNeutronLoadBalancerHealthMonitor(loadBalancerHealthMonitorID))).build();
+ }
+ }
+
+ /**
+ * Creates new LoadBalancerHealthMonitor */
+
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response createLoadBalancerHealthMonitors(final NeutronLoadBalancerHealthMonitorRequest input) {
+ INeutronLoadBalancerHealthMonitorCRUD loadBalancerHealthMonitorInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerHealthMonitorCRUD(this);
+ if (loadBalancerHealthMonitorInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerHealthMonitor CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronLoadBalancerHealthMonitor singleton = input.getSingleton();
+
+ /*
+ * Verify that the LoadBalancerHealthMonitor doesn't already exist.
+ */
+ if (loadBalancerHealthMonitorInterface.neutronLoadBalancerHealthMonitorExists(singleton.getLoadBalancerHealthMonitorID())) {
+ throw new BadRequestException("LoadBalancerHealthMonitor UUID already exists");
+ }
+ loadBalancerHealthMonitorInterface.addNeutronLoadBalancerHealthMonitor(singleton);
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerHealthMonitorAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
+ int status = service.canCreateNeutronLoadBalancerHealthMonitor(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ loadBalancerHealthMonitorInterface.addNeutronLoadBalancerHealthMonitor(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
+ service.neutronLoadBalancerHealthMonitorCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronLoadBalancerHealthMonitor> bulk = input.getBulk();
+ Iterator<NeutronLoadBalancerHealthMonitor> i = bulk.iterator();
+ HashMap<String, NeutronLoadBalancerHealthMonitor> testMap = new HashMap<String, NeutronLoadBalancerHealthMonitor>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerHealthMonitorAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronLoadBalancerHealthMonitor test = i.next();
+
+ /*
+ * Verify that the firewall policy doesn't already exist
+ */
+
+ if (loadBalancerHealthMonitorInterface
+ .neutronLoadBalancerHealthMonitorExists(test.getLoadBalancerHealthMonitorID())) {
+ throw new BadRequestException("LoadBalancerHealthMonitor UUID already is already created");
+ }
+ if (testMap.containsKey(test.getLoadBalancerHealthMonitorID())) {
+ throw new BadRequestException("LoadBalancerHealthMonitor UUID already exists");
+ }
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
+ int status = service.canCreateNeutronLoadBalancerHealthMonitor(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()) {
+ NeutronLoadBalancerHealthMonitor test = i.next();
+ loadBalancerHealthMonitorInterface.addNeutronLoadBalancerHealthMonitor(test);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
+ service.neutronLoadBalancerHealthMonitorCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a LoadBalancerHealthMonitor Policy
+ */
+ @Path("{loadBalancerHealthMonitorID}")
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response updateLoadBalancerHealthMonitor(
+ @PathParam("loadBalancerHealthMonitorID") String loadBalancerHealthMonitorID,
+ final NeutronLoadBalancerHealthMonitorRequest input) {
+ INeutronLoadBalancerHealthMonitorCRUD loadBalancerHealthMonitorInterface = NeutronCRUDInterfaces
+ .getINeutronLoadBalancerHealthMonitorCRUD(this);
+ if (loadBalancerHealthMonitorInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerHealthMonitor CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the LoadBalancerHealthMonitor exists and there is only one delta provided
+ */
+ if (!loadBalancerHealthMonitorInterface.neutronLoadBalancerHealthMonitorExists(loadBalancerHealthMonitorID)) {
+ throw new ResourceNotFoundException("LoadBalancerHealthMonitor UUID does not exist.");
+ }
+ if (!input.isSingleton()) {
+ throw new BadRequestException("Only singleton edit supported");
+ }
+ NeutronLoadBalancerHealthMonitor delta = input.getSingleton();
+ NeutronLoadBalancerHealthMonitor original = loadBalancerHealthMonitorInterface
+ .getNeutronLoadBalancerHealthMonitor(loadBalancerHealthMonitorID);
+
+ /*
+ * updates restricted by Neutron
+ */
+ if (delta.getLoadBalancerHealthMonitorID() != null ||
+ delta.getLoadBalancerHealthMonitorTenantID() != null ||
+ delta.getLoadBalancerHealthMonitorType() != null ||
+ delta.getLoadBalancerHealthMonitorDelay() != null ||
+ delta.getLoadBalancerHealthMonitorTimeout() != null ||
+ delta.getLoadBalancerHealthMonitorMaxRetries() != null ||
+ delta.getLoadBalancerHealthMonitorHttpMethod() != null ||
+ delta.getLoadBalancerHealthMonitorUrlPath() != null ||
+ delta.getLoadBalancerHealthMonitorExpectedCodes() != null ||
+ delta.getLoadBalancerHealthMonitorAdminStateIsUp() != null ||
+ delta.getLoadBalancerHealthMonitorStatus() != null) {
+ throw new BadRequestException("Attribute edit blocked by Neutron");
+ }
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerHealthMonitorAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
+ int status = service.canUpdateNeutronLoadBalancerHealthMonitor(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * update the object and return it
+ */
+ loadBalancerHealthMonitorInterface.updateNeutronLoadBalancerHealthMonitor(loadBalancerHealthMonitorID, delta);
+ NeutronLoadBalancerHealthMonitor updatedLoadBalancerHealthMonitor = loadBalancerHealthMonitorInterface
+ .getNeutronLoadBalancerHealthMonitor(loadBalancerHealthMonitorID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
+ service.neutronLoadBalancerHealthMonitorUpdated(updatedLoadBalancerHealthMonitor);
+ }
+ }
+ return Response.status(200).entity(new NeutronLoadBalancerHealthMonitorRequest
+ (loadBalancerHealthMonitorInterface.getNeutronLoadBalancerHealthMonitor
+ (loadBalancerHealthMonitorID))).build();
+ }
+
+
+
+ /**
+ * Deletes a LoadBalancerHealthMonitor
+ * */
+ @Path("{loadBalancerHealthMonitorID}")
+ @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 deleteLoadBalancerHealthMonitor(
+ @PathParam("loadBalancerHealthMonitorID") String loadBalancerHealthMonitorID) {
+ INeutronLoadBalancerHealthMonitorCRUD loadBalancerHealthMonitorInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerHealthMonitorCRUD(this);
+ if (loadBalancerHealthMonitorInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerHealthMonitor CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ /*
+ * verify the LoadBalancerHealthMonitor exists and it isn't currently in use
+ */
+ if (!loadBalancerHealthMonitorInterface.neutronLoadBalancerHealthMonitorExists(loadBalancerHealthMonitorID)) {
+ throw new ResourceNotFoundException("LoadBalancerHealthMonitor UUID does not exist.");
+ }
+ if (loadBalancerHealthMonitorInterface.neutronLoadBalancerHealthMonitorInUse(loadBalancerHealthMonitorID)) {
+ return Response.status(409).build();
+ }
+ NeutronLoadBalancerHealthMonitor singleton = loadBalancerHealthMonitorInterface.getNeutronLoadBalancerHealthMonitor(loadBalancerHealthMonitorID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerHealthMonitorAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
+ int status = service.canDeleteNeutronLoadBalancerHealthMonitor(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ loadBalancerHealthMonitorInterface.removeNeutronLoadBalancerHealthMonitor(loadBalancerHealthMonitorID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerHealthMonitorAware service = (INeutronLoadBalancerHealthMonitorAware) instance;
+ service.neutronLoadBalancerHealthMonitorDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerHealthMonitor;
+
+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 java.util.List;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronLoadBalancerHealthMonitorRequest {
+ /**
+ * See OpenStack Network API v2.0 Reference for description of
+ * http://docs.openstack.org/api/openstack-network/2.0/content/
+ */
+
+ @XmlElement(name="healthmonitor")
+ NeutronLoadBalancerHealthMonitor singletonLoadBalancerHealthMonitor;
+
+ @XmlElement(name="healthmonitors")
+ List<NeutronLoadBalancerHealthMonitor> bulkRequest;
+
+ NeutronLoadBalancerHealthMonitorRequest() {
+ }
+
+ NeutronLoadBalancerHealthMonitorRequest(List<NeutronLoadBalancerHealthMonitor> bulk) {
+ bulkRequest = bulk;
+ singletonLoadBalancerHealthMonitor = null;
+ }
+
+ NeutronLoadBalancerHealthMonitorRequest(NeutronLoadBalancerHealthMonitor group) {
+ singletonLoadBalancerHealthMonitor = group;
+ }
+
+ public List<NeutronLoadBalancerHealthMonitor> getBulk() {
+ return bulkRequest;
+ }
+
+ public NeutronLoadBalancerHealthMonitor getSingleton() {
+ return singletonLoadBalancerHealthMonitor;
+ }
+
+ public boolean isSingleton() {
+ return (singletonLoadBalancerHealthMonitor != null);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerListenerAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerListenerCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerListener;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+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 java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Neutron Northbound REST APIs for LoadBalancerListener Policies.<br>
+ * This class provides REST APIs for managing neutron LoadBalancerListener Policies
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+@Path("/listeners")
+public class NeutronLoadBalancerListenerNorthbound {
+
+ private NeutronLoadBalancerListener extractFields(NeutronLoadBalancerListener o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all LoadBalancerListener */
+ @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 listGroups(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // OpenStack LoadBalancerListener attributes
+ @QueryParam("id") String queryLoadBalancerListenerID,
+ @QueryParam("default_pool_id") String queryLoadBalancerListenerDefaultPoolID,
+ @QueryParam("tenant_id") String queryLoadBalancerListenerTenantID,
+ @QueryParam("name") String queryLoadBalancerListenerName,
+ @QueryParam("description") String queryLoadBalancerListenerDescription,
+ @QueryParam("shared") String queryLoadBalancerListenerIsShared,
+ @QueryParam("protocol") String queryLoadBalancerListenerProtocol,
+ @QueryParam("protocol_port") String queryLoadBalancerListenerProtocolPort,
+ @QueryParam("load_balancer_id") String queryLoadBalancerListenerLoadBalancerID,
+ @QueryParam("admin_state_up") String queryLoadBalancerListenerAdminIsUp,
+ @QueryParam("status") String queryLoadBalancerListenerStatus,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronLoadBalancerListenerCRUD loadBalancerListenerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerListenerCRUD(this);
+ // INeutronLoadBalancerListenerRuleCRUD firewallRuleInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerListenerRuleCRUD(this);
+
+ if (loadBalancerListenerInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerListener CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronLoadBalancerListener> allLoadBalancerListeners = loadBalancerListenerInterface.getAllNeutronLoadBalancerListeners();
+ // List<NeutronLoadBalancerListenerRule> allLoadBalancerListenerRules = firewallRuleInterface.getAllNeutronLoadBalancerListenerRules();
+ List<NeutronLoadBalancerListener> ans = new ArrayList<NeutronLoadBalancerListener>();
+ // List<NeutronLoadBalancerListenerRule> rules = new ArrayList<NeutronLoadBalancerListenerRule>();
+ Iterator<NeutronLoadBalancerListener> i = allLoadBalancerListeners.iterator();
+ while (i.hasNext()) {
+ NeutronLoadBalancerListener nsg = i.next();
+ if ((queryLoadBalancerListenerID == null ||
+ queryLoadBalancerListenerID.equals(nsg.getLoadBalancerListenerID())) &&
+ (queryLoadBalancerListenerDefaultPoolID == null ||
+ queryLoadBalancerListenerDefaultPoolID.equals(nsg.getNeutronLoadBalancerListenerDefaultPoolID())) &&
+ (queryLoadBalancerListenerTenantID == null ||
+ queryLoadBalancerListenerTenantID.equals(nsg.getLoadBalancerListenerTenantID())) &&
+ (queryLoadBalancerListenerName == null ||
+ queryLoadBalancerListenerName.equals(nsg.getLoadBalancerListenerName())) &&
+ (queryLoadBalancerListenerDescription == null ||
+ queryLoadBalancerListenerDescription.equals(nsg.getLoadBalancerListenerDescription())) &&
+ (queryLoadBalancerListenerIsShared == null ||
+ queryLoadBalancerListenerIsShared.equals(nsg.getLoadBalancerListenerIsShared())) &&
+ (queryLoadBalancerListenerProtocol == null ||
+ queryLoadBalancerListenerProtocol.equals(nsg.getNeutronLoadBalancerListenerProtocol())) &&
+ (queryLoadBalancerListenerProtocolPort == null ||
+ queryLoadBalancerListenerProtocolPort.equals(nsg.getNeutronLoadBalancerListenerProtocolPort())) &&
+ (queryLoadBalancerListenerLoadBalancerID == null ||
+ queryLoadBalancerListenerLoadBalancerID.equals(nsg.getNeutronLoadBalancerListenerLoadBalancerID())) &&
+ (queryLoadBalancerListenerAdminIsUp == null ||
+ queryLoadBalancerListenerAdminIsUp.equals(nsg.getLoadBalancerListenerAdminStateIsUp())) &&
+ (queryLoadBalancerListenerStatus == null ||
+ queryLoadBalancerListenerStatus.equals(nsg.getLoadBalancerListenerStatus()))) {
+ if (fields.size() > 0) {
+ ans.add(extractFields(nsg,fields));
+ } else {
+ ans.add(nsg);
+ }
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronLoadBalancerListenerRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific LoadBalancerListener */
+
+ @Path("{loadBalancerListenerID}")
+ @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 showLoadBalancerListener(@PathParam("loadBalancerListenerID") String loadBalancerListenerID,
+ // return fields
+ @QueryParam("fields") List<String> fields) {
+ INeutronLoadBalancerListenerCRUD loadBalancerListenerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerListenerCRUD(this);
+ if (loadBalancerListenerInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerListener CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!loadBalancerListenerInterface.neutronLoadBalancerListenerExists(loadBalancerListenerID)) {
+ throw new ResourceNotFoundException("LoadBalancerListener UUID does not exist.");
+ }
+ if (fields.size() > 0) {
+ NeutronLoadBalancerListener ans = loadBalancerListenerInterface.getNeutronLoadBalancerListener(loadBalancerListenerID);
+ return Response.status(200).entity(
+ new NeutronLoadBalancerListenerRequest(extractFields(ans, fields))).build();
+ } else {
+ return Response.status(200).entity(new NeutronLoadBalancerListenerRequest(loadBalancerListenerInterface.getNeutronLoadBalancerListener(loadBalancerListenerID))).build();
+ }
+ }
+
+ /**
+ * Creates new LoadBalancerListener */
+
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response createLoadBalancerListeners(final NeutronLoadBalancerListenerRequest input) {
+ INeutronLoadBalancerListenerCRUD loadBalancerListenerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerListenerCRUD(this);
+ if (loadBalancerListenerInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerListener CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronLoadBalancerListener singleton = input.getSingleton();
+
+ /*
+ * Verify that the LoadBalancerListener doesn't already exist.
+ */
+ if (loadBalancerListenerInterface.neutronLoadBalancerListenerExists(singleton.getLoadBalancerListenerID())) {
+ throw new BadRequestException("LoadBalancerListener UUID already exists");
+ }
+ loadBalancerListenerInterface.addNeutronLoadBalancerListener(singleton);
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerListenerAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
+ int status = service.canCreateNeutronLoadBalancerListener(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ loadBalancerListenerInterface.addNeutronLoadBalancerListener(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
+ service.neutronLoadBalancerListenerCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronLoadBalancerListener> bulk = input.getBulk();
+ Iterator<NeutronLoadBalancerListener> i = bulk.iterator();
+ HashMap<String, NeutronLoadBalancerListener> testMap = new HashMap<String, NeutronLoadBalancerListener>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerListenerAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronLoadBalancerListener test = i.next();
+
+ /*
+ * Verify that the firewall policy doesn't already exist
+ */
+
+ if (loadBalancerListenerInterface.neutronLoadBalancerListenerExists(test.getLoadBalancerListenerID())) {
+ throw new BadRequestException("LoadBalancerListener UUID already is already created");
+ }
+ if (testMap.containsKey(test.getLoadBalancerListenerID())) {
+ throw new BadRequestException("LoadBalancerListener UUID already exists");
+ }
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
+ int status = service.canCreateNeutronLoadBalancerListener(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()) {
+ NeutronLoadBalancerListener test = i.next();
+ loadBalancerListenerInterface.addNeutronLoadBalancerListener(test);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
+ service.neutronLoadBalancerListenerCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a LoadBalancerListener Policy
+ */
+ @Path("{loadBalancerListenerID}")
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response updateLoadBalancerListener(
+ @PathParam("loadBalancerListenerID") String loadBalancerListenerID, final NeutronLoadBalancerListenerRequest input) {
+ INeutronLoadBalancerListenerCRUD loadBalancerListenerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerListenerCRUD(this);
+ if (loadBalancerListenerInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerListener CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the LoadBalancerListener exists and there is only one delta provided
+ */
+ if (!loadBalancerListenerInterface.neutronLoadBalancerListenerExists(loadBalancerListenerID)) {
+ throw new ResourceNotFoundException("LoadBalancerListener UUID does not exist.");
+ }
+ if (!input.isSingleton()) {
+ throw new BadRequestException("Only singleton edit supported");
+ }
+ NeutronLoadBalancerListener delta = input.getSingleton();
+ NeutronLoadBalancerListener original = loadBalancerListenerInterface.getNeutronLoadBalancerListener(loadBalancerListenerID);
+
+ /*
+ * updates restricted by Neutron
+ */
+ if (delta.getLoadBalancerListenerID() != null ||
+ delta.getNeutronLoadBalancerListenerDefaultPoolID() != null ||
+ delta.getLoadBalancerListenerTenantID() != null ||
+ delta.getLoadBalancerListenerName() != null ||
+ delta.getLoadBalancerListenerDescription() != null ||
+ delta.getLoadBalancerListenerIsShared() != null ||
+ delta.getNeutronLoadBalancerListenerProtocol() != null ||
+ delta.getNeutronLoadBalancerListenerProtocolPort() != null ||
+ delta.getNeutronLoadBalancerListenerLoadBalancerID() != null ||
+ delta.getLoadBalancerListenerAdminStateIsUp() != null ||
+ delta.getLoadBalancerListenerStatus() != null) {
+ throw new BadRequestException("Attribute edit blocked by Neutron");
+ }
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerListenerAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
+ int status = service.canUpdateNeutronLoadBalancerListener(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * update the object and return it
+ */
+ loadBalancerListenerInterface.updateNeutronLoadBalancerListener(loadBalancerListenerID, delta);
+ NeutronLoadBalancerListener updatedLoadBalancerListener = loadBalancerListenerInterface.getNeutronLoadBalancerListener(loadBalancerListenerID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
+ service.neutronLoadBalancerListenerUpdated(updatedLoadBalancerListener);
+ }
+ }
+ return Response.status(200).entity(new NeutronLoadBalancerListenerRequest(loadBalancerListenerInterface.getNeutronLoadBalancerListener(loadBalancerListenerID))).build();
+ }
+
+ /**
+ * Deletes a LoadBalancerListener */
+
+ @Path("{loadBalancerListenerID}")
+ @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 deleteLoadBalancerListener(
+ @PathParam("loadBalancerListenerID") String loadBalancerListenerID) {
+ INeutronLoadBalancerListenerCRUD loadBalancerListenerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerListenerCRUD(this);
+ if (loadBalancerListenerInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerListener CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the LoadBalancerListener exists and it isn't currently in use
+ */
+ if (!loadBalancerListenerInterface.neutronLoadBalancerListenerExists(loadBalancerListenerID)) {
+ throw new ResourceNotFoundException("LoadBalancerListener UUID does not exist.");
+ }
+ if (loadBalancerListenerInterface.neutronLoadBalancerListenerInUse(loadBalancerListenerID)) {
+ return Response.status(409).build();
+ }
+ NeutronLoadBalancerListener singleton = loadBalancerListenerInterface.getNeutronLoadBalancerListener(loadBalancerListenerID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerListenerAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
+ int status = service.canDeleteNeutronLoadBalancerListener(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ loadBalancerListenerInterface.removeNeutronLoadBalancerListener(loadBalancerListenerID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerListenerAware service = (INeutronLoadBalancerListenerAware) instance;
+ service.neutronLoadBalancerListenerDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerListener;
+
+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 java.util.List;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronLoadBalancerListenerRequest {
+ /**
+ * See OpenStack Network API v2.0 Reference for description of
+ * http://docs.openstack.org/api/openstack-network/2.0/content/
+ */
+
+ @XmlElement(name="listener")
+ NeutronLoadBalancerListener singletonLoadBalancerListener;
+
+ @XmlElement(name="listeners")
+ List<NeutronLoadBalancerListener> bulkRequest;
+
+ NeutronLoadBalancerListenerRequest() {
+ }
+
+ NeutronLoadBalancerListenerRequest(List<NeutronLoadBalancerListener> bulk) {
+ bulkRequest = bulk;
+ singletonLoadBalancerListener = null;
+ }
+
+ NeutronLoadBalancerListenerRequest(NeutronLoadBalancerListener group) {
+ singletonLoadBalancerListener = group;
+ }
+
+ public List<NeutronLoadBalancerListener> getBulk() {
+ return bulkRequest;
+ }
+
+ public NeutronLoadBalancerListener getSingleton() {
+ return singletonLoadBalancerListener;
+ }
+
+ public boolean isSingleton() {
+ return (singletonLoadBalancerListener != null);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancer;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+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 java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Neutron Northbound REST APIs for LoadBalancers.<br>
+ * This class provides REST APIs for managing neutron LoadBalancers
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+@Path("/loadbalancers")
+public class NeutronLoadBalancerNorthbound {
+
+ private NeutronLoadBalancer extractFields(NeutronLoadBalancer o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all LoadBalancer */
+ @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 listGroups(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // OpenStack LoadBalancer attributes
+ @QueryParam("id") String queryLoadBalancerID,
+ @QueryParam("tenant_id") String queryLoadBalancerTenantID,
+ @QueryParam("name") String queryLoadBalancerName,
+ @QueryParam("description") String queryLoadBalancerDescription,
+ @QueryParam("status") String queryLoadBalancerStatus,
+ @QueryParam("vip_address") String queryLoadBalancerVipAddress,
+ @QueryParam("vip_subnet") String queryLoadBalancerVipSubnet,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(this);
+
+ if (loadBalancerInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronLoadBalancer> allLoadBalancers = loadBalancerInterface.getAllNeutronLoadBalancers();
+ // List<NeutronLoadBalancerRule> allLoadBalancerRules = firewallRuleInterface.getAllNeutronLoadBalancerRules();
+ List<NeutronLoadBalancer> ans = new ArrayList<NeutronLoadBalancer>();
+ // List<NeutronLoadBalancerRule> rules = new ArrayList<NeutronLoadBalancerRule>();
+ Iterator<NeutronLoadBalancer> i = allLoadBalancers.iterator();
+ while (i.hasNext()) {
+ NeutronLoadBalancer nsg = i.next();
+ if ((queryLoadBalancerID == null ||
+ queryLoadBalancerID.equals(nsg.getLoadBalancerID())) &&
+ (queryLoadBalancerTenantID == null ||
+ queryLoadBalancerTenantID.equals(nsg.getLoadBalancerTenantID())) &&
+ (queryLoadBalancerName == null ||
+ queryLoadBalancerName.equals(nsg.getLoadBalancerName())) &&
+ (queryLoadBalancerDescription == null ||
+ queryLoadBalancerDescription.equals(nsg.getLoadBalancerDescription())) &&
+ (queryLoadBalancerVipAddress == null ||
+ queryLoadBalancerVipAddress.equals(nsg.getLoadBalancerVipAddress())) &&
+ (queryLoadBalancerVipSubnet == null ||
+ queryLoadBalancerVipSubnet.equals(nsg.getLoadBalancerVipSubnetID()))) {
+ if (fields.size() > 0) {
+ ans.add(extractFields(nsg,fields));
+ } else {
+ ans.add(nsg);
+ }
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronLoadBalancerRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific LoadBalancer */
+
+ @Path("{loadBalancerID}")
+ @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 showLoadBalancer(@PathParam("loadBalancerID") String loadBalancerID,
+ // return fields
+ @QueryParam("fields") List<String> fields) {
+ INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
+ this);
+ if (loadBalancerInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
+ throw new ResourceNotFoundException("LoadBalancer UUID does not exist.");
+ }
+ if (fields.size() > 0) {
+ NeutronLoadBalancer ans = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
+ return Response.status(200).entity(
+ new NeutronLoadBalancerRequest(extractFields(ans, fields))).build();
+ } else {
+ return Response.status(200).entity(new NeutronLoadBalancerRequest(loadBalancerInterface.getNeutronLoadBalancer(
+ loadBalancerID))).build();
+ }
+ }
+
+ /**
+ * Creates new LoadBalancer */
+
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response createLoadBalancers(final NeutronLoadBalancerRequest input) {
+ INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
+ this);
+ if (loadBalancerInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronLoadBalancer singleton = input.getSingleton();
+
+ /*
+ * Verify that the LoadBalancer doesn't already exist.
+ */
+ if (loadBalancerInterface.neutronLoadBalancerExists(singleton.getLoadBalancerID())) {
+ throw new BadRequestException("LoadBalancer UUID already exists");
+ }
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
+ int status = service.canCreateNeutronLoadBalancer(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ loadBalancerInterface.addNeutronLoadBalancer(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
+ service.neutronLoadBalancerCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronLoadBalancer> bulk = input.getBulk();
+ Iterator<NeutronLoadBalancer> i = bulk.iterator();
+ HashMap<String, NeutronLoadBalancer> testMap = new HashMap<String, NeutronLoadBalancer>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronLoadBalancer test = i.next();
+
+ /*
+ * Verify that the loadbalancer doesn't already exist
+ */
+
+ if (loadBalancerInterface.neutronLoadBalancerExists(test.getLoadBalancerID())) {
+ throw new BadRequestException("Load Balancer Pool UUID already is already created");
+ }
+ if (testMap.containsKey(test.getLoadBalancerID())) {
+ throw new BadRequestException("Load Balancer Pool UUID already exists");
+ }
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
+ int status = service.canCreateNeutronLoadBalancer(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()) {
+ NeutronLoadBalancer test = i.next();
+ loadBalancerInterface.addNeutronLoadBalancer(test);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
+ service.neutronLoadBalancerCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a LoadBalancer Policy
+ */
+ @Path("{loadBalancerID}")
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response updateLoadBalancer(
+ @PathParam("loadBalancerID") String loadBalancerID, final NeutronLoadBalancerRequest input) {
+ INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
+ this);
+ if (loadBalancerInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the LoadBalancer exists and there is only one delta provided
+ */
+ if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
+ throw new ResourceNotFoundException("LoadBalancer UUID does not exist.");
+ }
+ if (!input.isSingleton()) {
+ throw new BadRequestException("Only singleton edit supported");
+ }
+ NeutronLoadBalancer delta = input.getSingleton();
+ NeutronLoadBalancer original = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
+
+ /*
+ * updates restricted by Neutron
+ */
+ if (delta.getLoadBalancerID() != null ||
+ delta.getLoadBalancerTenantID() != null ||
+ delta.getLoadBalancerName() != null ||
+ delta.getLoadBalancerDescription() != null ||
+ delta.getLoadBalancerStatus() != null ||
+ delta.getLoadBalancerVipAddress() != null ||
+ delta.getLoadBalancerVipSubnetID() != null) {
+ throw new BadRequestException("Attribute edit blocked by Neutron");
+ }
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
+ int status = service.canUpdateNeutronLoadBalancer(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * update the object and return it
+ */
+ loadBalancerInterface.updateNeutronLoadBalancer(loadBalancerID, delta);
+ NeutronLoadBalancer updatedLoadBalancer = loadBalancerInterface.getNeutronLoadBalancer(
+ loadBalancerID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
+ service.neutronLoadBalancerUpdated(updatedLoadBalancer);
+ }
+ }
+ return Response.status(200).entity(new NeutronLoadBalancerRequest(loadBalancerInterface.getNeutronLoadBalancer(
+ loadBalancerID))).build();
+ }
+
+ /**
+ * Deletes a LoadBalancer */
+
+ @Path("{loadBalancerID}")
+ @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 deleteLoadBalancer(
+ @PathParam("loadBalancerID") String loadBalancerID) {
+ INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
+ this);
+ if (loadBalancerInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the LoadBalancer exists and it isn't currently in use
+ */
+ if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
+ throw new ResourceNotFoundException("LoadBalancer UUID does not exist.");
+ }
+ if (loadBalancerInterface.neutronLoadBalancerInUse(loadBalancerID)) {
+ return Response.status(409).build();
+ }
+ NeutronLoadBalancer singleton = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
+ int status = service.canDeleteNeutronLoadBalancer(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ loadBalancerInterface.removeNeutronLoadBalancer(loadBalancerID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
+ service.neutronLoadBalancerDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPoolMember;
+
+import javax.xml.bind.annotation.XmlElement;
+import java.util.List;
+
+public class NeutronLoadBalancerPoolMemberRequest {
+
+ /**
+ * See OpenStack Network API v2.0 Reference for description of
+ * http://docs.openstack.org/api/openstack-network/2.0/content/
+ */
+
+ @XmlElement(name="member")
+ NeutronLoadBalancerPoolMember singletonLoadBalancerPoolMember;
+
+ @XmlElement(name="members")
+ List<NeutronLoadBalancerPoolMember> bulkRequest;
+
+ NeutronLoadBalancerPoolMemberRequest() {
+ }
+
+ NeutronLoadBalancerPoolMemberRequest(List<NeutronLoadBalancerPoolMember> bulk) {
+ bulkRequest = bulk;
+ singletonLoadBalancerPoolMember = null;
+ }
+
+ NeutronLoadBalancerPoolMemberRequest(NeutronLoadBalancerPoolMember group) {
+ singletonLoadBalancerPoolMember = group;
+ }
+
+ public List<NeutronLoadBalancerPoolMember> getBulk() {
+ return bulkRequest;
+ }
+
+ public NeutronLoadBalancerPoolMember getSingleton() {
+ return singletonLoadBalancerPoolMember;
+ }
+
+ public boolean isSingleton() {
+ return (singletonLoadBalancerPoolMember != null);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2014 SDN Hub, LLC.
+ *
+ * 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
+ *
+ * Authors : Srini Seetharaman
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolMemberAware;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool;
+import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPoolMember;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+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 java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+@Path("/pools/{loadBalancerPoolUUID}/members")
+public class NeutronLoadBalancerPoolMembersNorthbound {
+ private NeutronLoadBalancerPoolMember extractFields(NeutronLoadBalancerPoolMember o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+/**
+ * Returns a list of all LoadBalancerPoolMembers in specified pool
+ */
+@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 listMembers(
+ //Path param
+ @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
+
+ // return fields
+ @QueryParam("fields") List<String> fields,
+
+ // OpenStack LoadBalancerPool attributes
+ @QueryParam("id") String queryLoadBalancerPoolMemberID,
+ @QueryParam("tenant_id") String queryLoadBalancerPoolMemberTenantID,
+ @QueryParam("address") String queryLoadBalancerPoolMemberAddress,
+ @QueryParam("protocol_port") String queryLoadBalancerPoolMemberProtoPort,
+ @QueryParam("admin_state_up") String queryLoadBalancerPoolMemberAdminStateUp,
+ @QueryParam("weight") String queryLoadBalancerPoolMemberWeight,
+ @QueryParam("subnet_id") String queryLoadBalancerPoolMemberSubnetID,
+ @QueryParam("status") String queryLoadBalancerPoolMemberStatus,
+
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+) {
+ INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces
+ .getINeutronLoadBalancerPoolCRUD(this);
+ if (loadBalancerPoolInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
+ throw new ResourceNotFoundException("loadBalancerPool UUID does not exist.");
+ }
+ List<NeutronLoadBalancerPoolMember> members =
+ loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID).getLoadBalancerPoolMembers();
+ List<NeutronLoadBalancerPoolMember> ans = new ArrayList<NeutronLoadBalancerPoolMember>();
+ Iterator<NeutronLoadBalancerPoolMember> i = members.iterator();
+ while (i.hasNext()) {
+ NeutronLoadBalancerPoolMember nsg = i.next();
+ if ((queryLoadBalancerPoolMemberID == null ||
+ queryLoadBalancerPoolMemberID.equals(nsg.getPoolMemberID())) &&
+ loadBalancerPoolUUID.equals(nsg.getPoolID()) &&
+ (queryLoadBalancerPoolMemberTenantID == null ||
+ queryLoadBalancerPoolMemberTenantID.equals(nsg.getPoolMemberTenantID())) &&
+ (queryLoadBalancerPoolMemberAddress == null ||
+ queryLoadBalancerPoolMemberAddress.equals(nsg.getPoolMemberAddress())) &&
+ (queryLoadBalancerPoolMemberAdminStateUp == null ||
+ queryLoadBalancerPoolMemberAdminStateUp.equals(nsg.getPoolMemberAdminStateIsUp())) &&
+ (queryLoadBalancerPoolMemberWeight == null ||
+ queryLoadBalancerPoolMemberWeight.equals(nsg.getPoolMemberWeight())) &&
+ (queryLoadBalancerPoolMemberSubnetID == null ||
+ queryLoadBalancerPoolMemberSubnetID.equals(nsg.getPoolMemberSubnetID())) &&
+ (queryLoadBalancerPoolMemberStatus == null ||
+ queryLoadBalancerPoolMemberStatus.equals(nsg.getPoolMemberStatus()))) {
+ if (fields.size() > 0) {
+ ans.add(extractFields(nsg, fields));
+ } else {
+ ans.add(nsg);
+ }
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronLoadBalancerPoolMemberRequest(ans)).build();
+}
+
+/**
+ * Returns a specific LoadBalancerPoolMember
+ */
+
+@Path("{loadBalancerPoolMemberUUID}")
+@GET
+@Produces({ MediaType.APPLICATION_JSON })
+//@TypeHint(OpenStackLoadBalancerPoolMembers.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 showLoadBalancerPoolMember(
+ @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
+ @PathParam("loadBalancerPoolMemberUUID") String loadBalancerPoolMemberUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields ) {
+
+ INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces
+ .getINeutronLoadBalancerPoolCRUD(this);
+ if (loadBalancerPoolInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
+ throw new ResourceNotFoundException("loadBalancerPool UUID does not exist.");
+ }
+ List<NeutronLoadBalancerPoolMember> members =
+ loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID).getLoadBalancerPoolMembers();
+ for (NeutronLoadBalancerPoolMember ans: members) {
+ if (!ans.getPoolMemberID().equals(loadBalancerPoolMemberUUID))
+ continue;
+
+ if (fields.size() > 0) {
+ return Response.status(200).entity(
+ new NeutronLoadBalancerPoolMemberRequest(extractFields(ans, fields))).build();
+ } else {
+ return Response.status(200).entity(
+ new NeutronLoadBalancerPoolMemberRequest(ans)).build();
+ }
+ }
+ return Response.status(204).build();
+}
+
+/**
+ * Adds a Member to an LBaaS Pool member
+ */
+@PUT
+@Produces({MediaType.APPLICATION_JSON})
+@Consumes({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 createLoadBalancerPoolMember(
+ @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
+ final NeutronLoadBalancerPoolMemberRequest input) {
+
+ INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolCRUD(this);
+ if (loadBalancerPoolInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ // Verify that the loadBalancerPool exists, for the member to be added to its cache
+ if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
+ throw new ResourceNotFoundException("loadBalancerPool UUID does not exist.");
+ }
+ NeutronLoadBalancerPool singletonPool = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID);
+
+ if (input.isSingleton()) {
+ NeutronLoadBalancerPoolMember singleton = input.getSingleton();
+ singleton.setPoolID(loadBalancerPoolUUID);
+ String loadBalancerPoolMemberUUID = singleton.getPoolMemberID();
+
+ /*
+ * Verify that the LoadBalancerPoolMember doesn't already exist.
+ */
+ List<NeutronLoadBalancerPoolMember> members = singletonPool.getLoadBalancerPoolMembers();
+ for (NeutronLoadBalancerPoolMember member: members) {
+ if (member.getPoolMemberID().equals(loadBalancerPoolMemberUUID))
+ throw new BadRequestException("LoadBalancerPoolMember UUID already exists");
+ }
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerPoolMemberAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
+ int status = service.canCreateNeutronLoadBalancerPoolMember(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
+ service.neutronLoadBalancerPoolMemberCreated(singleton);
+ }
+ }
+
+ /**
+ * Add the member from the neutron load balancer pool as well
+ */
+ singletonPool.addLoadBalancerPoolMember(singleton);
+
+ } else {
+ List<NeutronLoadBalancerPoolMember> bulk = input.getBulk();
+ Iterator<NeutronLoadBalancerPoolMember> i = bulk.iterator();
+ HashMap<String, NeutronLoadBalancerPoolMember> testMap = new HashMap<String, NeutronLoadBalancerPoolMember>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerPoolMemberAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronLoadBalancerPoolMember test = i.next();
+ String loadBalancerPoolMemberUUID = test.getPoolMemberID();
+
+ /*
+ * Verify that the LoadBalancerPoolMember doesn't already exist.
+ */
+ List<NeutronLoadBalancerPoolMember> members = singletonPool.getLoadBalancerPoolMembers();
+ for (NeutronLoadBalancerPoolMember member: members) {
+ if (member.getPoolMemberID().equals(loadBalancerPoolMemberUUID))
+ throw new BadRequestException("LoadBalancerPoolMember UUID already exists");
+ }
+
+ if (testMap.containsKey(test.getPoolMemberID())) {
+ throw new BadRequestException("Load Balancer PoolMember UUID already exists");
+ }
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
+ int status = service.canCreateNeutronLoadBalancerPoolMember(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()) {
+ NeutronLoadBalancerPoolMember test = i.next();
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
+ service.neutronLoadBalancerPoolMemberCreated(test);
+ }
+ }
+ singletonPool.addLoadBalancerPoolMember(test);
+ }
+ }
+ return Response.status(201).entity(input).build();
+}
+
+/**
+ * Updates a LB member pool
+ */
+
+@Path("{loadBalancerPoolMemberUUID}")
+@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 = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+public Response updateLoadBalancerPoolMember(
+ @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
+ @PathParam("loadBalancerPoolMemberUUID") String loadBalancerPoolMemberUUID,
+ final NeutronLoadBalancerPoolMemberRequest input) {
+
+ //TODO: Implement update LB member pool
+ return Response.status(501).entity(input).build();
+}
+
+/**
+ * Deletes a LoadBalancerPoolMember
+ */
+
+@Path("{loadBalancerPoolMemberUUID}")
+@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 deleteLoadBalancerPoolMember(
+ @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
+ @PathParam("loadBalancerPoolMemberUUID") String loadBalancerPoolMemberUUID) {
+ INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolCRUD(this);
+ if (loadBalancerPoolInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ // Verify that the loadBalancerPool exists, for the member to be removed from its cache
+ if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
+ throw new ResourceNotFoundException("loadBalancerPool UUID does not exist.");
+ }
+
+ //Verify that the LB pool member exists
+ NeutronLoadBalancerPoolMember singleton = null;
+ List<NeutronLoadBalancerPoolMember> members =
+ loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID).getLoadBalancerPoolMembers();
+ for (NeutronLoadBalancerPoolMember member: members) {
+ if (member.getPoolMemberID().equals(loadBalancerPoolMemberUUID)) {
+ singleton = member;
+ break;
+ }
+ }
+ if (singleton == null)
+ throw new BadRequestException("LoadBalancerPoolMember UUID does not exist.");
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerPoolMemberAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
+ int status = service.canDeleteNeutronLoadBalancerPoolMember(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
+ service.neutronLoadBalancerPoolMemberDeleted(singleton);
+ }
+ }
+
+ /**
+ * Remove the member from the neutron load balancer pool
+ */
+ NeutronLoadBalancerPool singletonPool = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID);
+ singletonPool.removeLoadBalancerPoolMember(singleton);
+
+ return Response.status(204).build();
+}
+}
--- /dev/null
+/*
+ * Copyright (C) 2014 SDN Hub, LLC.
+ *
+ * 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
+ *
+ * Authors : Srini Seetharaman
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool;
+import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPoolMember;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+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 java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Neutron Northbound REST APIs for LoadBalancerPool Policies.<br>
+ * This class provides REST APIs for managing neutron LoadBalancerPool Policies
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+/**
+ * For now, the LB pool member data is maintained with the INeutronLoadBalancerPoolCRUD,
+ * and not duplicated within the INeutronLoadBalancerPoolMemberCRUD's cache.
+ */
+
+@Path("/pools")
+public class NeutronLoadBalancerPoolNorthbound {
+
+ private NeutronLoadBalancerPool extractFields(NeutronLoadBalancerPool o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all LoadBalancerPool
+ * */
+ @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 listGroups(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // OpenStack LoadBalancerPool attributes
+ @QueryParam("id") String queryLoadBalancerPoolID,
+ @QueryParam("tenant_id") String queryLoadBalancerPoolTenantID,
+ @QueryParam("name") String queryLoadBalancerPoolName,
+ @QueryParam("description") String queryLoadBalancerDescription,
+ @QueryParam("protocol") String queryLoadBalancerProtocol,
+ @QueryParam("lb_algorithm") String queryLoadBalancerPoolLbAlgorithm,
+ @QueryParam("healthmonitor_id") String queryLoadBalancerPoolHealthMonitorID,
+ @QueryParam("admin_state_up") String queryLoadBalancerIsAdminStateUp,
+ @QueryParam("status") String queryLoadBalancerPoolStatus,
+ @QueryParam("members") List<NeutronLoadBalancerPoolMember> queryLoadBalancerPoolMembers,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolCRUD(this);
+ if (loadBalancerPoolInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronLoadBalancerPool> allLoadBalancerPools = loadBalancerPoolInterface.getAllNeutronLoadBalancerPools();
+ List<NeutronLoadBalancerPool> ans = new ArrayList<NeutronLoadBalancerPool>();
+ Iterator<NeutronLoadBalancerPool> i = allLoadBalancerPools.iterator();
+ while (i.hasNext()) {
+ NeutronLoadBalancerPool nsg = i.next();
+ if ((queryLoadBalancerPoolID == null ||
+ queryLoadBalancerPoolID.equals(nsg.getLoadBalancerPoolID())) &&
+ (queryLoadBalancerPoolTenantID == null ||
+ queryLoadBalancerPoolTenantID.equals(nsg.getLoadBalancerPoolTenantID())) &&
+ (queryLoadBalancerPoolName == null ||
+ queryLoadBalancerPoolName.equals(nsg.getLoadBalancerPoolName())) &&
+ (queryLoadBalancerDescription == null ||
+ queryLoadBalancerDescription.equals(nsg.getLoadBalancerPoolDescription())) &&
+ (queryLoadBalancerPoolLbAlgorithm == null ||
+ queryLoadBalancerPoolLbAlgorithm.equals(nsg.getLoadBalancerPoolLbAlgorithm())) &&
+ (queryLoadBalancerPoolHealthMonitorID == null ||
+ queryLoadBalancerPoolHealthMonitorID.equals(nsg.getNeutronLoadBalancerPoolHealthMonitorID())) &&
+ (queryLoadBalancerIsAdminStateUp == null ||
+ queryLoadBalancerIsAdminStateUp.equals(nsg.getLoadBalancerPoolAdminIsStateIsUp())) &&
+ (queryLoadBalancerPoolStatus == null ||
+ queryLoadBalancerPoolStatus.equals(nsg.getLoadBalancerPoolStatus())) &&
+ (queryLoadBalancerPoolMembers.size() == 0 ||
+ queryLoadBalancerPoolMembers.equals(nsg.getLoadBalancerPoolMembers()))) {
+ if (fields.size() > 0) {
+ ans.add(extractFields(nsg,fields));
+ } else {
+ ans.add(nsg);
+ }
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronLoadBalancerPoolRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific LoadBalancerPool */
+
+ @Path("{loadBalancerPoolID}")
+ @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 showLoadBalancerPool(@PathParam("loadBalancerPoolID") String loadBalancerPoolID,
+ // return fields
+ @QueryParam("fields") List<String> fields) {
+ INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolCRUD(this);
+ if (loadBalancerPoolInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolID)) {
+ throw new ResourceNotFoundException("LoadBalancerPool UUID does not exist.");
+ }
+ if (fields.size() > 0) {
+ NeutronLoadBalancerPool ans = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolID);
+ return Response.status(200).entity(
+ new NeutronLoadBalancerPoolRequest(extractFields(ans, fields))).build();
+ } else {
+ return Response.status(200).entity(new NeutronLoadBalancerPoolRequest(loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolID))).build();
+ }
+ }
+
+ /**
+ * Creates new LoadBalancerPool */
+
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 409, condition = "Conflict"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response createLoadBalancerPools(final NeutronLoadBalancerPoolRequest input) {
+ INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolCRUD(this);
+ if (loadBalancerPoolInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (input.isSingleton()) {
+ NeutronLoadBalancerPool singleton = input.getSingleton();
+
+ /*
+ * Verify that the LoadBalancerPool doesn't already exist.
+ */
+ if (loadBalancerPoolInterface.neutronLoadBalancerPoolExists(singleton.getLoadBalancerPoolID())) {
+ throw new BadRequestException("LoadBalancerPool UUID already exists");
+ }
+ loadBalancerPoolInterface.addNeutronLoadBalancerPool(singleton);
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerPoolAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
+ int status = service.canCreateNeutronLoadBalancerPool(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ loadBalancerPoolInterface.addNeutronLoadBalancerPool(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
+ service.neutronLoadBalancerPoolCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronLoadBalancerPool> bulk = input.getBulk();
+ Iterator<NeutronLoadBalancerPool> i = bulk.iterator();
+ HashMap<String, NeutronLoadBalancerPool> testMap = new HashMap<String, NeutronLoadBalancerPool>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerPoolAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronLoadBalancerPool test = i.next();
+
+ /*
+ * Verify that the loadBalancerPool doesn't already exist
+ */
+
+ if (loadBalancerPoolInterface.neutronLoadBalancerPoolExists(test.getLoadBalancerPoolID())) {
+ throw new BadRequestException("Load Balancer Pool UUID already is already created");
+ }
+ if (testMap.containsKey(test.getLoadBalancerPoolID())) {
+ throw new BadRequestException("Load Balancer Pool UUID already exists");
+ }
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
+ int status = service.canCreateNeutronLoadBalancerPool(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()) {
+ NeutronLoadBalancerPool test = i.next();
+ loadBalancerPoolInterface.addNeutronLoadBalancerPool(test);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
+ service.neutronLoadBalancerPoolCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a LoadBalancerPool Policy
+ */
+ @Path("{loadBalancerPoolID}")
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response updateLoadBalancerPool(
+ @PathParam("loadBalancerPoolID") String loadBalancerPoolID, final NeutronLoadBalancerPoolRequest input) {
+ INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolCRUD(this);
+ if (loadBalancerPoolInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the LoadBalancerPool exists and there is only one delta provided
+ */
+ if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolID)) {
+ throw new ResourceNotFoundException("LoadBalancerPool UUID does not exist.");
+ }
+ if (!input.isSingleton()) {
+ throw new BadRequestException("Only singleton edit supported");
+ }
+ NeutronLoadBalancerPool delta = input.getSingleton();
+ NeutronLoadBalancerPool original = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolID);
+
+ /*
+ * updates restricted by Neutron
+ */
+ if (delta.getLoadBalancerPoolID() != null ||
+ delta.getLoadBalancerPoolTenantID() != null ||
+ delta.getLoadBalancerPoolName() != null ||
+ delta.getLoadBalancerPoolDescription() != null ||
+ delta.getLoadBalancerPoolProtocol() != null ||
+ delta.getLoadBalancerPoolLbAlgorithm() != null ||
+ delta.getNeutronLoadBalancerPoolHealthMonitorID() != null ||
+ delta.getLoadBalancerPoolAdminIsStateIsUp() != null ||
+ delta.getLoadBalancerPoolStatus() != null ||
+ delta.getLoadBalancerPoolMembers() != null) {
+ throw new BadRequestException("Attribute edit blocked by Neutron");
+ }
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerPoolAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
+ int status = service.canUpdateNeutronLoadBalancerPool(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * update the object and return it
+ */
+ loadBalancerPoolInterface.updateNeutronLoadBalancerPool(loadBalancerPoolID, delta);
+ NeutronLoadBalancerPool updatedLoadBalancerPool = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
+ service.neutronLoadBalancerPoolUpdated(updatedLoadBalancerPool);
+ }
+ }
+ return Response.status(200).entity(new NeutronLoadBalancerPoolRequest(loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolID))).build();
+ }
+
+ /**
+ * Deletes a LoadBalancerPool
+ */
+
+ @Path("{loadBalancerPoolUUID}")
+ @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 deleteLoadBalancerPool(
+ @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID) {
+ INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolCRUD(this);
+ if (loadBalancerPoolInterface == null) {
+ throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the LoadBalancerPool exists and it isn't currently in use
+ */
+ if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
+ throw new ResourceNotFoundException("LoadBalancerPool UUID does not exist.");
+ }
+ if (loadBalancerPoolInterface.neutronLoadBalancerPoolInUse(loadBalancerPoolUUID)) {
+ return Response.status(409).build();
+ }
+ NeutronLoadBalancerPool singleton = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerPoolAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
+ int status = service.canDeleteNeutronLoadBalancerPool(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * remove it and return 204 status
+ */
+ loadBalancerPoolInterface.removeNeutronLoadBalancerPool(loadBalancerPoolUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
+ service.neutronLoadBalancerPoolDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool;
+
+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 java.util.List;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronLoadBalancerPoolRequest {
+ /**
+ * See OpenStack Network API v2.0 Reference for description of
+ * http://docs.openstack.org/api/openstack-network/2.0/content/
+ */
+
+ @XmlElement(name="pool")
+ NeutronLoadBalancerPool singletonLoadBalancerPool;
+
+ @XmlElement(name="pools")
+ List<NeutronLoadBalancerPool> bulkRequest;
+
+ NeutronLoadBalancerPoolRequest() {
+ }
+
+ NeutronLoadBalancerPoolRequest(List<NeutronLoadBalancerPool> bulk) {
+ bulkRequest = bulk;
+ singletonLoadBalancerPool = null;
+ }
+
+ NeutronLoadBalancerPoolRequest(NeutronLoadBalancerPool group) {
+ singletonLoadBalancerPool = group;
+ }
+
+ public List<NeutronLoadBalancerPool> getBulk() {
+ return bulkRequest;
+ }
+
+ public NeutronLoadBalancerPool getSingleton() {
+ return singletonLoadBalancerPool;
+ }
+
+ public boolean isSingleton() {
+ return (singletonLoadBalancerPool != null);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancer;
+
+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 java.util.List;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronLoadBalancerRequest {
+ /**
+ * See OpenStack Network API v2.0 Reference for description of
+ * http://docs.openstack.org/api/openstack-network/2.0/content/
+ */
+
+ @XmlElement(name="loadbalancer")
+ NeutronLoadBalancer singletonLoadBalancer;
+
+ @XmlElement(name="loadbalancers")
+ List<NeutronLoadBalancer> bulkRequest;
+
+ NeutronLoadBalancerRequest() {
+ }
+
+ NeutronLoadBalancerRequest(List<NeutronLoadBalancer> bulk) {
+ bulkRequest = bulk;
+ singletonLoadBalancer = null;
+ }
+
+ NeutronLoadBalancerRequest(NeutronLoadBalancer group) {
+ singletonLoadBalancer = group;
+ }
+
+ public List<NeutronLoadBalancer> getBulk() {
+ return bulkRequest;
+ }
+
+ public NeutronLoadBalancer getSingleton() {
+ return singletonLoadBalancer;
+ }
+
+ public boolean isSingleton() {
+ return (singletonLoadBalancer != null);
+ }
+}
\ No newline at end of file
--- /dev/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.NeutronNetwork;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronNetworkRequest implements INeutronRequest<NeutronNetwork> {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="network")
+ NeutronNetwork singletonNetwork;
+
+ @XmlElement(name="networks")
+ List<NeutronNetwork> bulkRequest;
+
+ @XmlElement(name="networks_links")
+ List<NeutronPageLink> links;
+
+ NeutronNetworkRequest() {
+ }
+
+ NeutronNetworkRequest(List<NeutronNetwork> bulkRequest, List<NeutronPageLink> links) {
+ this.bulkRequest = bulkRequest;
+ this.links = links;
+ this.singletonNetwork = null;
+ }
+
+ NeutronNetworkRequest(List<NeutronNetwork> bulk) {
+ bulkRequest = bulk;
+ singletonNetwork = null;
+ }
+
+ NeutronNetworkRequest(NeutronNetwork net) {
+ singletonNetwork = net;
+ }
+
+ @Override
+ public NeutronNetwork getSingleton() {
+ return singletonNetwork;
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return (singletonNetwork != null);
+ }
+
+ @Override
+ public List<NeutronNetwork> getBulk() {
+ return bulkRequest;
+ }
+}
--- /dev/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.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.DefaultValue;
+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.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+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.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Neutron Northbound REST APIs for Network.<br>
+ * This class provides REST APIs for managing neutron Networks
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/networks")
+public class NeutronNetworksNorthbound {
+
+ @Context
+ UriInfo uriInfo;
+
+ private NeutronNetwork extractFields(NeutronNetwork o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all Networks */
+
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackNetworks.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized")})
+ public Response listNetworks(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("name") String queryName,
+ @QueryParam("admin_state_up") String queryAdminStateUp,
+ @QueryParam("status") String queryStatus,
+ @QueryParam("shared") String queryShared,
+ @QueryParam("tenant_id") String queryTenantID,
+ @QueryParam("router_external") String queryRouterExternal,
+ @QueryParam("provider_network_type") String queryProviderNetworkType,
+ @QueryParam("provider_physical_network") String queryProviderPhysicalNetwork,
+ @QueryParam("provider_segmentation_id") String queryProviderSegmentationID,
+ // linkTitle
+ @QueryParam("limit") Integer limit,
+ @QueryParam("marker") String marker,
+ @DefaultValue("false") @QueryParam("page_reverse") Boolean pageReverse
+ // sorting not supported
+ ) {
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronNetwork> allNetworks = networkInterface.getAllNetworks();
+ List<NeutronNetwork> ans = new ArrayList<NeutronNetwork>();
+ Iterator<NeutronNetwork> i = allNetworks.iterator();
+ while (i.hasNext()) {
+ NeutronNetwork oSN = i.next();
+ //match filters: TODO provider extension
+ Boolean bAdminStateUp = null;
+ Boolean bShared = null;
+ Boolean bRouterExternal = null;
+ if (queryAdminStateUp != null) {
+ bAdminStateUp = Boolean.valueOf(queryAdminStateUp);
+ }
+ if (queryShared != null) {
+ bShared = Boolean.valueOf(queryShared);
+ }
+ if (queryRouterExternal != null) {
+ bRouterExternal = Boolean.valueOf(queryRouterExternal);
+ }
+ if ((queryID == null || queryID.equals(oSN.getID())) &&
+ (queryName == null || queryName.equals(oSN.getNetworkName())) &&
+ (bAdminStateUp == null || bAdminStateUp.booleanValue() == oSN.isAdminStateUp()) &&
+ (queryStatus == null || queryStatus.equals(oSN.getStatus())) &&
+ (bShared == null || bShared.booleanValue() == oSN.isShared()) &&
+ (bRouterExternal == null || bRouterExternal.booleanValue() == oSN.isRouterExternal()) &&
+ (queryTenantID == null || queryTenantID.equals(oSN.getTenantID()))) {
+ if (fields.size() > 0) {
+ ans.add(extractFields(oSN,fields));
+ } else {
+ ans.add(oSN);
+ }
+ }
+ }
+
+ if (limit != null && ans.size() > 1) {
+ // Return a paginated request
+ NeutronNetworkRequest request = (NeutronNetworkRequest) PaginatedRequestFactory.createRequest(limit,
+ marker, pageReverse, uriInfo, ans, NeutronNetwork.class);
+ return Response.status(200).entity(request).build();
+ }
+
+ return Response.status(200).entity(new NeutronNetworkRequest(ans)).build();
+
+ }
+
+ /**
+ * Returns a specific Network */
+
+ @Path("{netUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackNetworks.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found") })
+ public Response showNetwork(
+ @PathParam("netUUID") String netUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields
+ ) {
+ INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+ if (networkInterface == null) {
+ throw new ServiceUnavailableException("Network CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!networkInterface.networkExists(netUUID)) {
+ throw new ResourceNotFoundException("network UUID does not exist.");
+ }
+ 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())) {
+ throw new BadRequestException("network UUID already exists");
+ }
+
+ 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
+ singleton.initDefaults();
+ networkInterface.addNetwork(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronNetworkAware service = (INeutronNetworkAware) instance;
+ service.neutronNetworkCreated(singleton);
+ }
+ }
+
+ } else {
+ List<NeutronNetwork> bulk = input.getBulk();
+ Iterator<NeutronNetwork> i = bulk.iterator();
+ HashMap<String, NeutronNetwork> testMap = new HashMap<String, NeutronNetwork>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronNetwork test = i.next();
+
+ /*
+ * network ID can't already exist, nor can there be an entry for this UUID
+ * already in this bulk request
+ */
+ if (networkInterface.networkExists(test.getID())) {
+ throw new BadRequestException("network UUID already exists");
+ }
+ if (testMap.containsKey(test.getID())) {
+ throw new BadRequestException("network UUID already exists");
+ }
+ 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)) {
+ throw new ResourceNotFoundException("network UUID does not exist.");
+ }
+ if (!input.isSingleton()) {
+ throw new BadRequestException("only singleton edits supported");
+ }
+ NeutronNetwork delta = input.getSingleton();
+
+ /*
+ * transitions forbidden by Neutron
+ */
+ if (delta.getID() != null || delta.getTenantID() != null ||
+ delta.getStatus() != null) {
+ throw new BadRequestException("attribute edit blocked by Neutron");
+ }
+
+ 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)) {
+ throw new ResourceNotFoundException("network UUID does not exist.");
+ }
+ if (networkInterface.networkInUse(netUUID)) {
+ throw new ResourceConflictException("Network ID in use");
+ }
+
+ 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();
+ }
+}
--- /dev/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 org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;
+
+import javax.ws.rs.core.Application;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * This class is an instance of javax.ws.rs.core.Application and is used to return the classes
+ * that will be instantiated for JAXRS processing. This is necessary
+ * because package scanning in jersey doesn't yet work in OSGi environment.
+ *
+ */
+public class NeutronNorthboundRSApplication extends Application {
+ @Override
+ public Set<Class<?>> getClasses() {
+ Set<Class<?>> classes = new HashSet<Class<?>>();
+// northbound URIs
+ classes.add(NeutronNetworksNorthbound.class);
+ classes.add(NeutronSubnetsNorthbound.class);
+ classes.add(NeutronPortsNorthbound.class);
+ classes.add(NeutronRoutersNorthbound.class);
+ classes.add(NeutronFloatingIPsNorthbound.class);
+ classes.add(NeutronSecurityGroupsNorthbound.class);
+ classes.add(NeutronSecurityRulesNorthbound.class);
+ classes.add(NeutronFirewallNorthbound.class);
+ classes.add(NeutronFirewallPolicyNorthbound.class);
+ classes.add(NeutronFirewallRulesNorthbound.class);
+ classes.add(NeutronLoadBalancerNorthbound.class);
+ classes.add(NeutronLoadBalancerListenerNorthbound.class);
+ classes.add(NeutronLoadBalancerPoolNorthbound.class);
+ classes.add(NeutronLoadBalancerHealthMonitorNorthbound.class);
+ classes.add(NeutronLoadBalancerPoolMembersNorthbound.class);
+ return classes;
+ }
+
+ @Override
+ public Set<Object> getSingletons() {
+ MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider();
+
+ moxyJsonProvider.setAttributePrefix("@");
+ moxyJsonProvider.setFormattedOutput(true);
+ moxyJsonProvider.setIncludeRoot(false);
+ moxyJsonProvider.setMarshalEmptyCollections(true);
+ moxyJsonProvider.setValueWrapper("$");
+
+ Map<String, String> namespacePrefixMapper = new HashMap<String, String>(1);
+ namespacePrefixMapper.put("router", "router"); // FIXME: fill in with XSD
+ namespacePrefixMapper.put("provider", "provider"); // FIXME: fill in with XSD
+ moxyJsonProvider.setNamespacePrefixMapper(namespacePrefixMapper);
+ moxyJsonProvider.setNamespaceSeparator(':');
+
+ HashSet<Object> set = new HashSet<Object>(1);
+ set.add(moxyJsonProvider);
+ return set;
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2014 Hewlett-Packard Development Company L.P
+ *
+ * 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
+ *
+ * Authors : Dave Tucker
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronPageLink {
+
+ @XmlElement(name="ref")
+ String ref;
+
+ @XmlElement (name="href")
+ String href;
+
+ public String getRef() {
+ return ref;
+ }
+
+ public void setRef(String ref) {
+ this.ref = ref;
+ }
+
+ public String getHref() {
+ return href;
+ }
+
+ public void setHref(String href) {
+ this.href = href;
+ }
+}
\ No newline at end of file
--- /dev/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.NeutronPort;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronPortRequest implements INeutronRequest<NeutronPort> {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="port")
+ NeutronPort singletonPort;
+
+ @XmlElement(name="ports")
+ List<NeutronPort> bulkRequest;
+
+ @XmlElement(name="ports_links")
+ List<NeutronPageLink> links;
+
+ NeutronPortRequest() {
+ }
+
+ public NeutronPortRequest(List<NeutronPort> bulkRequest, List<NeutronPageLink> links) {
+ this.bulkRequest = bulkRequest;
+ this.links = links;
+ this.singletonPort = null;
+ }
+
+ NeutronPortRequest(List<NeutronPort> bulk) {
+ bulkRequest = bulk;
+ singletonPort = null;
+ }
+
+ NeutronPortRequest(NeutronPort port) {
+ singletonPort = port;
+ }
+
+ @Override
+ public NeutronPort getSingleton() {
+ return singletonPort;
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return (singletonPort != null);
+ }
+
+ @Override
+ public List<NeutronPort> getBulk() {
+ return bulkRequest;
+ }
+}
--- /dev/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.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.DefaultValue;
+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.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+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.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.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Neutron Northbound REST APIs.<br>
+ * This class provides REST APIs for managing neutron port objects
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/ports")
+public class NeutronPortsNorthbound {
+
+ final String mac_regex="^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$";
+
+ private NeutronPort extractFields(NeutronPort o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ @Context
+ UriInfo uriInfo;
+
+ /**
+ * Returns a list of all Ports */
+
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackPorts.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response listPorts(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("network_id") String queryNetworkID,
+ @QueryParam("name") String queryName,
+ @QueryParam("admin_state_up") String queryAdminStateUp,
+ @QueryParam("status") String queryStatus,
+ @QueryParam("mac_address") String queryMACAddress,
+ @QueryParam("device_id") String queryDeviceID,
+ @QueryParam("device_owner") String queryDeviceOwner,
+ @QueryParam("tenant_id") String queryTenantID,
+ // linkTitle
+ @QueryParam("limit") Integer limit,
+ @QueryParam("marker") String marker,
+ @DefaultValue("false") @QueryParam("page_reverse") Boolean pageReverse
+ // sorting not supported
+ ) {
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronPort> allPorts = portInterface.getAllPorts();
+ List<NeutronPort> ans = new ArrayList<NeutronPort>();
+ Iterator<NeutronPort> i = allPorts.iterator();
+ while (i.hasNext()) {
+ NeutronPort oSS = i.next();
+ if ((queryID == null || queryID.equals(oSS.getID())) &&
+ (queryNetworkID == null || queryNetworkID.equals(oSS.getNetworkUUID())) &&
+ (queryName == null || queryName.equals(oSS.getName())) &&
+ (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&
+ (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&
+ (queryMACAddress == null || queryMACAddress.equals(oSS.getMacAddress())) &&
+ (queryDeviceID == null || queryDeviceID.equals(oSS.getDeviceID())) &&
+ (queryDeviceOwner == null || queryDeviceOwner.equals(oSS.getDeviceOwner())) &&
+ (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {
+ if (fields.size() > 0) {
+ ans.add(extractFields(oSS,fields));
+ } else {
+ ans.add(oSS);
+ }
+ }
+ }
+
+ if (limit != null && ans.size() > 1) {
+ // Return a paginated request
+ NeutronPortRequest request = (NeutronPortRequest) PaginatedRequestFactory.createRequest(limit,
+ marker, pageReverse, uriInfo, ans, NeutronPort.class);
+ return Response.status(200).entity(request).build();
+ }
+
+ return Response.status(200).entity(
+ new NeutronPortRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Port */
+
+ @Path("{portUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackPorts.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response showPort(
+ @PathParam("portUUID") String portUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields ) {
+ INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+ if (portInterface == null) {
+ throw new ServiceUnavailableException("Port CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!portInterface.portExists(portUUID)) {
+ throw new ResourceNotFoundException("port UUID does not exist.");
+ }
+ 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) {
+ throw new BadRequestException("network UUID musy be specified");
+ }
+ if (portInterface.portExists(singleton.getID())) {
+ throw new BadRequestException("port UUID already exists");
+ }
+ if (!networkInterface.networkExists(singleton.getNetworkUUID())) {
+ throw new ResourceNotFoundException("network UUID does not exist.");
+ }
+ if (singleton.getMacAddress() == null ||
+ !singleton.getMacAddress().matches(mac_regex)) {
+ throw new BadRequestException("MAC address not properly formatted");
+ }
+ if (portInterface.macInUse(singleton.getMacAddress())) {
+ throw new ResourceConflictException("MAC Address is in use.");
+ }
+ /*
+ * if fixed IPs are specified, each one has to have an existing subnet ID
+ * that is in the same scoping network as the port. In addition, if an IP
+ * address is specified it has to be a valid address for the subnet and not
+ * already in use
+ */
+ List<Neutron_IPs> fixedIPs = singleton.getFixedIPs();
+ if (fixedIPs != null && fixedIPs.size() > 0) {
+ Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();
+ while (fixedIPIterator.hasNext()) {
+ Neutron_IPs ip = fixedIPIterator.next();
+ if (ip.getSubnetUUID() == null) {
+ throw new BadRequestException("subnet UUID not specified");
+ }
+ if (!subnetInterface.subnetExists(ip.getSubnetUUID())) {
+ throw new BadRequestException("subnet UUID must exists");
+ }
+ NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());
+ if (!singleton.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID())) {
+ throw new BadRequestException("network UUID must match that of subnet");
+ }
+ if (ip.getIpAddress() != null) {
+ if (!subnet.isValidIP(ip.getIpAddress())) {
+ throw new BadRequestException("IP address is not valid");
+ }
+ if (subnet.isIPInUse(ip.getIpAddress())) {
+ throw new ResourceConflictException("IP address is in use.");
+ }
+ }
+ }
+ }
+
+ 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();
+ }
+ }
+ }
+
+
+ // add the port to the cache
+ portInterface.addPort(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ service.neutronPortCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronPort> bulk = input.getBulk();
+ Iterator<NeutronPort> i = bulk.iterator();
+ HashMap<String, NeutronPort> testMap = new HashMap<String, NeutronPort>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.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())) {
+ throw new BadRequestException("port UUID already exists");
+ }
+ if (testMap.containsKey(test.getID())) {
+ throw new BadRequestException("port UUID already exists");
+ }
+ for (NeutronPort check : testMap.values()) {
+ if (test.getMacAddress().equalsIgnoreCase(check.getMacAddress())) {
+ throw new ResourceConflictException("MAC address already allocated");
+ }
+ for (Neutron_IPs test_fixedIP : test.getFixedIPs()) {
+ for (Neutron_IPs check_fixedIP : check.getFixedIPs()) {
+ if (test_fixedIP.getIpAddress().equals(check_fixedIP.getIpAddress())) {
+ throw new ResourceConflictException("IP address already allocated");
+ }
+ }
+ }
+ }
+ testMap.put(test.getID(), test);
+ if (!networkInterface.networkExists(test.getNetworkUUID())) {
+ throw new ResourceNotFoundException("network UUID does not exist.");
+ }
+ if (!test.getMacAddress().matches(mac_regex)) {
+ throw new BadRequestException("MAC address not properly formatted");
+ }
+ if (portInterface.macInUse(test.getMacAddress())) {
+ throw new ResourceConflictException("MAC address in use");
+ }
+
+ /*
+ * if fixed IPs are specified, each one has to have an existing subnet ID
+ * that is in the same scoping network as the port. In addition, if an IP
+ * address is specified it has to be a valid address for the subnet and not
+ * already in use (or be the gateway IP address of the subnet)
+ */
+ List<Neutron_IPs> fixedIPs = test.getFixedIPs();
+ if (fixedIPs != null && fixedIPs.size() > 0) {
+ Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();
+ while (fixedIPIterator.hasNext()) {
+ Neutron_IPs ip = fixedIPIterator.next();
+ if (ip.getSubnetUUID() == null) {
+ throw new BadRequestException("subnet UUID must be specified");
+ }
+ if (!subnetInterface.subnetExists(ip.getSubnetUUID())) {
+ throw new BadRequestException("subnet UUID doesn't exists");
+ }
+ NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());
+ if (!test.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID())) {
+ throw new BadRequestException("network UUID must match that of subnet");
+ }
+ if (ip.getIpAddress() != null) {
+ if (!subnet.isValidIP(ip.getIpAddress())) {
+ throw new BadRequestException("ip address not valid");
+ }
+ //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())) {
+ throw new ResourceConflictException("IP address in use");
+ }
+ }
+ }
+ }
+ 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();
+ }
+ }
+ }
+ }
+
+ //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)) {
+ throw new ResourceNotFoundException("port UUID does not exist.");
+ }
+ NeutronPort target = portInterface.getPort(portUUID);
+ if (!input.isSingleton()) {
+ throw new BadRequestException("only singleton edit suported");
+ }
+ NeutronPort singleton = input.getSingleton();
+ NeutronPort original = portInterface.getPort(portUUID);
+
+ // deltas restricted by Neutron
+ if (singleton.getID() != null || singleton.getTenantID() != null ||
+ singleton.getStatus() != null) {
+ throw new BadRequestException("attribute change blocked by Neutron");
+ }
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronPortAware service = (INeutronPortAware) instance;
+ int status = service.canUpdatePort(singleton, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ // Verify the new fixed ips are valid
+ List<Neutron_IPs> fixedIPs = singleton.getFixedIPs();
+ if (fixedIPs != null && fixedIPs.size() > 0) {
+ Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();
+ while (fixedIPIterator.hasNext()) {
+ Neutron_IPs ip = fixedIPIterator.next();
+ if (ip.getSubnetUUID() == null) {
+ throw new BadRequestException("subnet UUID must be specified");
+ }
+ if (!subnetInterface.subnetExists(ip.getSubnetUUID())) {
+ throw new BadRequestException("subnet UUID doesn't exist.");
+ }
+ NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());
+ if (!target.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID())) {
+ throw new BadRequestException("network UUID must match that of subnet");
+ }
+ if (ip.getIpAddress() != null) {
+ if (!subnet.isValidIP(ip.getIpAddress())) {
+ throw new BadRequestException("invalid IP address");
+ }
+ if (subnet.isIPInUse(ip.getIpAddress())) {
+ throw new ResourceConflictException("IP address in use");
+ }
+ }
+ }
+ }
+
+ // 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)) {
+ throw new ResourceNotFoundException("port UUID does not exist.");
+ }
+ 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();
+ }
+}
--- /dev/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<NeutronRouter> bulkRequest;
+
+ NeutronRouterRequest() {
+ }
+
+ NeutronRouterRequest(List<NeutronRouter> bulk) {
+ bulkRequest = bulk;
+ singletonRouter = null;
+ }
+
+ NeutronRouterRequest(NeutronRouter router) {
+ singletonRouter = router;
+ }
+
+ public List<NeutronRouter> getBulk() {
+ return bulkRequest;
+ }
+
+ public NeutronRouter getSingleton() {
+ return singletonRouter;
+ }
+
+ public boolean isSingleton() {
+ return (singletonRouter != null);
+ }
+}
--- /dev/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.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.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+
+/**
+ * Neutron Northbound REST APIs.<br>
+ * This class provides REST APIs for managing neutron routers
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/routers")
+public class NeutronRoutersNorthbound {
+
+ private NeutronRouter extractFields(NeutronRouter o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all Routers */
+
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackRouters.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response listRouters(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("name") String queryName,
+ @QueryParam("admin_state_up") String queryAdminStateUp,
+ @QueryParam("status") String queryStatus,
+ @QueryParam("tenant_id") String queryTenantID,
+ @QueryParam("external_gateway_info") String queryExternalGatewayInfo,
+ // pagination
+ @QueryParam("limit") String limit,
+ @QueryParam("marker") String marker,
+ @QueryParam("page_reverse") String pageReverse
+ // sorting not supported
+ ) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronRouter> allRouters = routerInterface.getAllRouters();
+ List<NeutronRouter> ans = new ArrayList<NeutronRouter>();
+ Iterator<NeutronRouter> i = allRouters.iterator();
+ while (i.hasNext()) {
+ NeutronRouter oSS = i.next();
+ if ((queryID == null || queryID.equals(oSS.getID())) &&
+ (queryName == null || queryName.equals(oSS.getName())) &&
+ (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&
+ (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&
+ (queryExternalGatewayInfo == null || queryExternalGatewayInfo.equals(oSS.getExternalGatewayInfo())) &&
+ (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {
+ if (fields.size() > 0)
+ ans.add(extractFields(oSS,fields));
+ else
+ ans.add(oSS);
+ }
+ }
+ //TODO: apply pagination to results
+ return Response.status(200).entity(
+ new NeutronRouterRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Router */
+
+ @Path("{routerUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackRouters.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 403, condition = "Forbidden"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response showRouter(
+ @PathParam("routerUUID") String routerUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields) {
+ INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+ if (routerInterface == null) {
+ throw new ServiceUnavailableException("Router CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!routerInterface.routerExists(routerUUID)) {
+ throw new ResourceNotFoundException("Router UUID not found");
+ }
+ 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()))
+ throw new BadRequestException("router UUID already exists");
+ if (singleton.getExternalGatewayInfo() != null) {
+ String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();
+ if (!networkInterface.networkExists(externNetworkPtr))
+ throw new BadRequestException("External Network Pointer doesn't exist");
+ NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);
+ if (!externNetwork.isRouterExternal())
+ throw new BadRequestException("External Network Pointer isn't marked as router:external");
+ }
+ 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
+ */
+ throw new BadRequestException("Only singleton router creates supported");
+ }
+ 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))
+ throw new ResourceNotFoundException("Router UUID not found");
+ if (!input.isSingleton())
+ throw new BadRequestException("Only single router deltas supported");
+ NeutronRouter singleton = input.getSingleton();
+ NeutronRouter original = routerInterface.getRouter(routerUUID);
+
+ /*
+ * attribute changes blocked by Neutron
+ */
+ if (singleton.getID() != null || singleton.getTenantID() != null ||
+ singleton.getStatus() != null)
+ throw new BadRequestException("Request attribute change not allowed");
+
+ 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))
+ throw new BadRequestException("External Network Pointer does not exist");
+ NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);
+ if (!externNetwork.isRouterExternal())
+ throw new BadRequestException("External Network Pointer isn't marked as router:external");
+ }
+
+ /*
+ * 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))
+ throw new ResourceNotFoundException("Router UUID not found");
+ if (routerInterface.routerInUse(routerUUID))
+ throw new ResourceConflictException("Router UUID in Use");
+ 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))
+ throw new BadRequestException("Router UUID doesn't exist");
+ NeutronRouter target = routerInterface.getRouter(routerUUID);
+ if (input.getSubnetUUID() == null ||
+ input.getPortUUID() == null)
+ throw new BadRequestException("Must specify at subnet id, port id or both");
+
+ // check that the port is part of the subnet
+ NeutronSubnet targetSubnet = subnetInterface.getSubnet(input.getSubnetUUID());
+ if (targetSubnet == null)
+ throw new BadRequestException("Subnet id doesn't exist");
+ NeutronPort targetPort = portInterface.getPort(input.getPortUUID());
+ if (targetPort == null)
+ throw new BadRequestException("Port id doesn't exist");
+ if (!targetSubnet.getPortsInSubnet().contains(targetPort))
+ throw new BadRequestException("Port id not part of subnet id");
+
+ if (targetPort.getFixedIPs().size() != 1)
+ throw new BadRequestException("Port id must have a single fixedIP address");
+ if (targetPort.getDeviceID() != null ||
+ targetPort.getDeviceOwner() != null)
+ throw new ResourceConflictException("Target Port already allocated");
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronRouterAware service = (INeutronRouterAware) instance;
+ int status = service.canAttachInterface(target, input);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+
+ //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))
+ throw new BadRequestException("Router does not exist");
+ 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)
+ throw new ResourceNotFoundException("Port UUID not found");
+ 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;
+ int status = service.canDetachInterface(target, input);
+ if (status < 200 || status > 299)
+ return Response.status(status).build();
+ }
+ }
+
+ // 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());
+ if (targetInterface == null) {
+ throw new ResourceNotFoundException("Router interface not found for given Port UUID");
+ }
+ 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());
+ if (port == null) {
+ throw new ResourceNotFoundException("Port UUID not found");
+ }
+ if (port.getFixedIPs() == null) {
+ throw new ResourceNotFoundException("Port UUID has no fixed IPs");
+ }
+ NeutronSubnet subnet = subnetInterface.getSubnet(input.getSubnetUUID());
+ if (subnet == null) {
+ throw new ResourceNotFoundException("Subnet UUID not found");
+ }
+ if (!subnet.isValidIP(port.getFixedIPs().get(0).getIpAddress()))
+ throw new ResourceConflictException("Target Port IP not in Target Subnet");
+ 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
+ throw new BadRequestException("Must specify port id or subnet id or both");
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup;
+
+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 java.util.List;
+
+
+@XmlRootElement
+@XmlAccessorType (XmlAccessType.NONE)
+
+public class NeutronSecurityGroupRequest {
+ /**
+ * See OpenStack Network API v2.0 Reference for a
+ * description of annotated attributes and operations
+ */
+
+ @XmlElement (name = "security_group")
+ NeutronSecurityGroup singletonSecurityGroup;
+
+ @XmlElement (name = "security_groups")
+ List<NeutronSecurityGroup> bulkRequest;
+
+ NeutronSecurityGroupRequest() {
+ }
+
+ NeutronSecurityGroupRequest(List<NeutronSecurityGroup> bulk) {
+ bulkRequest = bulk;
+ singletonSecurityGroup = null;
+ }
+
+ NeutronSecurityGroupRequest(NeutronSecurityGroup group) {
+ singletonSecurityGroup = group;
+ }
+
+ public List<NeutronSecurityGroup> getBulk() {
+ return bulkRequest;
+ }
+
+ public NeutronSecurityGroup getSingleton() {
+ return singletonSecurityGroup;
+ }
+
+ public boolean isSingleton() {
+ return (singletonSecurityGroup != null);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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.INeutronSecurityGroupAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Neutron Northbound REST APIs for Security Group.<br>
+ * This class provides REST APIs for managing neutron Security Group
+ * <p/>
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ */
+@Path ("/security-groups")
+public class NeutronSecurityGroupsNorthbound {
+ static final Logger logger = LoggerFactory.getLogger(NeutronSecurityGroupsNorthbound.class);
+
+ private NeutronSecurityGroup extractFields(NeutronSecurityGroup o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all Security Groups
+ */
+ @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 listGroups(
+ // return fields
+ @QueryParam ("fields") List<String> fields,
+ // OpenStack security group attributes
+ @QueryParam ("id") String querySecurityGroupUUID,
+ @QueryParam ("name") String querySecurityGroupName,
+ @QueryParam ("description") String querySecurityDescription,
+ @QueryParam ("tenant_id") String querySecurityTenantID,
+ @QueryParam ("limit") String limit,
+ @QueryParam ("marker") String marker,
+ @QueryParam ("page_reverse") String pageReverse
+ ) {
+ INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this);
+
+ if (securityGroupInterface == null) {
+ throw new ServiceUnavailableException("Security Group CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronSecurityGroup> allSecurityGroups = securityGroupInterface.getAllNeutronSecurityGroups();
+ List<NeutronSecurityGroup> ans = new ArrayList<NeutronSecurityGroup>();
+ Iterator<NeutronSecurityGroup> i = allSecurityGroups.iterator();
+ while (i.hasNext()) {
+ NeutronSecurityGroup nsg = i.next();
+ if ((querySecurityGroupUUID == null ||
+ querySecurityGroupUUID.equals(nsg.getSecurityGroupUUID())) &&
+ (querySecurityGroupName == null ||
+ querySecurityGroupName.equals(nsg.getSecurityGroupName())) &&
+ (querySecurityDescription == null ||
+ querySecurityDescription.equals(nsg.getSecurityGroupDescription())) &&
+ (querySecurityTenantID == null ||
+ querySecurityTenantID.equals(nsg.getSecurityGroupTenantID()))) {
+ if (fields.size() > 0) {
+ ans.add(extractFields(nsg, fields));
+ } else {
+ ans.add(nsg);
+ }
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronSecurityGroupRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Security Group
+ */
+
+ @Path ("{securityGroupUUID}")
+ @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 showSecurityGroup(@PathParam ("securityGroupUUID") String securityGroupUUID,
+ // return fields
+ @QueryParam ("fields") List<String> fields) {
+ INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this);
+ if (securityGroupInterface == null) {
+ throw new ServiceUnavailableException("Security Group CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) {
+ throw new ResourceNotFoundException("Security Group UUID does not exist.");
+ }
+ if (!fields.isEmpty()) {
+ NeutronSecurityGroup ans = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID);
+ return Response.status(200).entity(
+ new NeutronSecurityGroupRequest(extractFields(ans, fields))).build();
+ } else {
+ return Response.status(200).entity(new NeutronSecurityGroupRequest(securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID))).build();
+ }
+ }
+
+ /**
+ * Creates new Security Group
+ */
+
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode (code = 404, condition = "Not Found"),
+ @ResponseCode (code = 409, condition = "Conflict"),
+ @ResponseCode (code = 501, condition = "Not Implemented")})
+ public Response createSecurityGroups(final NeutronSecurityGroupRequest input) {
+ INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this);
+ if (securityGroupInterface == null) {
+ throw new ServiceUnavailableException("Security Group CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ if (input.isSingleton()) {
+ NeutronSecurityGroup singleton = input.getSingleton();
+
+ /*
+ * Verify that the Security Group doesn't already exist.
+ */
+ if (securityGroupInterface.neutronSecurityGroupExists(singleton.getSecurityGroupUUID())) {
+ throw new BadRequestException("Security Group UUID already exists");
+ }
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+ int status = service.canCreateNeutronSecurityGroup(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ // Add to Neutron cache
+ securityGroupInterface.addNeutronSecurityGroup(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+ service.neutronSecurityGroupCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronSecurityGroup> bulk = input.getBulk();
+ Iterator<NeutronSecurityGroup> i = bulk.iterator();
+ HashMap<String, NeutronSecurityGroup> testMap = new HashMap<String, NeutronSecurityGroup>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronSecurityGroup test = i.next();
+
+ /*
+ * Verify that the security group doesn't already exist
+ */
+
+ if (securityGroupInterface.neutronSecurityGroupExists(test.getSecurityGroupUUID())) {
+ throw new BadRequestException("Security Group UUID already is already created");
+ }
+ if (instances != null) for (Object instance : instances) {
+ INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+ int status = service.canCreateNeutronSecurityGroup(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()) {
+ NeutronSecurityGroup test = i.next();
+ securityGroupInterface.addNeutronSecurityGroup(test);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+ service.neutronSecurityGroupCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a Security Group
+ */
+
+ @Path ("{securityGroupUUID}")
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode (code = 404, condition = "Not Found"),
+ @ResponseCode (code = 501, condition = "Not Implemented")})
+ public Response updateSecurityGroup(
+ @PathParam ("securityGroupUUID") String securityGroupUUID, final NeutronSecurityGroupRequest input) {
+ INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this);
+ if (securityGroupInterface == null) {
+ throw new ServiceUnavailableException("Security Group CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the Security Group exists and there is only one delta provided
+ */
+ if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) {
+ throw new ResourceNotFoundException("Security Group UUID does not exist.");
+ }
+ if (!input.isSingleton()) {
+ throw new BadRequestException("Only singleton edit supported");
+ }
+ NeutronSecurityGroup delta = input.getSingleton();
+ NeutronSecurityGroup original = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID);
+
+ if (delta.getSecurityGroupUUID() != null ||
+ delta.getSecurityGroupTenantID() != null ||
+ delta.getSecurityGroupName() != null ||
+ delta.getSecurityGroupDescription() != null) {
+ throw new BadRequestException("Attribute edit blocked by Neutron");
+ }
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+ int status = service.canUpdateNeutronSecurityGroup(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * update the object and return it
+ */
+ securityGroupInterface.updateNeutronSecurityGroup(securityGroupUUID, delta);
+ NeutronSecurityGroup updatedSecurityGroup = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+ service.neutronSecurityGroupUpdated(updatedSecurityGroup);
+ }
+ }
+ return Response.status(200).entity(new NeutronSecurityGroupRequest(securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID))).build();
+ }
+
+ /**
+ * Deletes a Security Group
+ */
+
+ @Path ("{securityGroupUUID}")
+ @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 deleteSecurityGroup(
+ @PathParam ("securityGroupUUID") String securityGroupUUID) {
+ INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this);
+ if (securityGroupInterface == null) {
+ throw new ServiceUnavailableException("Security Group CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the Security Group exists and it isn't currently in use
+ */
+ if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) {
+ throw new ResourceNotFoundException("Security Group UUID does not exist.");
+ }
+ if (securityGroupInterface.neutronSecurityGroupInUse(securityGroupUUID)) {
+ return Response.status(409).build();
+ }
+ NeutronSecurityGroup singleton = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+ int status = service.canDeleteNeutronSecurityGroup(singleton);
+ if ((status < 200) || (status > 299)) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * remove it and return 204 status
+ */
+ securityGroupInterface.removeNeutronSecurityGroup(securityGroupUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+ service.neutronSecurityGroupDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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 org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule;
+
+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 java.util.List;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronSecurityRuleRequest {
+ /**
+ * See OpenStack Network API v2.0 Reference for a
+ * description of annotated attributes and operations
+ */
+
+ @XmlElement(name="security_group_rule")
+ NeutronSecurityRule singletonSecurityRule;
+
+ @XmlElement(name="security_group_rules")
+ List<NeutronSecurityRule> bulkRequest;
+
+ NeutronSecurityRuleRequest() {
+ }
+
+ NeutronSecurityRuleRequest(List<NeutronSecurityRule> bulk) {
+ bulkRequest = bulk;
+ singletonSecurityRule = null;
+ }
+
+ NeutronSecurityRuleRequest(NeutronSecurityRule rule) {
+ singletonSecurityRule = rule;
+ }
+
+ public NeutronSecurityRule getSingleton() {
+ return singletonSecurityRule;
+ }
+
+ public boolean isSingleton() {
+ return (singletonSecurityRule != null);
+ }
+ public List<NeutronSecurityRule> getBulk() {
+ return bulkRequest;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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.INeutronSecurityGroupCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Neutron Northbound REST APIs for Security Rule.<br>
+ * This class provides REST APIs for managing neutron Security Rule
+ * <p/>
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ */
+
+@Path ("/security-group-rules")
+public class NeutronSecurityRulesNorthbound {
+ static final Logger logger = LoggerFactory.getLogger(NeutronSecurityRulesNorthbound.class);
+
+ private NeutronSecurityRule extractFields(NeutronSecurityRule o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ /**
+ * Returns a list of all Security Rules
+ */
+ @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 listRules(
+ // return fields
+ @QueryParam ("fields") List<String> fields,
+ // OpenStack security rule attributes
+ @QueryParam ("id") String querySecurityRuleUUID,
+ @QueryParam ("direction") String querySecurityRuleDirection,
+ @QueryParam ("protocol") String querySecurityRuleProtocol,
+ @QueryParam ("port_range_min") Integer querySecurityRulePortMin,
+ @QueryParam ("port_range_max") Integer querySecurityRulePortMax,
+ @QueryParam ("ethertype") String querySecurityRuleEthertype,
+ @QueryParam ("remote_ip_prefix") String querySecurityRuleIpPrefix,
+ @QueryParam ("remote_group_id") String querySecurityRemoteGroupID,
+ @QueryParam ("security_group_id") String querySecurityRuleGroupID,
+ @QueryParam ("tenant_id") String querySecurityRuleTenantID,
+ @QueryParam ("limit") String limit,
+ @QueryParam ("marker") String marker,
+ @QueryParam ("page_reverse") String pageReverse
+ ) {
+ INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this);
+ if (securityRuleInterface == null) {
+ throw new ServiceUnavailableException("Security Rule CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronSecurityRule> allSecurityRules = securityRuleInterface.getAllNeutronSecurityRules();
+ List<NeutronSecurityRule> ans = new ArrayList<NeutronSecurityRule>();
+ Iterator<NeutronSecurityRule> i = allSecurityRules.iterator();
+ while (i.hasNext()) {
+ NeutronSecurityRule nsr = i.next();
+ if ((querySecurityRuleUUID == null ||
+ querySecurityRuleUUID.equals(nsr.getSecurityRuleUUID())) &&
+ (querySecurityRuleDirection == null ||
+ querySecurityRuleDirection.equals(nsr.getSecurityRuleDirection())) &&
+ (querySecurityRuleProtocol == null ||
+ querySecurityRuleProtocol.equals(nsr.getSecurityRuleProtocol())) &&
+ (querySecurityRulePortMin == null ||
+ querySecurityRulePortMin.equals(nsr.getSecurityRulePortMin())) &&
+ (querySecurityRulePortMax == null ||
+ querySecurityRulePortMax.equals(nsr.getSecurityRulePortMax())) &&
+ (querySecurityRuleEthertype == null ||
+ querySecurityRuleEthertype.equals(nsr.getSecurityRuleEthertype())) &&
+ (querySecurityRuleIpPrefix == null ||
+ querySecurityRuleIpPrefix.equals(nsr.getSecurityRuleRemoteIpPrefix())) &&
+ (querySecurityRuleGroupID == null ||
+ querySecurityRuleGroupID.equals(nsr.getSecurityRuleGroupID())) &&
+ (querySecurityRemoteGroupID == null ||
+ querySecurityRemoteGroupID.equals(nsr.getSecurityRemoteGroupID())) &&
+ (querySecurityRuleTenantID == null ||
+ querySecurityRuleTenantID.equals(nsr.getSecurityRuleTenantID()))) {
+ if (fields.size() > 0) {
+ ans.add(extractFields(nsr, fields));
+ } else {
+ ans.add(nsr);
+ }
+ }
+ }
+ return Response.status(200).entity(
+ new NeutronSecurityRuleRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Security Rule
+ */
+
+ @Path ("{securityRuleUUID}")
+ @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 showSecurityRule(@PathParam ("securityRuleUUID") String securityRuleUUID,
+ // return fields
+ @QueryParam ("fields") List<String> fields) {
+ INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this);
+ if (securityRuleInterface == null) {
+ throw new ServiceUnavailableException("Security Rule CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) {
+ throw new ResourceNotFoundException("Security Rule UUID does not exist.");
+ }
+ if (!fields.isEmpty()) {
+ NeutronSecurityRule ans = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
+ return Response.status(200).entity(
+ new NeutronSecurityRuleRequest(extractFields(ans, fields))).build();
+ } else {
+ return Response.status(200).entity(new NeutronSecurityRuleRequest(securityRuleInterface.getNeutronSecurityRule(securityRuleUUID))).build();
+ }
+ }
+
+ /**
+ * Creates new Security Rule
+ */
+
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode (code = 404, condition = "Not Found"),
+ @ResponseCode (code = 409, condition = "Conflict"),
+ @ResponseCode (code = 501, condition = "Not Implemented")})
+ public Response createSecurityRules(final NeutronSecurityRuleRequest input) {
+ INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this);
+ if (securityRuleInterface == null) {
+ throw new ServiceUnavailableException("Security Rule CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this);
+ if (securityGroupInterface == null) {
+ throw new ServiceUnavailableException("Security Group CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * Existing entry checks
+ */
+
+ if (input.isSingleton()) {
+ NeutronSecurityRule singleton = input.getSingleton();
+
+ if (securityRuleInterface.neutronSecurityRuleExists(singleton.getSecurityRuleUUID())) {
+ throw new BadRequestException("Security Rule UUID already exists");
+ }
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+ int status = service.canCreateNeutronSecurityRule(singleton);
+ if ((status < 200) || (status > 299)) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ // add rule to cache
+ singleton.initDefaults();
+ securityRuleInterface.addNeutronSecurityRule(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+ service.neutronSecurityRuleCreated(singleton);
+ }
+ }
+
+ securityRuleInterface.addNeutronSecurityRule(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+ service.neutronSecurityRuleCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronSecurityRule> bulk = input.getBulk();
+ Iterator<NeutronSecurityRule> i = bulk.iterator();
+ HashMap<String, NeutronSecurityRule> testMap = new HashMap<String, NeutronSecurityRule>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronSecurityRule test = i.next();
+
+ /*
+ * Verify that the security rule doesn't already exist
+ */
+
+ if (securityRuleInterface.neutronSecurityRuleExists(test.getSecurityRuleUUID())) {
+ throw new BadRequestException("Security Rule UUID already exists");
+ }
+ if (testMap.containsKey(test.getSecurityRuleUUID())) {
+ throw new BadRequestException("Security Rule UUID already exists");
+ }
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+ int status = service.canCreateNeutronSecurityRule(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()) {
+ NeutronSecurityRule test = i.next();
+ securityRuleInterface.addNeutronSecurityRule(test);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+ service.neutronSecurityRuleCreated(test);
+ }
+ }
+ }
+ }
+ return Response.status(201).entity(input).build();
+ }
+
+ /**
+ * Updates a Security Rule
+ */
+
+ @Path ("{securityRuleUUID}")
+ @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 = 403, condition = "Forbidden"),
+ @ResponseCode (code = 404, condition = "Not Found"),
+ @ResponseCode (code = 501, condition = "Not Implemented")})
+ public Response updateSecurityRule(
+ @PathParam ("securityRuleUUID") String securityRuleUUID, final NeutronSecurityRuleRequest input) {
+ INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this);
+ if (securityRuleInterface == null) {
+ throw new ServiceUnavailableException("Security Rule CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the Security Rule exists and there is only one delta provided
+ */
+ if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) {
+ throw new ResourceNotFoundException("Security Rule UUID does not exist.");
+ }
+ if (!input.isSingleton()) {
+ throw new BadRequestException("Only singleton edit supported");
+ }
+ NeutronSecurityRule delta = input.getSingleton();
+ NeutronSecurityRule original = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
+
+ /*
+ * updates restricted by Neutron
+ *
+ */
+ if (delta.getSecurityRuleUUID() != null ||
+ delta.getSecurityRuleDirection() != null ||
+ delta.getSecurityRuleProtocol() != null ||
+ delta.getSecurityRulePortMin() != null ||
+ delta.getSecurityRulePortMax() != null ||
+ delta.getSecurityRuleEthertype() != null ||
+ delta.getSecurityRuleRemoteIpPrefix() != null ||
+ delta.getSecurityRuleGroupID() != null ||
+ delta.getSecurityRemoteGroupID() != null ||
+ delta.getSecurityRuleTenantID() != null) {
+ throw new BadRequestException("Attribute edit blocked by Neutron");
+ }
+
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+ int status = service.canUpdateNeutronSecurityRule(delta, original);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * update the object and return it
+ */
+ securityRuleInterface.updateNeutronSecurityRule(securityRuleUUID, delta);
+ NeutronSecurityRule updatedSecurityRule = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+ service.neutronSecurityRuleUpdated(updatedSecurityRule);
+ }
+ }
+ return Response.status(200).entity(new NeutronSecurityRuleRequest(securityRuleInterface.getNeutronSecurityRule(securityRuleUUID))).build();
+ }
+
+ /**
+ * Deletes a Security Rule
+ */
+
+ @Path ("{securityRuleUUID}")
+ @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 deleteSecurityRule(
+ @PathParam ("securityRuleUUID") String securityRuleUUID) {
+ INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this);
+ if (securityRuleInterface == null) {
+ throw new ServiceUnavailableException("Security Rule CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+
+ /*
+ * verify the Security Rule exists and it isn't currently in use
+ */
+ if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) {
+ throw new ResourceNotFoundException("Security Rule UUID does not exist.");
+ }
+ if (securityRuleInterface.neutronSecurityRuleInUse(securityRuleUUID)) {
+ return Response.status(409).build();
+ }
+ NeutronSecurityRule singleton = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+ int status = service.canDeleteNeutronSecurityRule(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+
+ /*
+ * remove it and return 204 status
+ */
+ securityRuleInterface.removeNeutronSecurityRule(securityRuleUUID);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+ service.neutronSecurityRuleDeleted(singleton);
+ }
+ }
+ return Response.status(204).build();
+ }
+}
\ No newline at end of file
--- /dev/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 implements INeutronRequest<NeutronSubnet> {
+ // See OpenStack Network API v2.0 Reference for description of
+ // annotated attributes
+
+ @XmlElement(name="subnet")
+ NeutronSubnet singletonSubnet;
+
+ @XmlElement(name="subnets")
+ List<NeutronSubnet> bulkRequest;
+
+ @XmlElement(name="subnets_links")
+ List<NeutronPageLink> links;
+
+ NeutronSubnetRequest() {
+ }
+
+ public NeutronSubnetRequest(List<NeutronSubnet> bulkRequest, List<NeutronPageLink> links) {
+ this.bulkRequest = bulkRequest;
+ this.links = links;
+ this.singletonSubnet = null;
+ }
+
+ NeutronSubnetRequest(List<NeutronSubnet> bulk) {
+ bulkRequest = bulk;
+ singletonSubnet = null;
+ links = null;
+ }
+
+ NeutronSubnetRequest(NeutronSubnet subnet) {
+ singletonSubnet = subnet;
+ bulkRequest = null;
+ links = null;
+ }
+
+ @Override
+ public NeutronSubnet getSingleton() {
+ return singletonSubnet;
+ }
+
+ @Override
+ public List<NeutronSubnet> getBulk() {
+ return bulkRequest;
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return (singletonSubnet != null);
+ }
+}
--- /dev/null
+/*
+ * Copyright IBM Corporation and others, 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.DefaultValue;
+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.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+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.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Neutron Northbound REST APIs for Subnets.<br>
+ * This class provides REST APIs for managing neutron Subnets
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/subnets")
+public class NeutronSubnetsNorthbound {
+
+ private NeutronSubnet extractFields(NeutronSubnet o, List<String> fields) {
+ return o.extractFields(fields);
+ }
+
+ @Context
+ UriInfo uriInfo;
+
+ /**
+ * Returns a list of all Subnets */
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackSubnets.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response listSubnets(
+ // return fields
+ @QueryParam("fields") List<String> fields,
+ // note: openstack isn't clear about filtering on lists, so we aren't handling them
+ @QueryParam("id") String queryID,
+ @QueryParam("network_id") String queryNetworkID,
+ @QueryParam("name") String queryName,
+ @QueryParam("ip_version") String queryIPVersion,
+ @QueryParam("cidr") String queryCIDR,
+ @QueryParam("gateway_ip") String queryGatewayIP,
+ @QueryParam("enable_dhcp") String queryEnableDHCP,
+ @QueryParam("tenant_id") String queryTenantID,
+ @QueryParam("ipv6_address_mode") String queryIpV6AddressMode,
+ @QueryParam("ipv6_ra_mode") String queryIpV6RaMode,
+ // linkTitle
+ @QueryParam("limit") Integer limit,
+ @QueryParam("marker") String marker,
+ @DefaultValue("false") @QueryParam("page_reverse") Boolean pageReverse
+ // sorting not supported
+ ) {
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ List<NeutronSubnet> allNetworks = subnetInterface.getAllSubnets();
+ List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();
+ Iterator<NeutronSubnet> i = allNetworks.iterator();
+ while (i.hasNext()) {
+ NeutronSubnet oSS = i.next();
+ if ((queryID == null || queryID.equals(oSS.getID())) &&
+ (queryNetworkID == null || queryNetworkID.equals(oSS.getNetworkUUID())) &&
+ (queryName == null || queryName.equals(oSS.getName())) &&
+ (queryIPVersion == null || queryIPVersion.equals(oSS.getIpVersion())) &&
+ (queryCIDR == null || queryCIDR.equals(oSS.getCidr())) &&
+ (queryGatewayIP == null || queryGatewayIP.equals(oSS.getGatewayIP())) &&
+ (queryEnableDHCP == null || queryEnableDHCP.equals(oSS.getEnableDHCP())) &&
+ (queryTenantID == null || queryTenantID.equals(oSS.getTenantID())) &&
+ (queryIpV6AddressMode == null || queryIpV6AddressMode.equals(oSS.getIpV6AddressMode())) &&
+ (queryIpV6RaMode == null || queryIpV6RaMode.equals(oSS.getIpV6RaMode()))){
+ if (fields.size() > 0) {
+ ans.add(extractFields(oSS,fields));
+ } else {
+ ans.add(oSS);
+ }
+ }
+ }
+
+ if (limit != null && ans.size() > 1) {
+ // Return a paginated request
+ NeutronSubnetRequest request = (NeutronSubnetRequest) PaginatedRequestFactory.createRequest(limit,
+ marker, pageReverse, uriInfo, ans, NeutronSubnet.class);
+ return Response.status(200).entity(request).build();
+ }
+
+ return Response.status(200).entity(
+ new NeutronSubnetRequest(ans)).build();
+ }
+
+ /**
+ * Returns a specific Subnet */
+
+ @Path("{subnetUUID}")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON })
+ //@TypeHint(OpenStackSubnets.class)
+ @StatusCodes({
+ @ResponseCode(code = 200, condition = "Operation successful"),
+ @ResponseCode(code = 401, condition = "Unauthorized"),
+ @ResponseCode(code = 404, condition = "Not Found"),
+ @ResponseCode(code = 501, condition = "Not Implemented") })
+ public Response showSubnet(
+ @PathParam("subnetUUID") String subnetUUID,
+ // return fields
+ @QueryParam("fields") List<String> fields) {
+ INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+ if (subnetInterface == null) {
+ throw new ServiceUnavailableException("Subnet CRUD Interface "
+ + RestMessages.SERVICEUNAVAILABLE.toString());
+ }
+ if (!subnetInterface.subnetExists(subnetUUID)) {
+ throw new ResourceNotFoundException("subnet UUID does not exist.");
+ }
+ 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())) {
+ throw new BadRequestException("subnet UUID already exists");
+ }
+ if (!networkInterface.networkExists(singleton.getNetworkUUID())) {
+ throw new ResourceNotFoundException("network UUID does not exist.");
+ }
+ if (!singleton.isValidCIDR()) {
+ throw new BadRequestException("invaild CIDR");
+ }
+ if (!singleton.initDefaults()) {
+ throw new InternalServerErrorException("subnet object could not be initialized properly");
+ }
+ if (singleton.gatewayIP_Pool_overlap()) {
+ throw new ResourceConflictException("IP pool overlaps with gateway");
+ }
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ int status = service.canCreateSubnet(singleton);
+ if (status < 200 || status > 299) {
+ return Response.status(status).build();
+ }
+ }
+ }
+ subnetInterface.addSubnet(singleton);
+ if (instances != null) {
+ for (Object instance : instances) {
+ INeutronSubnetAware service = (INeutronSubnetAware) instance;
+ service.neutronSubnetCreated(singleton);
+ }
+ }
+ } else {
+ List<NeutronSubnet> bulk = input.getBulk();
+ Iterator<NeutronSubnet> i = bulk.iterator();
+ HashMap<String, NeutronSubnet> testMap = new HashMap<String, NeutronSubnet>();
+ Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+ while (i.hasNext()) {
+ NeutronSubnet test = i.next();
+
+ /*
+ * Verify that the subnet doesn't already exist (Issue: is a deeper check necessary?)
+ * the specified network exists, the subnet has a valid network address,
+ * and that the gateway IP doesn't overlap with the allocation pools,
+ * and that the bulk request doesn't already contain a subnet with this id
+ */
+
+ if (!test.initDefaults()) {
+ throw new InternalServerErrorException("subnet object could not be initialized properly");
+ }
+ if (subnetInterface.subnetExists(test.getID())) {
+ throw new BadRequestException("subnet UUID already exists");
+ }
+ if (testMap.containsKey(test.getID())) {
+ throw new BadRequestException("subnet UUID already exists");
+ }
+ testMap.put(test.getID(), test);
+ if (!networkInterface.networkExists(test.getNetworkUUID())) {
+ throw new ResourceNotFoundException("network UUID does not exist.");
+ }
+ if (!test.isValidCIDR()) {
+ throw new BadRequestException("Invalid CIDR");
+ }
+ if (test.gatewayIP_Pool_overlap()) {
+ throw new ResourceConflictException("IP pool overlaps with gateway");
+ }
+ 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)) {
+ throw new ResourceNotFoundException("subnet UUID does not exist.");
+ }
+ if (!input.isSingleton()) {
+ throw new BadRequestException("Only singleton edit supported");
+ }
+ 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) {
+ throw new BadRequestException("Attribute edit blocked by Neutron");
+ }
+
+ 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)) {
+ throw new ResourceNotFoundException("subnet UUID does not exist.");
+ }
+ 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();
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * 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
+ *
+ * Authors : Dave Tucker
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import javax.ws.rs.core.UriInfo;
+import org.opendaylight.controller.networkconfig.neutron.INeutronObject;
+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.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+
+public class PaginatedRequestFactory {
+ private static final Comparator<INeutronObject> NEUTRON_OBJECT_COMPARATOR = new Comparator<INeutronObject>() {
+ @Override
+ public int compare(INeutronObject o1, INeutronObject o2) {
+ return o1.getID().compareTo(o2.getID());
+ }
+ };
+
+ public static class PaginationResults<T extends INeutronObject> {
+ List<T> collection;
+ List<NeutronPageLink> links;
+
+ public PaginationResults(List<T> collection, List<NeutronPageLink> links) {
+ this.collection = collection;
+ this.links = links;
+ }
+ }
+
+ private static final class MarkerObject implements INeutronObject {
+ private final String id;
+
+ MarkerObject(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public String getID() {
+ return id;
+ }
+
+ @Override
+ public void setID(String id) {
+ throw new UnsupportedOperationException("Marker has constant ID");
+ }
+ }
+
+ /*
+ * SuppressWarnings is needed because the compiler does not understand that we
+ * are actually safe here.
+ *
+ * FIXME: the only caller performs a cast back, so this is not actually necessary.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T extends INeutronObject> INeutronRequest<T> createRequest(Integer limit, String marker,
+ Boolean pageReverse,
+ UriInfo uriInfo,
+ List<T> collection,
+ Class<T> clazz) {
+ PaginationResults<T> results = _paginate(limit, marker, pageReverse, uriInfo, collection);
+
+ if (clazz.equals(NeutronNetwork.class)){
+ return (INeutronRequest<T>) new NeutronNetworkRequest((List<NeutronNetwork>) results.collection, results.links);
+ }
+ if (clazz.equals(NeutronSubnet.class)){
+ return (INeutronRequest<T>) new NeutronSubnetRequest((List<NeutronSubnet>) results.collection, results.links);
+ }
+ if (clazz.equals(NeutronPort.class)){
+ return (INeutronRequest<T>) new NeutronPortRequest((List<NeutronPort>) results.collection, results.links);
+ }
+ return null;
+ }
+
+ private static <T extends INeutronObject> PaginationResults<T> _paginate(Integer limit, String marker, Boolean pageReverse, UriInfo uriInfo, List<T> collection) {
+ List<NeutronPageLink> links = new ArrayList<>();
+ final int startPos;
+ String startMarker;
+ String endMarker;
+ Boolean firstPage = false;
+ Boolean lastPage = false;
+
+ Collections.sort(collection, NEUTRON_OBJECT_COMPARATOR);
+
+ if (marker != null) {
+ int offset = Collections.binarySearch(collection, new MarkerObject(marker), NEUTRON_OBJECT_COMPARATOR);
+ if (offset < 0) {
+ throw new ResourceNotFoundException("UUID for marker: " + marker + " could not be found");
+ }
+
+ if (!pageReverse) {
+ startPos = offset + 1;
+ }
+ else {
+ startPos = offset - limit;
+ }
+ }
+ else {
+ startPos = 0;
+ }
+
+ if (startPos == 0){
+ firstPage = true;
+ }
+
+ if (startPos + limit >= collection.size()) {
+ collection = collection.subList(startPos, collection.size());
+ startMarker = collection.get(0).getID();
+ endMarker = collection.get(collection.size() - 1).getID();
+ lastPage = true;
+ }
+ else if (startPos < 0) {
+ if (startPos + limit > 0) {
+ collection = collection.subList(0, startPos + limit);
+ startMarker = collection.get(0).getID();
+ endMarker = collection.get(collection.size() - 1).getID();
+ firstPage = true;
+ }
+ else {
+ throw new BadRequestException("Requested page is out of bounds. Please check the supplied limit and marker");
+ }
+ }
+ else {
+ collection = collection.subList(startPos, startPos + limit);
+ startMarker = collection.get(0).getID();
+ endMarker = collection.get(limit-1).getID();
+ }
+
+ if (!lastPage) {
+ NeutronPageLink next = new NeutronPageLink();
+ next.setRef("next");
+ next.setHref(uriInfo.getAbsolutePath().toString() + "?limit=" + limit.toString() + "&marker=" + endMarker);
+ links.add(next);
+ }
+
+ if (!firstPage) {
+ NeutronPageLink previous = new NeutronPageLink();
+ previous.setRef("previous");
+ previous.setHref(uriInfo.getAbsolutePath().toString() + "?limit=" + limit.toString() + "&marker=" + startMarker + "&page_reverse=True");
+ links.add(previous);
+ }
+
+ return new PaginationResults<T>(collection, links);
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>\r
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"\r
+ version="3.0">\r
+ <servlet>\r
+ <servlet-name>JAXRSNeutron</servlet-name>\r
+ <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>\r
+ <init-param>\r
+ <param-name>javax.ws.rs.Application</param-name>\r
+ <param-value>org.opendaylight.controller.networkconfig.neutron.northbound.NeutronNorthboundRSApplication</param-value>\r
+ </init-param>\r
+ <load-on-startup>1</load-on-startup>\r
+ </servlet>\r
+\r
+ <servlet-mapping>\r
+ <servlet-name>JAXRSNeutron</servlet-name>\r
+ <url-pattern>/*</url-pattern>\r
+ </servlet-mapping>\r
+ <security-constraint>\r
+ <web-resource-collection>\r
+ <web-resource-name>NB api</web-resource-name>\r
+ <url-pattern>/*</url-pattern>\r
+ </web-resource-collection>\r
+ <auth-constraint>\r
+ <role-name>System-Admin</role-name>\r
+ <role-name>Network-Admin</role-name>\r
+ <role-name>Network-Operator</role-name>\r
+ <role-name>Container-User</role-name>\r
+ </auth-constraint>\r
+ </security-constraint>\r
+\r
+ <security-role>\r
+ <role-name>System-Admin</role-name>\r
+ </security-role>\r
+ <security-role>\r
+ <role-name>Network-Admin</role-name>\r
+ </security-role>\r
+ <security-role>\r
+ <role-name>Network-Operator</role-name>\r
+ </security-role>\r
+ <security-role>\r
+ <role-name>Container-User</role-name>\r
+ </security-role>\r
+\r
+ <login-config>\r
+ <auth-method>BASIC</auth-method>\r
+ <realm-name>opendaylight</realm-name>\r
+ </login-config>\r
+</web-app>\r
--- /dev/null
+javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
\ No newline at end of file