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