2 * Copyright (C) 2014 Red Hat, Inc.
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
9 package org.opendaylight.neutron.northbound.api;
11 import java.net.HttpURLConnection;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.List;
18 import javax.ws.rs.Consumes;
19 import javax.ws.rs.DELETE;
20 import javax.ws.rs.GET;
21 import javax.ws.rs.POST;
22 import javax.ws.rs.PUT;
23 import javax.ws.rs.Path;
24 import javax.ws.rs.PathParam;
25 import javax.ws.rs.Produces;
26 import javax.ws.rs.QueryParam;
27 import javax.ws.rs.core.MediaType;
28 import javax.ws.rs.core.Response;
30 import org.codehaus.enunciate.jaxrs.ResponseCode;
31 import org.codehaus.enunciate.jaxrs.StatusCodes;
32 import org.opendaylight.neutron.spi.INeutronLoadBalancerAware;
33 import org.opendaylight.neutron.spi.INeutronLoadBalancerCRUD;
34 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
35 import org.opendaylight.neutron.spi.NeutronLoadBalancer;
38 * Neutron Northbound REST APIs for LoadBalancers.<br>
39 * This class provides REST APIs for managing neutron LoadBalancers
43 * Authentication scheme : <b>HTTP Basic</b><br>
44 * Authentication realm : <b>opendaylight</b><br>
45 * Transport : <b>HTTP and HTTPS</b><br>
47 * HTTPS Authentication is disabled by default. Administrator can enable it in
48 * tomcat-server.xml after adding a proper keystore / SSL certificate from a
49 * trusted authority.<br>
51 * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
54 @Path("/lbaas/loadbalancers")
55 public class NeutronLoadBalancerNorthbound {
57 private static final int HTTP_OK_BOTTOM = 200;
58 private static final int HTTP_OK_TOP = 299;
59 private static final String INTERFACE_NAME = "LoadBalancer CRUD Interface";
60 private static final String UUID_NO_EXIST = "LoadBalancer UUID does not exist.";
61 private static final String NO_PROVIDERS = "No providers registered. Please try again later";
62 private static final String NO_PROVIDER_LIST = "Couldn't get providers list. Please try again later";
64 private NeutronLoadBalancer extractFields(NeutronLoadBalancer o, List<String> fields) {
65 return o.extractFields(fields);
68 private NeutronCRUDInterfaces getNeutronInterfaces() {
69 NeutronCRUDInterfaces answer = new NeutronCRUDInterfaces().fetchINeutronLoadBalancerCRUD(this);
70 if (answer.getLoadBalancerInterface() == null) {
71 throw new ServiceUnavailableException(INTERFACE_NAME
72 + RestMessages.SERVICEUNAVAILABLE.toString());
78 * Returns a list of all LoadBalancer */
80 @Produces({ MediaType.APPLICATION_JSON })
82 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
83 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
84 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
85 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
87 public Response listGroups(
89 @QueryParam("fields") List<String> fields,
90 // OpenStack LoadBalancer attributes
91 @QueryParam("id") String queryLoadBalancerID,
92 @QueryParam("tenant_id") String queryLoadBalancerTenantID,
93 @QueryParam("name") String queryLoadBalancerName,
94 @QueryParam("description") String queryLoadBalancerDescription,
95 @QueryParam("status") String queryLoadBalancerStatus,
96 @QueryParam("vip_address") String queryLoadBalancerVipAddress,
97 @QueryParam("vip_subnet") String queryLoadBalancerVipSubnet,
99 @QueryParam("limit") String limit,
100 @QueryParam("marker") String marker,
101 @QueryParam("page_reverse") String pageReverse
102 // sorting not supported
104 INeutronLoadBalancerCRUD loadBalancerInterface = getNeutronInterfaces().getLoadBalancerInterface();
105 List<NeutronLoadBalancer> allLoadBalancers = loadBalancerInterface.getAllNeutronLoadBalancers();
106 List<NeutronLoadBalancer> ans = new ArrayList<NeutronLoadBalancer>();
107 Iterator<NeutronLoadBalancer> i = allLoadBalancers.iterator();
108 while (i.hasNext()) {
109 NeutronLoadBalancer nsg = i.next();
110 if ((queryLoadBalancerID == null ||
111 queryLoadBalancerID.equals(nsg.getLoadBalancerID())) &&
112 (queryLoadBalancerTenantID == null ||
113 queryLoadBalancerTenantID.equals(nsg.getLoadBalancerTenantID())) &&
114 (queryLoadBalancerName == null ||
115 queryLoadBalancerName.equals(nsg.getLoadBalancerName())) &&
116 (queryLoadBalancerDescription == null ||
117 queryLoadBalancerDescription.equals(nsg.getLoadBalancerDescription())) &&
118 (queryLoadBalancerVipAddress == null ||
119 queryLoadBalancerVipAddress.equals(nsg.getLoadBalancerVipAddress())) &&
120 (queryLoadBalancerVipSubnet == null ||
121 queryLoadBalancerVipSubnet.equals(nsg.getLoadBalancerVipSubnetID()))) {
122 if (fields.size() > 0) {
123 ans.add(extractFields(nsg,fields));
129 return Response.status(HttpURLConnection.HTTP_OK).entity(
130 new NeutronLoadBalancerRequest(ans)).build();
134 * Returns a specific LoadBalancer */
136 @Path("{loadBalancerID}")
138 @Produces({ MediaType.APPLICATION_JSON })
141 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
142 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
143 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
144 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
145 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
146 public Response showLoadBalancer(@PathParam("loadBalancerID") String loadBalancerID,
148 @QueryParam("fields") List<String> fields) {
149 INeutronLoadBalancerCRUD loadBalancerInterface = getNeutronInterfaces().getLoadBalancerInterface();
150 if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
151 throw new ResourceNotFoundException(UUID_NO_EXIST);
153 if (fields.size() > 0) {
154 NeutronLoadBalancer ans = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
155 return Response.status(HttpURLConnection.HTTP_OK).entity(
156 new NeutronLoadBalancerRequest(extractFields(ans, fields))).build();
158 return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronLoadBalancerRequest(loadBalancerInterface.getNeutronLoadBalancer(
159 loadBalancerID))).build();
164 * Creates new LoadBalancer */
167 @Produces({ MediaType.APPLICATION_JSON })
168 @Consumes({ MediaType.APPLICATION_JSON })
171 @ResponseCode(code = HttpURLConnection.HTTP_CREATED, condition = "Created"),
172 @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
173 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
174 @ResponseCode(code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
175 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
176 @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
177 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
178 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
179 public Response createLoadBalancers(final NeutronLoadBalancerRequest input) {
180 INeutronLoadBalancerCRUD loadBalancerInterface = getNeutronInterfaces().getLoadBalancerInterface();
181 if (input.isSingleton()) {
182 NeutronLoadBalancer singleton = input.getSingleton();
185 * Verify that the LoadBalancer doesn't already exist.
187 if (loadBalancerInterface.neutronLoadBalancerExists(singleton.getLoadBalancerID())) {
188 throw new BadRequestException("LoadBalancer UUID already exists");
190 Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerAware.class, this);
191 if (instances != null) {
192 if (instances.length > 0) {
193 for (Object instance : instances) {
194 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
195 int status = service.canCreateNeutronLoadBalancer(singleton);
196 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
197 return Response.status(status).build();
201 throw new ServiceUnavailableException(NO_PROVIDERS);
204 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
207 loadBalancerInterface.addNeutronLoadBalancer(singleton);
208 if (instances != null) {
209 for (Object instance : instances) {
210 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
211 service.neutronLoadBalancerCreated(singleton);
215 List<NeutronLoadBalancer> bulk = input.getBulk();
216 Iterator<NeutronLoadBalancer> i = bulk.iterator();
217 HashMap<String, NeutronLoadBalancer> testMap = new HashMap<String, NeutronLoadBalancer>();
218 Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerAware.class, this);
219 while (i.hasNext()) {
220 NeutronLoadBalancer test = i.next();
223 * Verify that the loadbalancer doesn't already exist
226 if (loadBalancerInterface.neutronLoadBalancerExists(test.getLoadBalancerID())) {
227 throw new BadRequestException("Load Balancer Pool UUID already is already created");
229 if (testMap.containsKey(test.getLoadBalancerID())) {
230 throw new BadRequestException("Load Balancer Pool UUID already exists");
232 if (instances != null) {
233 if (instances.length > 0) {
234 for (Object instance : instances) {
235 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
236 int status = service.canCreateNeutronLoadBalancer(test);
237 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
238 return Response.status(status).build();
242 throw new ServiceUnavailableException(NO_PROVIDERS);
245 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
249 * now, each element of the bulk request can be added to the cache
252 while (i.hasNext()) {
253 NeutronLoadBalancer test = i.next();
254 loadBalancerInterface.addNeutronLoadBalancer(test);
255 if (instances != null) {
256 for (Object instance : instances) {
257 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
258 service.neutronLoadBalancerCreated(test);
263 return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build();
267 * Updates a LoadBalancer Policy
269 @Path("{loadBalancerID}")
271 @Produces({ MediaType.APPLICATION_JSON })
272 @Consumes({ MediaType.APPLICATION_JSON })
275 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
276 @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
277 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
278 @ResponseCode(code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
279 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
280 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
281 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
282 public Response updateLoadBalancer(
283 @PathParam("loadBalancerID") String loadBalancerID, final NeutronLoadBalancerRequest input) {
284 INeutronLoadBalancerCRUD loadBalancerInterface = getNeutronInterfaces().getLoadBalancerInterface();
287 * verify the LoadBalancer exists and there is only one delta provided
289 if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
290 throw new ResourceNotFoundException(UUID_NO_EXIST);
292 if (!input.isSingleton()) {
293 throw new BadRequestException("Only singleton edit supported");
295 NeutronLoadBalancer delta = input.getSingleton();
296 NeutronLoadBalancer original = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
299 * updates restricted by Neutron
301 if (delta.getLoadBalancerID() != null ||
302 delta.getLoadBalancerTenantID() != null ||
303 delta.getLoadBalancerName() != null ||
304 delta.getLoadBalancerDescription() != null ||
305 delta.getLoadBalancerStatus() != null ||
306 delta.getLoadBalancerVipAddress() != null ||
307 delta.getLoadBalancerVipSubnetID() != null) {
308 throw new BadRequestException("Attribute edit blocked by Neutron");
311 Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerAware.class, this);
312 if (instances != null) {
313 if (instances.length > 0) {
314 for (Object instance : instances) {
315 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
316 int status = service.canUpdateNeutronLoadBalancer(delta, original);
317 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
318 return Response.status(status).build();
322 throw new ServiceUnavailableException(NO_PROVIDERS);
325 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
329 * update the object and return it
331 loadBalancerInterface.updateNeutronLoadBalancer(loadBalancerID, delta);
332 NeutronLoadBalancer updatedLoadBalancer = loadBalancerInterface.getNeutronLoadBalancer(
334 if (instances != null) {
335 for (Object instance : instances) {
336 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
337 service.neutronLoadBalancerUpdated(updatedLoadBalancer);
340 return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronLoadBalancerRequest(loadBalancerInterface.getNeutronLoadBalancer(
341 loadBalancerID))).build();
345 * Deletes a LoadBalancer */
347 @Path("{loadBalancerID}")
350 @ResponseCode(code = HttpURLConnection.HTTP_NO_CONTENT, condition = "No Content"),
351 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
352 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
353 @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
354 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
355 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
356 public Response deleteLoadBalancer(
357 @PathParam("loadBalancerID") String loadBalancerID) {
358 INeutronLoadBalancerCRUD loadBalancerInterface = getNeutronInterfaces().getLoadBalancerInterface();
361 * verify the LoadBalancer exists and it isn't currently in use
363 if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
364 throw new ResourceNotFoundException(UUID_NO_EXIST);
366 if (loadBalancerInterface.neutronLoadBalancerInUse(loadBalancerID)) {
367 return Response.status(HttpURLConnection.HTTP_CONFLICT).build();
369 NeutronLoadBalancer singleton = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
370 Object[] instances = NeutronUtil.getInstances(INeutronLoadBalancerAware.class, this);
371 if (instances != null) {
372 if (instances.length > 0) {
373 for (Object instance : instances) {
374 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
375 int status = service.canDeleteNeutronLoadBalancer(singleton);
376 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
377 return Response.status(status).build();
381 throw new ServiceUnavailableException(NO_PROVIDERS);
384 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
388 loadBalancerInterface.removeNeutronLoadBalancer(loadBalancerID);
389 if (instances != null) {
390 for (Object instance : instances) {
391 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
392 service.neutronLoadBalancerDeleted(singleton);
395 return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build();