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.controller.networkconfig.neutron.northbound;
12 import org.codehaus.enunciate.jaxrs.ResponseCode;
13 import org.codehaus.enunciate.jaxrs.StatusCodes;
14 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerAware;
15 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerCRUD;
16 import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
17 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancer;
18 import org.opendaylight.controller.northbound.commons.RestMessages;
19 import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
20 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
21 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
22 import org.opendaylight.controller.sal.utils.ServiceHelper;
24 import javax.ws.rs.Consumes;
25 import javax.ws.rs.DELETE;
26 import javax.ws.rs.GET;
27 import javax.ws.rs.POST;
28 import javax.ws.rs.PUT;
29 import javax.ws.rs.Path;
30 import javax.ws.rs.PathParam;
31 import javax.ws.rs.Produces;
32 import javax.ws.rs.QueryParam;
33 import javax.ws.rs.core.MediaType;
34 import javax.ws.rs.core.Response;
35 import java.util.ArrayList;
36 import java.util.HashMap;
37 import java.util.Iterator;
38 import java.util.List;
41 * Neutron Northbound REST APIs for LoadBalancers.<br>
42 * This class provides REST APIs for managing neutron LoadBalancers
46 * Authentication scheme : <b>HTTP Basic</b><br>
47 * Authentication realm : <b>opendaylight</b><br>
48 * Transport : <b>HTTP and HTTPS</b><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>
54 * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
57 @Path("/loadbalancers")
58 public class NeutronLoadBalancerNorthbound {
60 private NeutronLoadBalancer extractFields(NeutronLoadBalancer o, List<String> fields) {
61 return o.extractFields(fields);
65 * Returns a list of all LoadBalancer */
67 @Produces({ MediaType.APPLICATION_JSON })
69 @ResponseCode(code = 200, condition = "Operation successful"),
70 @ResponseCode(code = 401, condition = "Unauthorized"),
71 @ResponseCode(code = 501, condition = "Not Implemented") })
73 public Response listGroups(
75 @QueryParam("fields") List<String> fields,
76 // OpenStack LoadBalancer attributes
77 @QueryParam("id") String queryLoadBalancerID,
78 @QueryParam("tenant_id") String queryLoadBalancerTenantID,
79 @QueryParam("name") String queryLoadBalancerName,
80 @QueryParam("description") String queryLoadBalancerDescription,
81 @QueryParam("status") String queryLoadBalancerStatus,
82 @QueryParam("vip_address") String queryLoadBalancerVipAddress,
83 @QueryParam("vip_subnet") String queryLoadBalancerVipSubnet,
85 @QueryParam("limit") String limit,
86 @QueryParam("marker") String marker,
87 @QueryParam("page_reverse") String pageReverse
88 // sorting not supported
90 INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(this);
92 if (loadBalancerInterface == null) {
93 throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
94 + RestMessages.SERVICEUNAVAILABLE.toString());
96 List<NeutronLoadBalancer> allLoadBalancers = loadBalancerInterface.getAllNeutronLoadBalancers();
97 // List<NeutronLoadBalancerRule> allLoadBalancerRules = firewallRuleInterface.getAllNeutronLoadBalancerRules();
98 List<NeutronLoadBalancer> ans = new ArrayList<NeutronLoadBalancer>();
99 // List<NeutronLoadBalancerRule> rules = new ArrayList<NeutronLoadBalancerRule>();
100 Iterator<NeutronLoadBalancer> i = allLoadBalancers.iterator();
101 while (i.hasNext()) {
102 NeutronLoadBalancer nsg = i.next();
103 if ((queryLoadBalancerID == null ||
104 queryLoadBalancerID.equals(nsg.getLoadBalancerID())) &&
105 (queryLoadBalancerTenantID == null ||
106 queryLoadBalancerTenantID.equals(nsg.getLoadBalancerTenantID())) &&
107 (queryLoadBalancerName == null ||
108 queryLoadBalancerName.equals(nsg.getLoadBalancerName())) &&
109 (queryLoadBalancerDescription == null ||
110 queryLoadBalancerDescription.equals(nsg.getLoadBalancerDescription())) &&
111 (queryLoadBalancerVipAddress == null ||
112 queryLoadBalancerVipAddress.equals(nsg.getLoadBalancerVipAddress())) &&
113 (queryLoadBalancerVipSubnet == null ||
114 queryLoadBalancerVipSubnet.equals(nsg.getLoadBalancerVipSubnetID()))) {
115 if (fields.size() > 0) {
116 ans.add(extractFields(nsg,fields));
122 return Response.status(200).entity(
123 new NeutronLoadBalancerRequest(ans)).build();
127 * Returns a specific LoadBalancer */
129 @Path("{loadBalancerID}")
131 @Produces({ MediaType.APPLICATION_JSON })
134 @ResponseCode(code = 200, condition = "Operation successful"),
135 @ResponseCode(code = 401, condition = "Unauthorized"),
136 @ResponseCode(code = 404, condition = "Not Found"),
137 @ResponseCode(code = 501, condition = "Not Implemented") })
138 public Response showLoadBalancer(@PathParam("loadBalancerID") String loadBalancerID,
140 @QueryParam("fields") List<String> fields) {
141 INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
143 if (loadBalancerInterface == null) {
144 throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
145 + RestMessages.SERVICEUNAVAILABLE.toString());
147 if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
148 throw new ResourceNotFoundException("LoadBalancer UUID does not exist.");
150 if (fields.size() > 0) {
151 NeutronLoadBalancer ans = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
152 return Response.status(200).entity(
153 new NeutronLoadBalancerRequest(extractFields(ans, fields))).build();
155 return Response.status(200).entity(new NeutronLoadBalancerRequest(loadBalancerInterface.getNeutronLoadBalancer(
156 loadBalancerID))).build();
161 * Creates new LoadBalancer */
164 @Produces({ MediaType.APPLICATION_JSON })
165 @Consumes({ MediaType.APPLICATION_JSON })
168 @ResponseCode(code = 201, condition = "Created"),
169 @ResponseCode(code = 400, condition = "Bad Request"),
170 @ResponseCode(code = 401, condition = "Unauthorized"),
171 @ResponseCode(code = 403, condition = "Forbidden"),
172 @ResponseCode(code = 404, condition = "Not Found"),
173 @ResponseCode(code = 409, condition = "Conflict"),
174 @ResponseCode(code = 501, condition = "Not Implemented") })
175 public Response createLoadBalancers(final NeutronLoadBalancerRequest input) {
176 INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
178 if (loadBalancerInterface == null) {
179 throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
180 + RestMessages.SERVICEUNAVAILABLE.toString());
182 if (input.isSingleton()) {
183 NeutronLoadBalancer singleton = input.getSingleton();
186 * Verify that the LoadBalancer doesn't already exist.
188 if (loadBalancerInterface.neutronLoadBalancerExists(singleton.getLoadBalancerID())) {
189 throw new BadRequestException("LoadBalancer UUID already exists");
191 Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerAware.class, this, null);
192 if (instances != null) {
193 for (Object instance : instances) {
194 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
195 int status = service.canCreateNeutronLoadBalancer(singleton);
196 if (status < 200 || status > 299) {
197 return Response.status(status).build();
201 loadBalancerInterface.addNeutronLoadBalancer(singleton);
202 if (instances != null) {
203 for (Object instance : instances) {
204 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
205 service.neutronLoadBalancerCreated(singleton);
209 List<NeutronLoadBalancer> bulk = input.getBulk();
210 Iterator<NeutronLoadBalancer> i = bulk.iterator();
211 HashMap<String, NeutronLoadBalancer> testMap = new HashMap<String, NeutronLoadBalancer>();
212 Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerAware.class, this, null);
213 while (i.hasNext()) {
214 NeutronLoadBalancer test = i.next();
217 * Verify that the loadbalancer doesn't already exist
220 if (loadBalancerInterface.neutronLoadBalancerExists(test.getLoadBalancerID())) {
221 throw new BadRequestException("Load Balancer Pool UUID already is already created");
223 if (testMap.containsKey(test.getLoadBalancerID())) {
224 throw new BadRequestException("Load Balancer Pool UUID already exists");
226 if (instances != null) {
227 for (Object instance : instances) {
228 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
229 int status = service.canCreateNeutronLoadBalancer(test);
230 if (status < 200 || status > 299) {
231 return Response.status(status).build();
237 * now, each element of the bulk request can be added to the cache
240 while (i.hasNext()) {
241 NeutronLoadBalancer test = i.next();
242 loadBalancerInterface.addNeutronLoadBalancer(test);
243 if (instances != null) {
244 for (Object instance : instances) {
245 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
246 service.neutronLoadBalancerCreated(test);
251 return Response.status(201).entity(input).build();
255 * Updates a LoadBalancer Policy
257 @Path("{loadBalancerID}")
259 @Produces({ MediaType.APPLICATION_JSON })
260 @Consumes({ MediaType.APPLICATION_JSON })
263 @ResponseCode(code = 200, condition = "Operation successful"),
264 @ResponseCode(code = 400, condition = "Bad Request"),
265 @ResponseCode(code = 401, condition = "Unauthorized"),
266 @ResponseCode(code = 403, condition = "Forbidden"),
267 @ResponseCode(code = 404, condition = "Not Found"),
268 @ResponseCode(code = 501, condition = "Not Implemented") })
269 public Response updateLoadBalancer(
270 @PathParam("loadBalancerID") String loadBalancerID, final NeutronLoadBalancerRequest input) {
271 INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
273 if (loadBalancerInterface == null) {
274 throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
275 + RestMessages.SERVICEUNAVAILABLE.toString());
279 * verify the LoadBalancer exists and there is only one delta provided
281 if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
282 throw new ResourceNotFoundException("LoadBalancer UUID does not exist.");
284 if (!input.isSingleton()) {
285 throw new BadRequestException("Only singleton edit supported");
287 NeutronLoadBalancer delta = input.getSingleton();
288 NeutronLoadBalancer original = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
291 * updates restricted by Neutron
293 if (delta.getLoadBalancerID() != null ||
294 delta.getLoadBalancerTenantID() != null ||
295 delta.getLoadBalancerName() != null ||
296 delta.getLoadBalancerDescription() != null ||
297 delta.getLoadBalancerStatus() != null ||
298 delta.getLoadBalancerVipAddress() != null ||
299 delta.getLoadBalancerVipSubnetID() != null) {
300 throw new BadRequestException("Attribute edit blocked by Neutron");
303 Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerAware.class, this, null);
304 if (instances != null) {
305 for (Object instance : instances) {
306 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
307 int status = service.canUpdateNeutronLoadBalancer(delta, original);
308 if (status < 200 || status > 299) {
309 return Response.status(status).build();
315 * update the object and return it
317 loadBalancerInterface.updateNeutronLoadBalancer(loadBalancerID, delta);
318 NeutronLoadBalancer updatedLoadBalancer = loadBalancerInterface.getNeutronLoadBalancer(
320 if (instances != null) {
321 for (Object instance : instances) {
322 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
323 service.neutronLoadBalancerUpdated(updatedLoadBalancer);
326 return Response.status(200).entity(new NeutronLoadBalancerRequest(loadBalancerInterface.getNeutronLoadBalancer(
327 loadBalancerID))).build();
331 * Deletes a LoadBalancer */
333 @Path("{loadBalancerID}")
336 @ResponseCode(code = 204, condition = "No Content"),
337 @ResponseCode(code = 401, condition = "Unauthorized"),
338 @ResponseCode(code = 404, condition = "Not Found"),
339 @ResponseCode(code = 409, condition = "Conflict"),
340 @ResponseCode(code = 501, condition = "Not Implemented") })
341 public Response deleteLoadBalancer(
342 @PathParam("loadBalancerID") String loadBalancerID) {
343 INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
345 if (loadBalancerInterface == null) {
346 throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
347 + RestMessages.SERVICEUNAVAILABLE.toString());
351 * verify the LoadBalancer exists and it isn't currently in use
353 if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
354 throw new ResourceNotFoundException("LoadBalancer UUID does not exist.");
356 if (loadBalancerInterface.neutronLoadBalancerInUse(loadBalancerID)) {
357 return Response.status(409).build();
359 NeutronLoadBalancer singleton = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
360 Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerAware.class, this, null);
361 if (instances != null) {
362 for (Object instance : instances) {
363 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
364 int status = service.canDeleteNeutronLoadBalancer(singleton);
365 if (status < 200 || status > 299) {
366 return Response.status(status).build();
371 loadBalancerInterface.removeNeutronLoadBalancer(loadBalancerID);
372 if (instances != null) {
373 for (Object instance : instances) {
374 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
375 service.neutronLoadBalancerDeleted(singleton);
378 return Response.status(204).build();