BUG #4026 neutron spi: make NeutronObject implements INeutronObject
[neutron.git] / northbound-api / src / main / java / org / opendaylight / neutron / northbound / api / NeutronLoadBalancerNorthbound.java
1 /*
2  * Copyright (C) 2014 Red Hat, Inc.
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.INeutronLoadBalancerAware;
32 import org.opendaylight.neutron.spi.INeutronLoadBalancerCRUD;
33 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
34 import org.opendaylight.neutron.spi.NeutronLoadBalancer;
35
36 /**
37  * Neutron Northbound REST APIs for LoadBalancers.<br>
38  * This class provides REST APIs for managing neutron LoadBalancers
39  *
40  * <br>
41  * <br>
42  * Authentication scheme : <b>HTTP Basic</b><br>
43  * Authentication realm : <b>opendaylight</b><br>
44  * Transport : <b>HTTP and HTTPS</b><br>
45  * <br>
46  * HTTPS Authentication is disabled by default. Administrator can enable it in
47  * tomcat-server.xml after adding a proper keystore / SSL certificate from a
48  * trusted authority.<br>
49  * More info :
50  * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
51  *
52  */
53 @Path("/lbaas/loadbalancers")
54 public class NeutronLoadBalancerNorthbound {
55
56     private static final int HTTP_OK_BOTTOM = 200;
57     private static final int HTTP_OK_TOP = 299;
58     private static final String INTERFACE_NAME = "LoadBalancer CRUD Interface";
59     private static final String UUID_NO_EXIST = "LoadBalancer UUID does not exist.";
60     private static final String NO_PROVIDERS = "No providers registered.  Please try again later";
61     private static final String NO_PROVIDER_LIST = "Couldn't get providers list.  Please try again later";
62
63     private NeutronLoadBalancer extractFields(NeutronLoadBalancer o, List<String> fields) {
64         return o.extractFields(fields);
65     }
66
67     private NeutronCRUDInterfaces getNeutronInterfaces() {
68         NeutronCRUDInterfaces answer = new NeutronCRUDInterfaces().fetchINeutronLoadBalancerCRUD(this);
69         if (answer.getLoadBalancerInterface() == null) {
70             throw new ServiceUnavailableException(INTERFACE_NAME
71                 + RestMessages.SERVICEUNAVAILABLE.toString());
72         }
73         return answer;
74     }
75
76     /**
77      * Returns a list of all LoadBalancer */
78     @GET
79     @Produces({ MediaType.APPLICATION_JSON })
80     @StatusCodes({
81             @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
82             @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
83             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
84             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
85
86     public Response listGroups(
87             // return fields
88             @QueryParam("fields") List<String> fields,
89             // OpenStack LoadBalancer attributes
90             @QueryParam("id") String queryLoadBalancerID,
91             @QueryParam("tenant_id") String queryLoadBalancerTenantID,
92             @QueryParam("name") String queryLoadBalancerName,
93             @QueryParam("description") String queryLoadBalancerDescription,
94             @QueryParam("status") String queryLoadBalancerStatus,
95             @QueryParam("vip_address") String queryLoadBalancerVipAddress,
96             @QueryParam("vip_subnet") String queryLoadBalancerVipSubnet,
97             // pagination
98             @QueryParam("limit") String limit,
99             @QueryParam("marker") String marker,
100             @QueryParam("page_reverse") String pageReverse
101             // sorting not supported
102     ) {
103         INeutronLoadBalancerCRUD loadBalancerInterface = getNeutronInterfaces().getLoadBalancerInterface();
104         List<NeutronLoadBalancer> allLoadBalancers = loadBalancerInterface.getAllNeutronLoadBalancers();
105         List<NeutronLoadBalancer> ans = new ArrayList<NeutronLoadBalancer>();
106         Iterator<NeutronLoadBalancer> i = allLoadBalancers.iterator();
107         while (i.hasNext()) {
108             NeutronLoadBalancer nsg = i.next();
109             if ((queryLoadBalancerID == null ||
110                     queryLoadBalancerID.equals(nsg.getID())) &&
111                     (queryLoadBalancerTenantID == null ||
112                             queryLoadBalancerTenantID.equals(nsg.getLoadBalancerTenantID())) &&
113                     (queryLoadBalancerName == null ||
114                             queryLoadBalancerName.equals(nsg.getLoadBalancerName())) &&
115                     (queryLoadBalancerDescription == null ||
116                             queryLoadBalancerDescription.equals(nsg.getLoadBalancerDescription())) &&
117                     (queryLoadBalancerVipAddress == null ||
118                             queryLoadBalancerVipAddress.equals(nsg.getLoadBalancerVipAddress())) &&
119                     (queryLoadBalancerVipSubnet == null ||
120                             queryLoadBalancerVipSubnet.equals(nsg.getLoadBalancerVipSubnetID()))) {
121                 if (fields.size() > 0) {
122                     ans.add(extractFields(nsg,fields));
123                 } else {
124                     ans.add(nsg);
125                 }
126             }
127         }
128         return Response.status(HttpURLConnection.HTTP_OK).entity(
129                 new NeutronLoadBalancerRequest(ans)).build();
130     }
131
132     /**
133      * Returns a specific LoadBalancer */
134
135     @Path("{loadBalancerID}")
136     @GET
137     @Produces({ MediaType.APPLICATION_JSON })
138
139     @StatusCodes({
140             @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
141             @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
142             @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
143             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
144             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
145     public Response showLoadBalancer(@PathParam("loadBalancerID") String loadBalancerID,
146             // return fields
147             @QueryParam("fields") List<String> fields) {
148         INeutronLoadBalancerCRUD loadBalancerInterface = getNeutronInterfaces().getLoadBalancerInterface();
149         if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
150             throw new ResourceNotFoundException(UUID_NO_EXIST);
151         }
152         if (fields.size() > 0) {
153             NeutronLoadBalancer ans = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
154             return Response.status(HttpURLConnection.HTTP_OK).entity(
155                     new NeutronLoadBalancerRequest(extractFields(ans, fields))).build();
156         } else {
157             return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronLoadBalancerRequest(loadBalancerInterface.getNeutronLoadBalancer(
158                     loadBalancerID))).build();
159         }
160     }
161
162     /**
163      * Creates new LoadBalancer */
164
165     @POST
166     @Produces({ MediaType.APPLICATION_JSON })
167     @Consumes({ MediaType.APPLICATION_JSON })
168
169     @StatusCodes({
170             @ResponseCode(code = HttpURLConnection.HTTP_CREATED, condition = "Created"),
171             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
172     public Response createLoadBalancers(final NeutronLoadBalancerRequest input) {
173         INeutronLoadBalancerCRUD loadBalancerInterface = getNeutronInterfaces().getLoadBalancerInterface();
174         if (input.isSingleton()) {
175             NeutronLoadBalancer singleton = input.getSingleton();
176
177             Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerAware.class, this);
178             if (instances != null) {
179                 if (instances.length > 0) {
180                     for (Object instance : instances) {
181                         INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
182                         int status = service.canCreateNeutronLoadBalancer(singleton);
183                         if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
184                             return Response.status(status).build();
185                         }
186                     }
187                 } else {
188                     throw new ServiceUnavailableException(NO_PROVIDERS);
189                 }
190             } else {
191                 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
192             }
193
194             loadBalancerInterface.addNeutronLoadBalancer(singleton);
195             if (instances != null) {
196                 for (Object instance : instances) {
197                     INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
198                     service.neutronLoadBalancerCreated(singleton);
199                 }
200             }
201         } else {
202             Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerAware.class, this);
203             for (NeutronLoadBalancer test : input.getBulk()) {
204                 if (instances != null) {
205                     if (instances.length > 0) {
206                         for (Object instance : instances) {
207                             INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
208                             int status = service.canCreateNeutronLoadBalancer(test);
209                             if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
210                                 return Response.status(status).build();
211                             }
212                         }
213                     } else {
214                         throw new ServiceUnavailableException(NO_PROVIDERS);
215                     }
216                 } else {
217                     throw new ServiceUnavailableException(NO_PROVIDER_LIST);
218                 }
219             }
220             /*
221              * now, each element of the bulk request can be added to the cache
222              */
223             for (NeutronLoadBalancer test : input.getBulk()) {
224                 loadBalancerInterface.addNeutronLoadBalancer(test);
225                 if (instances != null) {
226                     for (Object instance : instances) {
227                         INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
228                         service.neutronLoadBalancerCreated(test);
229                     }
230                 }
231             }
232         }
233         return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build();
234     }
235
236     /**
237      * Updates a LoadBalancer Policy
238      */
239     @Path("{loadBalancerID}")
240     @PUT
241     @Produces({ MediaType.APPLICATION_JSON })
242     @Consumes({ MediaType.APPLICATION_JSON })
243
244     @StatusCodes({
245             @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
246             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
247     public Response updateLoadBalancer(
248             @PathParam("loadBalancerID") String loadBalancerID, final NeutronLoadBalancerRequest input) {
249         INeutronLoadBalancerCRUD loadBalancerInterface = getNeutronInterfaces().getLoadBalancerInterface();
250
251         NeutronLoadBalancer delta = input.getSingleton();
252         NeutronLoadBalancer original = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
253
254         Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerAware.class, this);
255         if (instances != null) {
256             if (instances.length > 0) {
257                 for (Object instance : instances) {
258                     INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
259                     int status = service.canUpdateNeutronLoadBalancer(delta, original);
260                     if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
261                         return Response.status(status).build();
262                     }
263                 }
264             } else {
265                 throw new ServiceUnavailableException(NO_PROVIDERS);
266             }
267         } else {
268             throw new ServiceUnavailableException(NO_PROVIDER_LIST);
269         }
270
271         /*
272          * update the object and return it
273          */
274         loadBalancerInterface.updateNeutronLoadBalancer(loadBalancerID, delta);
275         NeutronLoadBalancer updatedLoadBalancer = loadBalancerInterface.getNeutronLoadBalancer(
276                 loadBalancerID);
277         if (instances != null) {
278             for (Object instance : instances) {
279                 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
280                 service.neutronLoadBalancerUpdated(updatedLoadBalancer);
281             }
282         }
283         return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronLoadBalancerRequest(loadBalancerInterface.getNeutronLoadBalancer(
284                 loadBalancerID))).build();
285     }
286
287     /**
288      * Deletes a LoadBalancer */
289
290     @Path("{loadBalancerID}")
291     @DELETE
292     @StatusCodes({
293             @ResponseCode(code = HttpURLConnection.HTTP_NO_CONTENT, condition = "No Content"),
294             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
295     public Response deleteLoadBalancer(
296             @PathParam("loadBalancerID") String loadBalancerID) {
297         INeutronLoadBalancerCRUD loadBalancerInterface = getNeutronInterfaces().getLoadBalancerInterface();
298
299         NeutronLoadBalancer singleton = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
300         Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerAware.class, this);
301         if (instances != null) {
302             if (instances.length > 0) {
303                 for (Object instance : instances) {
304                     INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
305                     int status = service.canDeleteNeutronLoadBalancer(singleton);
306                     if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
307                         return Response.status(status).build();
308                     }
309                 }
310             } else {
311                 throw new ServiceUnavailableException(NO_PROVIDERS);
312             }
313         } else {
314             throw new ServiceUnavailableException(NO_PROVIDER_LIST);
315         }
316
317
318         loadBalancerInterface.removeNeutronLoadBalancer(loadBalancerID);
319         if (instances != null) {
320             for (Object instance : instances) {
321                 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
322                 service.neutronLoadBalancerDeleted(singleton);
323             }
324         }
325         return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build();
326     }
327 }