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 loadBalancerInterface.addNeutronLoadBalancer(singleton);
193 Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerAware.class, this, null);
194 if (instances != null) {
195 for (Object instance : instances) {
196 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
197 int status = service.canCreateNeutronLoadBalancer(singleton);
198 if (status < 200 || status > 299) {
199 return Response.status(status).build();
203 loadBalancerInterface.addNeutronLoadBalancer(singleton);
204 if (instances != null) {
205 for (Object instance : instances) {
206 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
207 service.neutronLoadBalancerCreated(singleton);
211 List<NeutronLoadBalancer> bulk = input.getBulk();
212 Iterator<NeutronLoadBalancer> i = bulk.iterator();
213 HashMap<String, NeutronLoadBalancer> testMap = new HashMap<String, NeutronLoadBalancer>();
214 Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerAware.class, this, null);
215 while (i.hasNext()) {
216 NeutronLoadBalancer test = i.next();
219 * Verify that the firewall policy doesn't already exist
222 if (loadBalancerInterface.neutronLoadBalancerExists(test.getLoadBalancerID())) {
223 throw new BadRequestException("Load Balancer Pool UUID already is already created");
225 if (testMap.containsKey(test.getLoadBalancerID())) {
226 throw new BadRequestException("Load Balancer Pool UUID already exists");
228 if (instances != null) {
229 for (Object instance : instances) {
230 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
231 int status = service.canCreateNeutronLoadBalancer(test);
232 if (status < 200 || status > 299) {
233 return Response.status(status).build();
239 * now, each element of the bulk request can be added to the cache
242 while (i.hasNext()) {
243 NeutronLoadBalancer test = i.next();
244 loadBalancerInterface.addNeutronLoadBalancer(test);
245 if (instances != null) {
246 for (Object instance : instances) {
247 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
248 service.neutronLoadBalancerCreated(test);
253 return Response.status(201).entity(input).build();
257 * Updates a LoadBalancer Policy
259 @Path("{loadBalancerID}")
261 @Produces({ MediaType.APPLICATION_JSON })
262 @Consumes({ MediaType.APPLICATION_JSON })
265 @ResponseCode(code = 200, condition = "Operation successful"),
266 @ResponseCode(code = 400, condition = "Bad Request"),
267 @ResponseCode(code = 401, condition = "Unauthorized"),
268 @ResponseCode(code = 403, condition = "Forbidden"),
269 @ResponseCode(code = 404, condition = "Not Found"),
270 @ResponseCode(code = 501, condition = "Not Implemented") })
271 public Response updateLoadBalancer(
272 @PathParam("loadBalancerID") String loadBalancerID, final NeutronLoadBalancerRequest input) {
273 INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
275 if (loadBalancerInterface == null) {
276 throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
277 + RestMessages.SERVICEUNAVAILABLE.toString());
281 * verify the LoadBalancer exists and there is only one delta provided
283 if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
284 throw new ResourceNotFoundException("LoadBalancer UUID does not exist.");
286 if (!input.isSingleton()) {
287 throw new BadRequestException("Only singleton edit supported");
289 NeutronLoadBalancer delta = input.getSingleton();
290 NeutronLoadBalancer original = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
293 * updates restricted by Neutron
295 if (delta.getLoadBalancerID() != null ||
296 delta.getLoadBalancerTenantID() != null ||
297 delta.getLoadBalancerName() != null ||
298 delta.getLoadBalancerDescription() != null ||
299 delta.getLoadBalancerStatus() != null ||
300 delta.getLoadBalancerVipAddress() != null ||
301 delta.getLoadBalancerVipSubnetID() != null) {
302 throw new BadRequestException("Attribute edit blocked by Neutron");
305 Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerAware.class, this, null);
306 if (instances != null) {
307 for (Object instance : instances) {
308 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
309 int status = service.canUpdateNeutronLoadBalancer(delta, original);
310 if (status < 200 || status > 299) {
311 return Response.status(status).build();
317 * update the object and return it
319 loadBalancerInterface.updateNeutronLoadBalancer(loadBalancerID, delta);
320 NeutronLoadBalancer updatedLoadBalancer = loadBalancerInterface.getNeutronLoadBalancer(
322 if (instances != null) {
323 for (Object instance : instances) {
324 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
325 service.neutronLoadBalancerUpdated(updatedLoadBalancer);
328 return Response.status(200).entity(new NeutronLoadBalancerRequest(loadBalancerInterface.getNeutronLoadBalancer(
329 loadBalancerID))).build();
333 * Deletes a LoadBalancer */
335 @Path("{loadBalancerID}")
338 @ResponseCode(code = 204, condition = "No Content"),
339 @ResponseCode(code = 401, condition = "Unauthorized"),
340 @ResponseCode(code = 404, condition = "Not Found"),
341 @ResponseCode(code = 409, condition = "Conflict"),
342 @ResponseCode(code = 501, condition = "Not Implemented") })
343 public Response deleteLoadBalancer(
344 @PathParam("loadBalancerID") String loadBalancerID) {
345 INeutronLoadBalancerCRUD loadBalancerInterface = NeutronCRUDInterfaces.getINeutronLoadBalancerCRUD(
347 if (loadBalancerInterface == null) {
348 throw new ServiceUnavailableException("LoadBalancer CRUD Interface "
349 + RestMessages.SERVICEUNAVAILABLE.toString());
353 * verify the LoadBalancer exists and it isn't currently in use
355 if (!loadBalancerInterface.neutronLoadBalancerExists(loadBalancerID)) {
356 throw new ResourceNotFoundException("LoadBalancer UUID does not exist.");
358 if (loadBalancerInterface.neutronLoadBalancerInUse(loadBalancerID)) {
359 return Response.status(409).build();
361 NeutronLoadBalancer singleton = loadBalancerInterface.getNeutronLoadBalancer(loadBalancerID);
362 Object[] instances = ServiceHelper.getGlobalInstances(INeutronLoadBalancerAware.class, this, null);
363 if (instances != null) {
364 for (Object instance : instances) {
365 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
366 int status = service.canDeleteNeutronLoadBalancer(singleton);
367 if (status < 200 || status > 299) {
368 return Response.status(status).build();
373 loadBalancerInterface.removeNeutronLoadBalancer(loadBalancerID);
374 if (instances != null) {
375 for (Object instance : instances) {
376 INeutronLoadBalancerAware service = (INeutronLoadBalancerAware) instance;
377 service.neutronLoadBalancerDeleted(singleton);
380 return Response.status(204).build();