Merge "Bug 2697: Improvement wrong response handling, missing message"
[controller.git] / opendaylight / networkconfiguration / neutron / northbound / src / main / java / org / opendaylight / controller / networkconfig / neutron / northbound / NeutronLoadBalancerPoolMembersNorthbound.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.controller.networkconfig.neutron.northbound;
12
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.List;
17
18 import javax.ws.rs.Consumes;
19 import javax.ws.rs.DELETE;
20 import javax.ws.rs.GET;
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.controller.networkconfig.neutron.INeutronLoadBalancerPoolCRUD;
32 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolMemberAware;
33 import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
34 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool;
35 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPoolMember;
36
37 @Path("/pools/{loadBalancerPoolUUID}/members")
38 public class NeutronLoadBalancerPoolMembersNorthbound {
39     private NeutronLoadBalancerPoolMember extractFields(NeutronLoadBalancerPoolMember o, List<String> fields) {
40         return o.extractFields(fields);
41     }
42 /**
43  * Returns a list of all LoadBalancerPoolMembers in specified pool
44  */
45 @GET
46 @Produces({MediaType.APPLICATION_JSON})
47 @StatusCodes({
48         @ResponseCode(code = 200, condition = "Operation successful"),
49         @ResponseCode(code = 401, condition = "Unauthorized"),
50         @ResponseCode(code = 501, condition = "Not Implemented")})
51
52 public Response listMembers(
53         //Path param
54         @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
55
56         // return fields
57         @QueryParam("fields") List<String> fields,
58
59         // OpenStack LoadBalancerPool attributes
60         @QueryParam("id") String queryLoadBalancerPoolMemberID,
61         @QueryParam("tenant_id") String queryLoadBalancerPoolMemberTenantID,
62         @QueryParam("address") String queryLoadBalancerPoolMemberAddress,
63         @QueryParam("protocol_port") String queryLoadBalancerPoolMemberProtoPort,
64         @QueryParam("admin_state_up") String queryLoadBalancerPoolMemberAdminStateUp,
65         @QueryParam("weight") String queryLoadBalancerPoolMemberWeight,
66         @QueryParam("subnet_id") String queryLoadBalancerPoolMemberSubnetID,
67         @QueryParam("status") String queryLoadBalancerPoolMemberStatus,
68
69         // pagination
70         @QueryParam("limit") String limit,
71         @QueryParam("marker") String marker,
72         @QueryParam("page_reverse") String pageReverse
73         // sorting not supported
74 ) {
75     INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces
76             .getINeutronLoadBalancerPoolCRUD(this);
77     if (loadBalancerPoolInterface == null) {
78         throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
79                 + RestMessages.SERVICEUNAVAILABLE.toString());
80     }
81     if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
82         throw new ResourceNotFoundException("loadBalancerPool UUID does not exist.");
83     }
84     List<NeutronLoadBalancerPoolMember> members =
85                 loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID).getLoadBalancerPoolMembers();
86     List<NeutronLoadBalancerPoolMember> ans = new ArrayList<NeutronLoadBalancerPoolMember>();
87     Iterator<NeutronLoadBalancerPoolMember> i = members.iterator();
88     while (i.hasNext()) {
89         NeutronLoadBalancerPoolMember nsg = i.next();
90         if ((queryLoadBalancerPoolMemberID == null ||
91                 queryLoadBalancerPoolMemberID.equals(nsg.getPoolMemberID())) &&
92                 loadBalancerPoolUUID.equals(nsg.getPoolID()) &&
93                 (queryLoadBalancerPoolMemberTenantID == null ||
94                         queryLoadBalancerPoolMemberTenantID.equals(nsg.getPoolMemberTenantID())) &&
95                 (queryLoadBalancerPoolMemberAddress == null ||
96                         queryLoadBalancerPoolMemberAddress.equals(nsg.getPoolMemberAddress())) &&
97                 (queryLoadBalancerPoolMemberAdminStateUp == null ||
98                         queryLoadBalancerPoolMemberAdminStateUp.equals(nsg.getPoolMemberAdminStateIsUp())) &&
99                 (queryLoadBalancerPoolMemberWeight == null ||
100                         queryLoadBalancerPoolMemberWeight.equals(nsg.getPoolMemberWeight())) &&
101                 (queryLoadBalancerPoolMemberSubnetID == null ||
102                         queryLoadBalancerPoolMemberSubnetID.equals(nsg.getPoolMemberSubnetID())) &&
103                 (queryLoadBalancerPoolMemberStatus == null ||
104                         queryLoadBalancerPoolMemberStatus.equals(nsg.getPoolMemberStatus()))) {
105             if (fields.size() > 0) {
106                 ans.add(extractFields(nsg, fields));
107             } else {
108                 ans.add(nsg);
109             }
110         }
111     }
112     return Response.status(200).entity(
113             new NeutronLoadBalancerPoolMemberRequest(ans)).build();
114 }
115
116 /**
117  * Returns a specific LoadBalancerPoolMember
118  */
119
120 @Path("{loadBalancerPoolMemberUUID}")
121 @GET
122 @Produces({ MediaType.APPLICATION_JSON })
123 //@TypeHint(OpenStackLoadBalancerPoolMembers.class)
124 @StatusCodes({
125     @ResponseCode(code = 200, condition = "Operation successful"),
126     @ResponseCode(code = 401, condition = "Unauthorized"),
127     @ResponseCode(code = 404, condition = "Not Found"),
128     @ResponseCode(code = 501, condition = "Not Implemented") })
129 public Response showLoadBalancerPoolMember(
130         @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
131         @PathParam("loadBalancerPoolMemberUUID") String loadBalancerPoolMemberUUID,
132         // return fields
133         @QueryParam("fields") List<String> fields ) {
134
135     INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces
136             .getINeutronLoadBalancerPoolCRUD(this);
137     if (loadBalancerPoolInterface == null) {
138         throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
139                 + RestMessages.SERVICEUNAVAILABLE.toString());
140     }
141     if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
142         throw new ResourceNotFoundException("loadBalancerPool UUID does not exist.");
143     }
144     List<NeutronLoadBalancerPoolMember> members =
145                 loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID).getLoadBalancerPoolMembers();
146     for (NeutronLoadBalancerPoolMember ans: members) {
147         if (!ans.getPoolMemberID().equals(loadBalancerPoolMemberUUID))
148             continue;
149
150         if (fields.size() > 0) {
151             return Response.status(200).entity(
152                 new NeutronLoadBalancerPoolMemberRequest(extractFields(ans, fields))).build();
153         } else {
154             return Response.status(200).entity(
155                 new NeutronLoadBalancerPoolMemberRequest(ans)).build();
156         }
157     }
158     return Response.status(204).build();
159 }
160
161 /**
162  * Adds a Member to an LBaaS Pool member
163  */
164 @PUT
165 @Produces({MediaType.APPLICATION_JSON})
166 @Consumes({MediaType.APPLICATION_JSON})
167 @StatusCodes({
168         @ResponseCode(code = 200, condition = "Operation successful"),
169         @ResponseCode(code = 401, condition = "Unauthorized"),
170         @ResponseCode(code = 404, condition = "Not Found"),
171         @ResponseCode(code = 501, condition = "Not Implemented")})
172 public Response createLoadBalancerPoolMember(
173         @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
174         final NeutronLoadBalancerPoolMemberRequest input) {
175
176     INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolCRUD(this);
177     if (loadBalancerPoolInterface == null) {
178         throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
179                 + RestMessages.SERVICEUNAVAILABLE.toString());
180     }
181     // Verify that the loadBalancerPool exists, for the member to be added to its cache
182     if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
183         throw new ResourceNotFoundException("loadBalancerPool UUID does not exist.");
184     }
185     NeutronLoadBalancerPool singletonPool = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID);
186
187     if (input.isSingleton()) {
188         NeutronLoadBalancerPoolMember singleton = input.getSingleton();
189         singleton.setPoolID(loadBalancerPoolUUID);
190         String loadBalancerPoolMemberUUID = singleton.getPoolMemberID();
191
192         /*
193          *  Verify that the LoadBalancerPoolMember doesn't already exist.
194          */
195         List<NeutronLoadBalancerPoolMember> members = singletonPool.getLoadBalancerPoolMembers();
196         for (NeutronLoadBalancerPoolMember member: members) {
197             if (member.getPoolMemberID().equals(loadBalancerPoolMemberUUID))
198                 throw new BadRequestException("LoadBalancerPoolMember UUID already exists");
199         }
200
201         Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerPoolMemberAware.class, this);
202         if (instances != null) {
203             if (instances.length > 0) {
204                 for (Object instance : instances) {
205                     INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
206                     int status = service.canCreateNeutronLoadBalancerPoolMember(singleton);
207                     if (status < 200 || status > 299) {
208                         return Response.status(status).build();
209                     }
210                 }
211             } else {
212                 throw new ServiceUnavailableException("No providers registered.  Please try again later");
213             }
214         } else {
215             throw new ServiceUnavailableException("Couldn't get providers list.  Please try again later");
216         }
217
218         if (instances != null) {
219             for (Object instance : instances) {
220                 INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
221                 service.neutronLoadBalancerPoolMemberCreated(singleton);
222             }
223         }
224
225         /**
226          * Add the member from the neutron load balancer pool as well
227          */
228         singletonPool.addLoadBalancerPoolMember(singleton);
229
230     } else {
231         List<NeutronLoadBalancerPoolMember> bulk = input.getBulk();
232         Iterator<NeutronLoadBalancerPoolMember> i = bulk.iterator();
233         HashMap<String, NeutronLoadBalancerPoolMember> testMap = new HashMap<String, NeutronLoadBalancerPoolMember>();
234         Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerPoolMemberAware.class, this);
235         while (i.hasNext()) {
236             NeutronLoadBalancerPoolMember test = i.next();
237             String loadBalancerPoolMemberUUID = test.getPoolMemberID();
238
239             /*
240              *  Verify that the LoadBalancerPoolMember doesn't already exist.
241              */
242             List<NeutronLoadBalancerPoolMember> members = singletonPool.getLoadBalancerPoolMembers();
243             for (NeutronLoadBalancerPoolMember member: members) {
244                 if (member.getPoolMemberID().equals(loadBalancerPoolMemberUUID))
245                     throw new BadRequestException("LoadBalancerPoolMember UUID already exists");
246             }
247
248             if (testMap.containsKey(test.getPoolMemberID())) {
249                 throw new BadRequestException("Load Balancer PoolMember UUID already exists");
250             }
251             if (instances != null) {
252                 if (instances.length > 0) {
253                     for (Object instance : instances) {
254                         INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
255                         int status = service.canCreateNeutronLoadBalancerPoolMember(test);
256                         if (status < 200 || status > 299) {
257                             return Response.status(status).build();
258                         }
259                     }
260                 } else {
261                     throw new ServiceUnavailableException("No providers registered.  Please try again later");
262                 }
263             } else {
264                 throw new ServiceUnavailableException("Couldn't get providers list.  Please try again later");
265             }
266         }
267         /*
268          * now, each element of the bulk request can be added to the cache
269          */
270         i = bulk.iterator();
271         while (i.hasNext()) {
272             NeutronLoadBalancerPoolMember test = i.next();
273             if (instances != null) {
274                 for (Object instance : instances) {
275                     INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
276                     service.neutronLoadBalancerPoolMemberCreated(test);
277                 }
278             }
279             singletonPool.addLoadBalancerPoolMember(test);
280         }
281     }
282     return Response.status(201).entity(input).build();
283 }
284
285 /**
286  * Updates a LB member pool
287  */
288
289 @Path("{loadBalancerPoolMemberUUID}")
290 @PUT
291 @Produces({ MediaType.APPLICATION_JSON })
292 @Consumes({ MediaType.APPLICATION_JSON })
293 @StatusCodes({
294         @ResponseCode(code = 200, condition = "Operation successful"),
295         @ResponseCode(code = 400, condition = "Bad Request"),
296         @ResponseCode(code = 401, condition = "Unauthorized"),
297         @ResponseCode(code = 403, condition = "Forbidden"),
298         @ResponseCode(code = 404, condition = "Not Found"),
299         @ResponseCode(code = 501, condition = "Not Implemented") })
300 public Response updateLoadBalancerPoolMember(
301         @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
302         @PathParam("loadBalancerPoolMemberUUID") String loadBalancerPoolMemberUUID,
303         final NeutronLoadBalancerPoolMemberRequest input) {
304
305     //TODO: Implement update LB member pool
306     return Response.status(501).entity(input).build();
307 }
308
309 /**
310  * Deletes a LoadBalancerPoolMember
311  */
312
313 @Path("{loadBalancerPoolMemberUUID}")
314 @DELETE
315 @StatusCodes({
316     @ResponseCode(code = 204, condition = "No Content"),
317     @ResponseCode(code = 401, condition = "Unauthorized"),
318     @ResponseCode(code = 403, condition = "Forbidden"),
319     @ResponseCode(code = 404, condition = "Not Found"),
320     @ResponseCode(code = 501, condition = "Not Implemented") })
321 public Response deleteLoadBalancerPoolMember(
322         @PathParam("loadBalancerPoolUUID") String loadBalancerPoolUUID,
323         @PathParam("loadBalancerPoolMemberUUID") String loadBalancerPoolMemberUUID) {
324     INeutronLoadBalancerPoolCRUD loadBalancerPoolInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerPoolCRUD(this);
325     if (loadBalancerPoolInterface == null) {
326         throw new ServiceUnavailableException("LoadBalancerPool CRUD Interface "
327                 + RestMessages.SERVICEUNAVAILABLE.toString());
328     }
329
330     // Verify that the loadBalancerPool exists, for the member to be removed from its cache
331     if (!loadBalancerPoolInterface.neutronLoadBalancerPoolExists(loadBalancerPoolUUID)) {
332         throw new ResourceNotFoundException("loadBalancerPool UUID does not exist.");
333     }
334
335     //Verify that the LB pool member exists
336     NeutronLoadBalancerPoolMember singleton = null;
337     List<NeutronLoadBalancerPoolMember> members =
338             loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID).getLoadBalancerPoolMembers();
339     for (NeutronLoadBalancerPoolMember member: members) {
340         if (member.getPoolMemberID().equals(loadBalancerPoolMemberUUID)) {
341             singleton = member;
342             break;
343         }
344     }
345     if (singleton == null)
346         throw new BadRequestException("LoadBalancerPoolMember UUID does not exist.");
347
348     Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerPoolMemberAware.class, this);
349     if (instances != null) {
350         if (instances.length > 0) {
351             for (Object instance : instances) {
352                 INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
353                 int status = service.canDeleteNeutronLoadBalancerPoolMember(singleton);
354                 if (status < 200 || status > 299) {
355                     return Response.status(status).build();
356                 }
357             }
358         } else {
359             throw new ServiceUnavailableException("No providers registered.  Please try again later");
360         }
361     } else {
362         throw new ServiceUnavailableException("Couldn't get providers list.  Please try again later");
363     }
364
365     if (instances != null) {
366         for (Object instance : instances) {
367             INeutronLoadBalancerPoolMemberAware service = (INeutronLoadBalancerPoolMemberAware) instance;
368             service.neutronLoadBalancerPoolMemberDeleted(singleton);
369         }
370     }
371
372     /**
373      * Remove the member from the neutron load balancer pool
374      */
375     NeutronLoadBalancerPool singletonPool = loadBalancerPoolInterface.getNeutronLoadBalancerPool(loadBalancerPoolUUID);
376     singletonPool.removeLoadBalancerPoolMember(singleton);
377
378     return Response.status(204).build();
379 }
380 }