Code cleanup: use collection interfaces in declarations
[neutron.git] / northbound-api / src / main / java / org / opendaylight / neutron / northbound / api / NeutronLoadBalancerPoolNorthbound.java
1 /*
2  * Copyright (C) 2014 SDN Hub, LLC.
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  * Authors : Srini Seetharaman
9  */
10
11 package org.opendaylight.neutron.northbound.api;
12
13 import java.net.HttpURLConnection;
14
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.Map;
20
21 import javax.ws.rs.Consumes;
22 import javax.ws.rs.DELETE;
23 import javax.ws.rs.GET;
24 import javax.ws.rs.POST;
25 import javax.ws.rs.PUT;
26 import javax.ws.rs.Path;
27 import javax.ws.rs.PathParam;
28 import javax.ws.rs.Produces;
29 import javax.ws.rs.QueryParam;
30 import javax.ws.rs.core.MediaType;
31 import javax.ws.rs.core.Response;
32
33 import org.codehaus.enunciate.jaxrs.ResponseCode;
34 import org.codehaus.enunciate.jaxrs.StatusCodes;
35 import org.opendaylight.neutron.spi.INeutronLoadBalancerPoolAware;
36 import org.opendaylight.neutron.spi.INeutronLoadBalancerPoolCRUD;
37 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
38 import org.opendaylight.neutron.spi.NeutronLoadBalancerPool;
39 import org.opendaylight.neutron.spi.NeutronLoadBalancerPoolMember;
40
41 /**
42  * Neutron Northbound REST APIs for LoadBalancerPool Policies.<br>
43  * This class provides REST APIs for managing neutron LoadBalancerPool Policies
44  *
45  * <br>
46  * <br>
47  * Authentication scheme : <b>HTTP Basic</b><br>
48  * Authentication realm : <b>opendaylight</b><br>
49  * Transport : <b>HTTP and HTTPS</b><br>
50  * <br>
51  * HTTPS Authentication is disabled by default. Administrator can enable it in
52  * tomcat-server.xml after adding a proper keystore / SSL certificate from a
53  * trusted authority.<br>
54  * More info :
55  * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
56  *
57  */
58
59 /**
60  * For now, the LB pool member data is maintained with the INeutronLoadBalancerPoolCRUD,
61  * and not duplicated within the INeutronLoadBalancerPoolMemberCRUD's cache.
62  */
63
64 @Path("/lbaas/pools")
65 public class NeutronLoadBalancerPoolNorthbound {
66
67     private static final int HTTP_OK_BOTTOM = 200;
68     private static final int HTTP_OK_TOP = 299;
69     private static final String INTERFACE_NAME = "LoadBalancerPool CRUD Interface";
70     private static final String UUID_NO_EXIST = "LoadBalancerPool UUID does not exist.";
71     private static final String NO_PROVIDERS = "No providers registered.  Please try again later";
72     private static final String NO_PROVIDER_LIST = "Couldn't get providers list.  Please try again later";
73
74     private NeutronLoadBalancerPool extractFields(NeutronLoadBalancerPool o, List<String> fields) {
75         return o.extractFields(fields);
76     }
77
78     private NeutronCRUDInterfaces getNeutronInterfaces() {
79         NeutronCRUDInterfaces answer = new NeutronCRUDInterfaces().fetchINeutronLoadBalancerPoolCRUD(this);
80         if (answer.getLoadBalancerPoolInterface() == null) {
81             throw new ServiceUnavailableException(INTERFACE_NAME
82                     + RestMessages.SERVICEUNAVAILABLE.toString());
83         }
84         return answer;
85     }
86
87     /**
88      * Returns a list of all LoadBalancerPool
89      * */
90     @GET
91     @Produces({ MediaType.APPLICATION_JSON })
92     @StatusCodes({
93             @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
94             @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
95             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
96             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
97
98     public Response listGroups(
99             // return fields
100             @QueryParam("fields") List<String> fields,
101             // OpenStack LoadBalancerPool attributes
102             @QueryParam("id") String queryLoadBalancerPoolID,
103             @QueryParam("tenant_id") String queryLoadBalancerPoolTenantID,
104             @QueryParam("name") String queryLoadBalancerPoolName,
105             @QueryParam("description") String queryLoadBalancerDescription,
106             @QueryParam("protocol") String queryLoadBalancerProtocol,
107             @QueryParam("lb_algorithm") String queryLoadBalancerPoolLbAlgorithm,
108             @QueryParam("healthmonitor_id") String queryLoadBalancerPoolHealthMonitorID,
109             @QueryParam("admin_state_up") String queryLoadBalancerIsAdminStateUp,
110             @QueryParam("members") List<NeutronLoadBalancerPoolMember> queryLoadBalancerPoolMembers,
111             // pagination
112             @QueryParam("limit") String limit,
113             @QueryParam("marker") String marker,
114             @QueryParam("page_reverse") String pageReverse
115             // sorting not supported
116     ) {
117         INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = getNeutronInterfaces().getLoadBalancerPoolInterface();
118         List<NeutronLoadBalancerPool> allLoadBalancerPools = loadBalancerPoolInterface.getAllNeutronLoadBalancerPools();
119         List<NeutronLoadBalancerPool> ans = new ArrayList<NeutronLoadBalancerPool>();
120         Iterator<NeutronLoadBalancerPool> i = allLoadBalancerPools.iterator();
121         while (i.hasNext()) {
122             NeutronLoadBalancerPool nsg = i.next();
123             if ((queryLoadBalancerPoolID == null ||
124                     queryLoadBalancerPoolID.equals(nsg.getLoadBalancerPoolID())) &&
125                     (queryLoadBalancerPoolTenantID == null ||
126                             queryLoadBalancerPoolTenantID.equals(nsg.getLoadBalancerPoolTenantID())) &&
127                     (queryLoadBalancerPoolName == null ||
128                             queryLoadBalancerPoolName.equals(nsg.getLoadBalancerPoolName())) &&
129                     (queryLoadBalancerDescription == null ||
130                             queryLoadBalancerDescription.equals(nsg.getLoadBalancerPoolDescription())) &&
131                     (queryLoadBalancerPoolLbAlgorithm == null ||
132                             queryLoadBalancerPoolLbAlgorithm.equals(nsg.getLoadBalancerPoolLbAlgorithm())) &&
133                     (queryLoadBalancerPoolHealthMonitorID == null ||
134                             queryLoadBalancerPoolHealthMonitorID.equals(nsg.getNeutronLoadBalancerPoolHealthMonitorID())) &&
135                     (queryLoadBalancerIsAdminStateUp == null ||
136                             queryLoadBalancerIsAdminStateUp.equals(nsg.getLoadBalancerPoolAdminIsStateIsUp())) &&
137                     (queryLoadBalancerPoolMembers.size() == 0 ||
138                             queryLoadBalancerPoolMembers.equals(nsg.getLoadBalancerPoolMembers()))) {
139                 if (fields.size() > 0) {
140                     ans.add(extractFields(nsg,fields));
141                 } else {
142                     ans.add(nsg);
143                 }
144             }
145         }
146         return Response.status(HttpURLConnection.HTTP_OK).entity(
147                 new NeutronLoadBalancerPoolRequest(ans)).build();
148     }
149
150     /**
151      * Returns a specific LoadBalancerPool */
152
153     @Path("{loadBalancerPoolID}")
154     @GET
155     @Produces({ MediaType.APPLICATION_JSON })
156     @StatusCodes({
157             @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
158             @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
159             @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
160             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
161             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
162     public Response showLoadBalancerPool(@PathParam("loadBalancerPoolID") String loadBalancerPoolID,
163             // return fields
164             @QueryParam("fields") List<String> fields) {
165         INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = getNeutronInterfaces().getLoadBalancerPoolInterface();
166         if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolID)) {
167             throw new ResourceNotFoundException(UUID_NO_EXIST);
168         }
169         if (fields.size() > 0) {
170             NeutronLoadBalancerPool ans = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolID);
171             return Response.status(HttpURLConnection.HTTP_OK).entity(
172                     new NeutronLoadBalancerPoolRequest(extractFields(ans, fields))).build();
173         } else {
174             return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronLoadBalancerPoolRequest(loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolID))).build();
175         }
176     }
177
178     /**
179      * Creates new LoadBalancerPool */
180
181     @POST
182     @Produces({ MediaType.APPLICATION_JSON })
183     @Consumes({ MediaType.APPLICATION_JSON })
184     @StatusCodes({
185             @ResponseCode(code = HttpURLConnection.HTTP_CREATED, condition = "Created"),
186             @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
187             @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
188             @ResponseCode(code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
189             @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
190             @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
191             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
192             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
193     public Response createLoadBalancerPools(final NeutronLoadBalancerPoolRequest input) {
194         INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = getNeutronInterfaces().getLoadBalancerPoolInterface();
195         if (input.isSingleton()) {
196             NeutronLoadBalancerPool singleton = input.getSingleton();
197
198             /*
199              *  Verify that the LoadBalancerPool doesn't already exist.
200              */
201             if (loadBalancerPoolInterface.neutronLoadBalancerPoolExists(singleton.getLoadBalancerPoolID())) {
202                 throw new BadRequestException("LoadBalancerPool UUID already exists");
203             }
204
205             Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerPoolAware.class, this);
206             if (instances != null) {
207                 if (instances.length > 0) {
208                     for (Object instance : instances) {
209                         INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
210                         int status = service.canCreateNeutronLoadBalancerPool(singleton);
211                         if (status < HttpURLConnection.HTTP_OK || status > HTTP_OK_TOP) {
212                             return Response.status(status).build();
213                         }
214                     }
215                 } else {
216                     throw new ServiceUnavailableException(NO_PROVIDERS);
217                 }
218             } else {
219                 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
220             }
221             loadBalancerPoolInterface.addNeutronLoadBalancerPool(singleton);
222             if (instances != null) {
223                 for (Object instance : instances) {
224                     INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
225                     service.neutronLoadBalancerPoolCreated(singleton);
226                 }
227             }
228         } else {
229             List<NeutronLoadBalancerPool> bulk = input.getBulk();
230             Iterator<NeutronLoadBalancerPool> i = bulk.iterator();
231             Map<String, NeutronLoadBalancerPool> testMap = new HashMap<String, NeutronLoadBalancerPool>();
232             Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerPoolAware.class, this);
233             while (i.hasNext()) {
234                 NeutronLoadBalancerPool test = i.next();
235
236                 /*
237                  *  Verify that the loadBalancerPool doesn't already exist
238                  */
239
240                 if (loadBalancerPoolInterface.neutronLoadBalancerPoolExists(test.getLoadBalancerPoolID())) {
241                     throw new BadRequestException("Load Balancer Pool UUID already is already created");
242                 }
243                 if (testMap.containsKey(test.getLoadBalancerPoolID())) {
244                     throw new BadRequestException("Load Balancer Pool UUID already exists");
245                 }
246                 if (instances != null) {
247                     if (instances.length > 0) {
248                         for (Object instance : instances) {
249                             INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
250                             int status = service.canCreateNeutronLoadBalancerPool(test);
251                             if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
252                                 return Response.status(status).build();
253                             }
254                         }
255                     } else {
256                         throw new ServiceUnavailableException(NO_PROVIDERS);
257                     }
258                 } else {
259                     throw new ServiceUnavailableException(NO_PROVIDER_LIST);
260                 }
261             }
262             /*
263              * now, each element of the bulk request can be added to the cache
264              */
265             i = bulk.iterator();
266             while (i.hasNext()) {
267                 NeutronLoadBalancerPool test = i.next();
268                 loadBalancerPoolInterface.addNeutronLoadBalancerPool(test);
269                 if (instances != null) {
270                     for (Object instance : instances) {
271                         INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
272                         service.neutronLoadBalancerPoolCreated(test);
273                     }
274                 }
275             }
276         }
277         return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build();
278     }
279
280     /**
281      * Updates a LoadBalancerPool Policy
282      */
283     @Path("{loadBalancerPoolID}")
284     @PUT
285     @Produces({ MediaType.APPLICATION_JSON })
286     @Consumes({ MediaType.APPLICATION_JSON })
287     @StatusCodes({
288             @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
289             @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
290             @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
291             @ResponseCode(code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
292             @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
293             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
294             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
295     public Response updateLoadBalancerPool(
296             @PathParam("loadBalancerPoolID") String loadBalancerPoolID, final NeutronLoadBalancerPoolRequest input) {
297         INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = getNeutronInterfaces().getLoadBalancerPoolInterface();
298
299         /*
300          * verify the LoadBalancerPool exists and there is only one delta provided
301          */
302         if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolID)) {
303             throw new ResourceNotFoundException(UUID_NO_EXIST);
304         }
305         if (!input.isSingleton()) {
306             throw new BadRequestException("Only singleton edit supported");
307         }
308         NeutronLoadBalancerPool delta = input.getSingleton();
309         NeutronLoadBalancerPool original = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolID);
310
311         /*
312          * updates restricted by Neutron
313          */
314         if (delta.getLoadBalancerPoolID() != null ||
315                 delta.getLoadBalancerPoolTenantID() != null ||
316                 delta.getLoadBalancerPoolName() != null ||
317                 delta.getLoadBalancerPoolDescription() != null ||
318                 delta.getLoadBalancerPoolProtocol() != null ||
319                 delta.getLoadBalancerPoolLbAlgorithm() != null ||
320                 delta.getNeutronLoadBalancerPoolHealthMonitorID() != null ||
321                 delta.getLoadBalancerPoolAdminIsStateIsUp() != null ||
322                 delta.getLoadBalancerPoolMembers() != null) {
323             throw new BadRequestException("Attribute edit blocked by Neutron");
324         }
325
326         Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerPoolAware.class, this);
327         if (instances != null) {
328             if (instances.length > 0) {
329                 for (Object instance : instances) {
330                     INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
331                     int status = service.canUpdateNeutronLoadBalancerPool(delta, original);
332                     if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
333                         return Response.status(status).build();
334                     }
335                 }
336             } else {
337                 throw new ServiceUnavailableException(NO_PROVIDERS);
338             }
339         } else {
340             throw new ServiceUnavailableException(NO_PROVIDER_LIST);
341         }
342
343         /*
344          * update the object and return it
345          */
346         loadBalancerPoolInterface.updateNeutronLoadBalancerPool(loadBalancerPoolID, delta);
347         NeutronLoadBalancerPool updatedLoadBalancerPool = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolID);
348         if (instances != null) {
349             for (Object instance : instances) {
350                 INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
351                 service.neutronLoadBalancerPoolUpdated(updatedLoadBalancerPool);
352             }
353         }
354         return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronLoadBalancerPoolRequest(loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolID))).build();
355     }
356
357     /**
358      * Deletes a LoadBalancerPool
359      */
360
361     @Path("{loadBalancerPoolUUID}")
362     @DELETE
363     @StatusCodes({
364             @ResponseCode(code = HttpURLConnection.HTTP_NO_CONTENT, condition = "No Content"),
365             @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
366             @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
367             @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
368             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
369             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
370     public Response deleteLoadBalancerPool(
371             @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID) {
372         INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = getNeutronInterfaces().getLoadBalancerPoolInterface();
373
374         /*
375          * verify the LoadBalancerPool exists and it isn't currently in use
376          */
377         if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
378             throw new ResourceNotFoundException(UUID_NO_EXIST);
379         }
380         if (loadBalancerPoolInterface.neutronLoadBalancerPoolInUse(loadBalancerPoolUUID)) {
381             return Response.status(HttpURLConnection.HTTP_CONFLICT).build();
382         }
383         NeutronLoadBalancerPool singleton = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID);
384         Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerPoolAware.class, this);
385         if (instances != null) {
386             if (instances.length > 0) {
387                 for (Object instance : instances) {
388                     INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
389                     int status = service.canDeleteNeutronLoadBalancerPool(singleton);
390                     if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
391                         return Response.status(status).build();
392                     }
393                 }
394             } else {
395                 throw new ServiceUnavailableException(NO_PROVIDERS);
396             }
397         } else {
398             throw new ServiceUnavailableException(NO_PROVIDER_LIST);
399         }
400
401         /*
402          * remove it and return 204 status
403          */
404         loadBalancerPoolInterface.removeNeutronLoadBalancerPool(loadBalancerPoolUUID);
405         if (instances != null) {
406             for (Object instance : instances) {
407                 INeutronLoadBalancerPoolAware service = (INeutronLoadBalancerPoolAware) instance;
408                 service.neutronLoadBalancerPoolDeleted(singleton);
409             }
410         }
411         return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build();
412     }
413 }