northbound: introduce a base class for nortubhound classes
[neutron.git] / northbound-api / src / main / java / org / opendaylight / neutron / northbound / api / NeutronFloatingIPsNorthbound.java
1 /*
2  * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.neutron.northbound.api;
10
11 import java.net.HttpURLConnection;
12
13 import java.util.ArrayList;
14 import java.util.Iterator;
15 import java.util.List;
16
17 import javax.ws.rs.Consumes;
18 import javax.ws.rs.DELETE;
19 import javax.ws.rs.GET;
20 import javax.ws.rs.POST;
21 import javax.ws.rs.PUT;
22 import javax.ws.rs.Path;
23 import javax.ws.rs.PathParam;
24 import javax.ws.rs.Produces;
25 import javax.ws.rs.QueryParam;
26 import javax.ws.rs.core.MediaType;
27 import javax.ws.rs.core.Response;
28
29 import org.codehaus.enunciate.jaxrs.ResponseCode;
30 import org.codehaus.enunciate.jaxrs.StatusCodes;
31 import org.opendaylight.neutron.spi.INeutronFloatingIPAware;
32 import org.opendaylight.neutron.spi.INeutronFloatingIPCRUD;
33 import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
34 import org.opendaylight.neutron.spi.INeutronPortCRUD;
35 import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
36 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
37 import org.opendaylight.neutron.spi.NeutronFloatingIP;
38 import org.opendaylight.neutron.spi.NeutronNetwork;
39
40 /**
41  * Neutron Northbound REST APIs.<br>
42  * This class provides REST APIs for managing Neutron Floating IPs
43  *
44  * <br>
45  * <br>
46  * Authentication scheme : <b>HTTP Basic</b><br>
47  * Authentication realm : <b>opendaylight</b><br>
48  * Transport : <b>HTTP and HTTPS</b><br>
49  * <br>
50  * HTTPS Authentication is disabled by default. Administrator can enable it in
51  * tomcat-server.xml after adding a proper keystore / SSL certificate from a
52  * trusted authority.<br>
53  * More info :
54  * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
55  *
56  */
57
58 @Path("/floatingips")
59 public class NeutronFloatingIPsNorthbound extends AbstractNeutronNorthbound {
60     private static final String RESOURCE_NAME = "Floating IP";
61
62
63     private NeutronFloatingIP extractFields(NeutronFloatingIP o, List<String> fields) {
64         return o.extractFields(fields);
65     }
66
67     private NeutronCRUDInterfaces getNeutronInterfaces(boolean flag) {
68         NeutronCRUDInterfaces answer = new NeutronCRUDInterfaces().fetchINeutronFloatingIPCRUD(this);
69         if (answer.getFloatingIPInterface() == null) {
70             throw new ServiceUnavailableException(serviceUnavailable(RESOURCE_NAME));
71         }
72         if (flag) {
73             answer = answer.fetchINeutronNetworkCRUD(this).fetchINeutronSubnetCRUD(this).fetchINeutronPortCRUD(this);
74             if (answer.getNetworkInterface() == null) {
75                 throw new ServiceUnavailableException("Network CRUD Interface "
76                         + RestMessages.SERVICEUNAVAILABLE.toString());
77             }
78             if (answer.getSubnetInterface() == null) {
79                 throw new ServiceUnavailableException("Subnet CRUD Interface "
80                         + RestMessages.SERVICEUNAVAILABLE.toString());
81             }
82             if (answer.getPortInterface() == null) {
83                 throw new ServiceUnavailableException("Port CRUD Interface "
84                         + RestMessages.SERVICEUNAVAILABLE.toString());
85             }
86         }
87         return answer;
88     }
89     /**
90      * Returns a list of all FloatingIPs */
91
92     @GET
93     @Produces({ MediaType.APPLICATION_JSON })
94     @StatusCodes({
95             @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
96             @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
97             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
98             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
99     public Response listFloatingIPs(
100             // return fields
101             @QueryParam("fields") List<String> fields,
102             // note: openstack isn't clear about filtering on lists, so we aren't handling them
103             @QueryParam("id") String queryID,
104             @QueryParam("floating_network_id") String queryFloatingNetworkId,
105             @QueryParam("port_id") String queryPortId,
106             @QueryParam("fixed_ip_address") String queryFixedIPAddress,
107             @QueryParam("floating_ip_address") String queryFloatingIPAddress,
108             @QueryParam("tenant_id") String queryTenantID,
109             @QueryParam("router_id") String queryRouterID,
110             @QueryParam("status") String queryStatus,
111             // pagination
112             @QueryParam("limit") String limit,
113             @QueryParam("marker") String marker,
114             @QueryParam("page_reverse") String pageReverse
115             // sorting not supported
116             ) {
117         INeutronFloatingIPCRUD floatingIPInterface = getNeutronInterfaces(false).getFloatingIPInterface();
118         List<NeutronFloatingIP> allFloatingIPs = floatingIPInterface.getAllFloatingIPs();
119         List<NeutronFloatingIP> ans = new ArrayList<NeutronFloatingIP>();
120         Iterator<NeutronFloatingIP> i = allFloatingIPs.iterator();
121         while (i.hasNext()) {
122             NeutronFloatingIP oSS = i.next();
123             //match filters: TODO provider extension and router extension
124             if ((queryID == null || queryID.equals(oSS.getID())) &&
125                     (queryFloatingNetworkId == null || queryFloatingNetworkId.equals(oSS.getFloatingNetworkUUID())) &&
126                     (queryPortId == null || queryPortId.equals(oSS.getPortUUID())) &&
127                     (queryFixedIPAddress == null || queryFixedIPAddress.equals(oSS.getFixedIPAddress())) &&
128                     (queryFloatingIPAddress == null || queryFloatingIPAddress.equals(oSS.getFloatingIPAddress())) &&
129                     (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&
130                     (queryRouterID == null || queryRouterID.equals(oSS.getRouterUUID())) &&
131                     (queryTenantID == null || queryTenantID.equals(oSS.getTenantUUID()))) {
132                 if (fields.size() > 0) {
133                     ans.add(extractFields(oSS,fields));
134                 } else {
135                     ans.add(oSS);
136                 }
137             }
138         }
139         //TODO: apply pagination to results
140         return Response.status(HttpURLConnection.HTTP_OK).entity(
141                 new NeutronFloatingIPRequest(ans)).build();
142     }
143
144     /**
145      * Returns a specific FloatingIP */
146
147     @Path("{floatingipUUID}")
148     @GET
149     @Produces({ MediaType.APPLICATION_JSON })
150     @StatusCodes({
151             @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
152             @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
153             @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
154             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
155             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
156     public Response showFloatingIP(
157             @PathParam("floatingipUUID") String floatingipUUID,
158             // return fields
159             @QueryParam("fields") List<String> fields ) {
160         INeutronFloatingIPCRUD floatingIPInterface = getNeutronInterfaces(false).getFloatingIPInterface();
161         if (!floatingIPInterface.floatingIPExists(floatingipUUID)) {
162             throw new ResourceNotFoundException(uuidNoExist(RESOURCE_NAME));
163         }
164         if (fields.size() > 0) {
165             NeutronFloatingIP ans = floatingIPInterface.getFloatingIP(floatingipUUID);
166             return Response.status(HttpURLConnection.HTTP_OK).entity(
167                     new NeutronFloatingIPRequest(extractFields(ans, fields))).build();
168         } else {
169             return Response.status(HttpURLConnection.HTTP_OK).entity(
170                     new NeutronFloatingIPRequest(floatingIPInterface.getFloatingIP(floatingipUUID))).build();
171         }
172     }
173
174     /**
175      * Creates new FloatingIPs */
176
177     @POST
178     @Produces({ MediaType.APPLICATION_JSON })
179     @Consumes({ MediaType.APPLICATION_JSON })
180     @StatusCodes({
181         @ResponseCode(code = HttpURLConnection.HTTP_CREATED, condition = "Created"),
182         @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
183     public Response createFloatingIPs(final NeutronFloatingIPRequest input) {
184         NeutronCRUDInterfaces interfaces = getNeutronInterfaces(true);
185         INeutronFloatingIPCRUD floatingIPInterface = interfaces.getFloatingIPInterface();
186         if (input.isSingleton()) {
187             Object[] instances = NeutronUtil.getInstances(INeutronFloatingIPAware.class, this);
188             if (instances != null) {
189                 if (instances.length > 0) {
190                     for (Object instance : instances) {
191                         INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
192                         int status = service.canCreateFloatingIP(input.getSingleton());
193                         if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
194                             return Response.status(status).build();
195                         }
196                     }
197                 } else {
198                     throw new ServiceUnavailableException(NO_PROVIDERS);
199                 }
200             } else {
201                 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
202             }
203             floatingIPInterface.addFloatingIP(input.getSingleton());
204             if (instances != null) {
205                 for (Object instance : instances) {
206                     INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
207                     service.neutronFloatingIPCreated(input.getSingleton());
208                 }
209             }
210         } else {
211             throw new BadRequestException("only singleton requests allowed.");
212         }
213         return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build();
214     }
215
216     /**
217      * Updates a FloatingIP */
218
219     @Path("{floatingipUUID}")
220     @PUT
221     @Produces({ MediaType.APPLICATION_JSON })
222     @Consumes({ MediaType.APPLICATION_JSON })
223     @StatusCodes({
224             @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
225             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
226     public Response updateFloatingIP(
227             @PathParam("floatingipUUID") String floatingipUUID,
228             NeutronFloatingIPRequest input
229             ) {
230         NeutronCRUDInterfaces interfaces = getNeutronInterfaces(true);
231         INeutronFloatingIPCRUD floatingIPInterface = interfaces.getFloatingIPInterface();
232
233         NeutronFloatingIP singleton = input.getSingleton();
234         NeutronFloatingIP target = floatingIPInterface.getFloatingIP(floatingipUUID);
235         Object[] instances = NeutronUtil.getInstances(INeutronFloatingIPAware.class, this);
236         if (instances != null) {
237             if (instances.length > 0) {
238                 for (Object instance : instances) {
239                     INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
240                     int status = service.canUpdateFloatingIP(singleton, target);
241                     if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
242                         return Response.status(status).build();
243                     }
244                 }
245             } else {
246                 throw new ServiceUnavailableException(NO_PROVIDERS);
247             }
248         } else {
249             throw new ServiceUnavailableException(NO_PROVIDER_LIST);
250         }
251         floatingIPInterface.updateFloatingIP(floatingipUUID, singleton);
252         target = floatingIPInterface.getFloatingIP(floatingipUUID);
253         if (instances != null) {
254             for (Object instance : instances) {
255                 INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
256                 service.neutronFloatingIPUpdated(target);
257             }
258         }
259         return Response.status(HttpURLConnection.HTTP_OK).entity(
260                 new NeutronFloatingIPRequest(target)).build();
261
262     }
263
264     /**
265      * Deletes a FloatingIP */
266
267     @Path("{floatingipUUID}")
268     @DELETE
269     @StatusCodes({
270             @ResponseCode(code = HttpURLConnection.HTTP_NO_CONTENT, condition = "No Content"),
271             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
272     public Response deleteFloatingIP(
273             @PathParam("floatingipUUID") String floatingipUUID) {
274         INeutronFloatingIPCRUD floatingIPInterface = getNeutronInterfaces(false).getFloatingIPInterface();
275         NeutronFloatingIP singleton = floatingIPInterface.getFloatingIP(floatingipUUID);
276         Object[] instances = NeutronUtil.getInstances(INeutronFloatingIPAware.class, this);
277         if (instances != null) {
278             if (instances.length > 0) {
279                 for (Object instance : instances) {
280                     INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
281                     int status = service.canDeleteFloatingIP(singleton);
282                     if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
283                         return Response.status(status).build();
284                     }
285                 }
286             } else {
287                 throw new ServiceUnavailableException(NO_PROVIDERS);
288             }
289         } else {
290             throw new ServiceUnavailableException(NO_PROVIDER_LIST);
291         }
292         floatingIPInterface.removeFloatingIP(floatingipUUID);
293         if (instances != null) {
294             for (Object instance : instances) {
295                 INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
296                 service.neutronFloatingIPDeleted(singleton);
297             }
298         }
299         return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build();
300     }
301 }