2 * Copyright IBM Corporation, 2013. All rights reserved.
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.util.ArrayList;
12 import java.util.Iterator;
13 import java.util.List;
15 import javax.ws.rs.Consumes;
16 import javax.ws.rs.DELETE;
17 import javax.ws.rs.GET;
18 import javax.ws.rs.POST;
19 import javax.ws.rs.PUT;
20 import javax.ws.rs.Path;
21 import javax.ws.rs.PathParam;
22 import javax.ws.rs.Produces;
23 import javax.ws.rs.QueryParam;
24 import javax.ws.rs.core.MediaType;
25 import javax.ws.rs.core.Response;
27 import org.codehaus.enunciate.jaxrs.ResponseCode;
28 import org.codehaus.enunciate.jaxrs.StatusCodes;
29 import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
30 import org.opendaylight.neutron.spi.INeutronPortCRUD;
31 import org.opendaylight.neutron.spi.INeutronRouterAware;
32 import org.opendaylight.neutron.spi.INeutronRouterCRUD;
33 import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
34 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
35 import org.opendaylight.neutron.spi.NeutronNetwork;
36 import org.opendaylight.neutron.spi.NeutronPort;
37 import org.opendaylight.neutron.spi.NeutronRouter;
38 import org.opendaylight.neutron.spi.NeutronRouter_Interface;
39 import org.opendaylight.neutron.spi.NeutronSubnet;
43 * Neutron Northbound REST APIs.<br>
44 * This class provides REST APIs for managing neutron routers
48 * Authentication scheme : <b>HTTP Basic</b><br>
49 * Authentication realm : <b>opendaylight</b><br>
50 * Transport : <b>HTTP and HTTPS</b><br>
52 * HTTPS Authentication is disabled by default. Administrator can enable it in
53 * tomcat-server.xml after adding a proper keystore / SSL certificate from a
54 * trusted authority.<br>
56 * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
61 public class NeutronRoutersNorthbound {
63 private NeutronRouter extractFields(NeutronRouter o, List<String> fields) {
64 return o.extractFields(fields);
68 * Returns a list of all Routers */
71 @Produces({ MediaType.APPLICATION_JSON })
72 //@TypeHint(OpenStackRouters.class)
74 @ResponseCode(code = 200, condition = "Operation successful"),
75 @ResponseCode(code = 401, condition = "Unauthorized"),
76 @ResponseCode(code = 501, condition = "Not Implemented"),
77 @ResponseCode(code = 503, condition = "No providers available") })
78 public Response listRouters(
80 @QueryParam("fields") List<String> fields,
81 // note: openstack isn't clear about filtering on lists, so we aren't handling them
82 @QueryParam("id") String queryID,
83 @QueryParam("name") String queryName,
84 @QueryParam("admin_state_up") String queryAdminStateUp,
85 @QueryParam("status") String queryStatus,
86 @QueryParam("tenant_id") String queryTenantID,
87 @QueryParam("external_gateway_info") String queryExternalGatewayInfo,
89 @QueryParam("limit") String limit,
90 @QueryParam("marker") String marker,
91 @QueryParam("page_reverse") String pageReverse
92 // sorting not supported
94 INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
95 if (routerInterface == null) {
96 throw new ServiceUnavailableException("Router CRUD Interface "
97 + RestMessages.SERVICEUNAVAILABLE.toString());
99 List<NeutronRouter> allRouters = routerInterface.getAllRouters();
100 List<NeutronRouter> ans = new ArrayList<NeutronRouter>();
101 Iterator<NeutronRouter> i = allRouters.iterator();
102 while (i.hasNext()) {
103 NeutronRouter oSS = i.next();
104 if ((queryID == null || queryID.equals(oSS.getID())) &&
105 (queryName == null || queryName.equals(oSS.getName())) &&
106 (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&
107 (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&
108 (queryExternalGatewayInfo == null || queryExternalGatewayInfo.equals(oSS.getExternalGatewayInfo())) &&
109 (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {
110 if (fields.size() > 0)
111 ans.add(extractFields(oSS,fields));
116 //TODO: apply pagination to results
117 return Response.status(200).entity(
118 new NeutronRouterRequest(ans)).build();
122 * Returns a specific Router */
124 @Path("{routerUUID}")
126 @Produces({ MediaType.APPLICATION_JSON })
127 //@TypeHint(OpenStackRouters.class)
129 @ResponseCode(code = 200, condition = "Operation successful"),
130 @ResponseCode(code = 401, condition = "Unauthorized"),
131 @ResponseCode(code = 403, condition = "Forbidden"),
132 @ResponseCode(code = 404, condition = "Not Found"),
133 @ResponseCode(code = 501, condition = "Not Implemented"),
134 @ResponseCode(code = 503, condition = "No providers available") })
135 public Response showRouter(
136 @PathParam("routerUUID") String routerUUID,
138 @QueryParam("fields") List<String> fields) {
139 INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
140 if (routerInterface == null) {
141 throw new ServiceUnavailableException("Router CRUD Interface "
142 + RestMessages.SERVICEUNAVAILABLE.toString());
144 if (!routerInterface.routerExists(routerUUID)) {
145 throw new ResourceNotFoundException("Router UUID not found");
147 if (fields.size() > 0) {
148 NeutronRouter ans = routerInterface.getRouter(routerUUID);
149 return Response.status(200).entity(
150 new NeutronRouterRequest(extractFields(ans, fields))).build();
152 return Response.status(200).entity(
153 new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();
157 * Creates new Routers */
160 @Produces({ MediaType.APPLICATION_JSON })
161 @Consumes({ MediaType.APPLICATION_JSON })
162 //@TypeHint(OpenStackRouters.class)
164 @ResponseCode(code = 201, condition = "Created"),
165 @ResponseCode(code = 400, condition = "Bad Request"),
166 @ResponseCode(code = 401, condition = "Unauthorized"),
167 @ResponseCode(code = 501, condition = "Not Implemented"),
168 @ResponseCode(code = 503, condition = "No providers available") })
169 public Response createRouters(final NeutronRouterRequest input) {
170 INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
171 if (routerInterface == null) {
172 throw new ServiceUnavailableException("Router CRUD Interface "
173 + RestMessages.SERVICEUNAVAILABLE.toString());
175 INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
176 if (networkInterface == null) {
177 throw new ServiceUnavailableException("Network CRUD Interface "
178 + RestMessages.SERVICEUNAVAILABLE.toString());
180 if (input.isSingleton()) {
181 NeutronRouter singleton = input.getSingleton();
184 * verify that the router doesn't already exist (issue: is deeper inspection necessary?)
185 * if there is external gateway information provided, verify that the specified network
186 * exists and has been designated as "router:external"
188 if (routerInterface.routerExists(singleton.getID()))
189 throw new BadRequestException("router UUID already exists");
190 if (singleton.getExternalGatewayInfo() != null) {
191 String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();
192 if (!networkInterface.networkExists(externNetworkPtr))
193 throw new BadRequestException("External Network Pointer doesn't exist");
194 NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);
195 if (!externNetwork.isRouterExternal())
196 throw new BadRequestException("External Network Pointer isn't marked as router:external");
198 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
199 if (instances != null) {
200 if (instances.length > 0) {
201 for (Object instance : instances) {
202 INeutronRouterAware service = (INeutronRouterAware) instance;
203 int status = service.canCreateRouter(singleton);
204 if (status < 200 || status > 299)
205 return Response.status(status).build();
208 throw new ServiceUnavailableException("No providers registered. Please try again later");
211 throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
215 * add router to the cache
217 routerInterface.addRouter(singleton);
218 if (instances != null) {
219 for (Object instance : instances) {
220 INeutronRouterAware service = (INeutronRouterAware) instance;
221 service.neutronRouterCreated(singleton);
227 * only singleton router creates supported
229 throw new BadRequestException("Only singleton router creates supported");
231 return Response.status(201).entity(input).build();
235 * Updates a Router */
237 @Path("{routerUUID}")
239 @Produces({ MediaType.APPLICATION_JSON })
240 @Consumes({ MediaType.APPLICATION_JSON })
241 //@TypeHint(OpenStackRouters.class)
243 @ResponseCode(code = 200, condition = "Operation successful"),
244 @ResponseCode(code = 400, condition = "Bad Request"),
245 @ResponseCode(code = 401, condition = "Unauthorized"),
246 @ResponseCode(code = 404, condition = "Not Found"),
247 @ResponseCode(code = 501, condition = "Not Implemented"),
248 @ResponseCode(code = 503, condition = "No providers available") })
249 public Response updateRouter(
250 @PathParam("routerUUID") String routerUUID,
251 NeutronRouterRequest input
253 INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
254 if (routerInterface == null) {
255 throw new ServiceUnavailableException("Router CRUD Interface "
256 + RestMessages.SERVICEUNAVAILABLE.toString());
258 INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
259 if (networkInterface == null) {
260 throw new ServiceUnavailableException("Network CRUD Interface "
261 + RestMessages.SERVICEUNAVAILABLE.toString());
265 * router has to exist and only a single delta can be supplied
267 if (!routerInterface.routerExists(routerUUID))
268 throw new ResourceNotFoundException("Router UUID not found");
269 if (!input.isSingleton())
270 throw new BadRequestException("Only single router deltas supported");
271 NeutronRouter singleton = input.getSingleton();
272 NeutronRouter original = routerInterface.getRouter(routerUUID);
275 * attribute changes blocked by Neutron
277 if (singleton.getID() != null || singleton.getTenantID() != null ||
278 singleton.getStatus() != null)
279 throw new BadRequestException("Request attribute change not allowed");
281 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
282 if (instances != null) {
283 if (instances.length > 0) {
284 for (Object instance : instances) {
285 INeutronRouterAware service = (INeutronRouterAware) instance;
286 int status = service.canUpdateRouter(singleton, original);
287 if (status < 200 || status > 299)
288 return Response.status(status).build();
291 throw new ServiceUnavailableException("No providers registered. Please try again later");
294 throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
297 * if the external gateway info is being changed, verify that the new network
298 * exists and has been designated as an external network
300 if (singleton.getExternalGatewayInfo() != null) {
301 String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();
302 if (!networkInterface.networkExists(externNetworkPtr))
303 throw new BadRequestException("External Network Pointer does not exist");
304 NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);
305 if (!externNetwork.isRouterExternal())
306 throw new BadRequestException("External Network Pointer isn't marked as router:external");
310 * update the router entry and return the modified object
312 routerInterface.updateRouter(routerUUID, singleton);
313 NeutronRouter updatedRouter = routerInterface.getRouter(routerUUID);
314 if (instances != null) {
315 for (Object instance : instances) {
316 INeutronRouterAware service = (INeutronRouterAware) instance;
317 service.neutronRouterUpdated(updatedRouter);
320 return Response.status(200).entity(
321 new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();
326 * Deletes a Router */
328 @Path("{routerUUID}")
331 @ResponseCode(code = 204, condition = "No Content"),
332 @ResponseCode(code = 401, condition = "Unauthorized"),
333 @ResponseCode(code = 404, condition = "Not Found"),
334 @ResponseCode(code = 409, condition = "Conflict"),
335 @ResponseCode(code = 501, condition = "Not Implemented"),
336 @ResponseCode(code = 503, condition = "No providers available") })
337 public Response deleteRouter(
338 @PathParam("routerUUID") String routerUUID) {
339 INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
340 if (routerInterface == null) {
341 throw new ServiceUnavailableException("Router CRUD Interface "
342 + RestMessages.SERVICEUNAVAILABLE.toString());
346 * verify that the router exists and is not in use before removing it
348 if (!routerInterface.routerExists(routerUUID))
349 throw new ResourceNotFoundException("Router UUID not found");
350 if (routerInterface.routerInUse(routerUUID))
351 throw new ResourceConflictException("Router UUID in Use");
352 NeutronRouter singleton = routerInterface.getRouter(routerUUID);
353 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
354 if (instances != null) {
355 if (instances.length > 0) {
356 for (Object instance : instances) {
357 INeutronRouterAware service = (INeutronRouterAware) instance;
358 int status = service.canDeleteRouter(singleton);
359 if (status < 200 || status > 299)
360 return Response.status(status).build();
363 throw new ServiceUnavailableException("No providers registered. Please try again later");
366 throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
368 routerInterface.removeRouter(routerUUID);
369 if (instances != null) {
370 for (Object instance : instances) {
371 INeutronRouterAware service = (INeutronRouterAware) instance;
372 service.neutronRouterDeleted(singleton);
375 return Response.status(204).build();
379 * Adds an interface to a router */
381 @Path("{routerUUID}/add_router_interface")
383 @Produces({ MediaType.APPLICATION_JSON })
384 @Consumes({ MediaType.APPLICATION_JSON })
385 //@TypeHint(OpenStackRouterInterfaces.class)
387 @ResponseCode(code = 200, condition = "Operation successful"),
388 @ResponseCode(code = 400, condition = "Bad Request"),
389 @ResponseCode(code = 401, condition = "Unauthorized"),
390 @ResponseCode(code = 404, condition = "Not Found"),
391 @ResponseCode(code = 409, condition = "Conflict"),
392 @ResponseCode(code = 501, condition = "Not Implemented"),
393 @ResponseCode(code = 503, condition = "No providers available") })
394 public Response addRouterInterface(
395 @PathParam("routerUUID") String routerUUID,
396 NeutronRouter_Interface input
398 INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
399 if (routerInterface == null) {
400 throw new ServiceUnavailableException("Router CRUD Interface "
401 + RestMessages.SERVICEUNAVAILABLE.toString());
403 INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
404 if (portInterface == null) {
405 throw new ServiceUnavailableException("Port CRUD Interface "
406 + RestMessages.SERVICEUNAVAILABLE.toString());
408 INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
409 if (subnetInterface == null) {
410 throw new ServiceUnavailableException("Subnet CRUD Interface "
411 + RestMessages.SERVICEUNAVAILABLE.toString());
415 * While the Neutron specification says that the router has to exist and the input can only specify either a subnet id
416 * or a port id, but not both, this code assumes that the plugin has filled everything in for us and so both must be present
418 if (!routerInterface.routerExists(routerUUID))
419 throw new BadRequestException("Router UUID doesn't exist");
420 NeutronRouter target = routerInterface.getRouter(routerUUID);
421 if (input.getSubnetUUID() == null ||
422 input.getPortUUID() == null)
423 throw new BadRequestException("Must specify at subnet id, port id or both");
425 // check that the port is part of the subnet
426 NeutronSubnet targetSubnet = subnetInterface.getSubnet(input.getSubnetUUID());
427 if (targetSubnet == null)
428 throw new BadRequestException("Subnet id doesn't exist");
429 NeutronPort targetPort = portInterface.getPort(input.getPortUUID());
430 if (targetPort == null)
431 throw new BadRequestException("Port id doesn't exist");
432 if (!targetSubnet.getPortsInSubnet().contains(targetPort))
433 throw new BadRequestException("Port id not part of subnet id");
435 if (targetPort.getFixedIPs().size() != 1)
436 throw new BadRequestException("Port id must have a single fixedIP address");
437 if (targetPort.getDeviceID() != null ||
438 targetPort.getDeviceOwner() != null)
439 throw new ResourceConflictException("Target Port already allocated");
440 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
441 if (instances != null) {
442 if (instances.length > 0) {
443 for (Object instance : instances) {
444 INeutronRouterAware service = (INeutronRouterAware) instance;
445 int status = service.canAttachInterface(target, input);
446 if (status < 200 || status > 299)
447 return Response.status(status).build();
450 throw new ServiceUnavailableException("No providers registered. Please try again later");
453 throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
456 //mark the port device id and device owner fields
457 targetPort.setDeviceOwner("network:router_interface");
458 targetPort.setDeviceID(routerUUID);
460 target.addInterface(input.getPortUUID(), input);
461 if (instances != null) {
462 for (Object instance : instances) {
463 INeutronRouterAware service = (INeutronRouterAware) instance;
464 service.neutronRouterInterfaceAttached(target, input);
468 return Response.status(200).entity(input).build();
472 * Removes an interface to a router */
474 @Path("{routerUUID}/remove_router_interface")
476 @Produces({ MediaType.APPLICATION_JSON })
477 @Consumes({ MediaType.APPLICATION_JSON })
478 //@TypeHint(OpenStackRouterInterfaces.class)
480 @ResponseCode(code = 200, condition = "Operation successful"),
481 @ResponseCode(code = 400, condition = "Bad Request"),
482 @ResponseCode(code = 401, condition = "Unauthorized"),
483 @ResponseCode(code = 404, condition = "Not Found"),
484 @ResponseCode(code = 409, condition = "Conflict"),
485 @ResponseCode(code = 501, condition = "Not Implemented"),
486 @ResponseCode(code = 503, condition = "No providers available") })
487 public Response removeRouterInterface(
488 @PathParam("routerUUID") String routerUUID,
489 NeutronRouter_Interface input
491 INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
492 if (routerInterface == null) {
493 throw new ServiceUnavailableException("Router CRUD Interface "
494 + RestMessages.SERVICEUNAVAILABLE.toString());
496 INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
497 if (portInterface == null) {
498 throw new ServiceUnavailableException("Port CRUD Interface "
499 + RestMessages.SERVICEUNAVAILABLE.toString());
501 INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
502 if (subnetInterface == null) {
503 throw new ServiceUnavailableException("Subnet CRUD Interface "
504 + RestMessages.SERVICEUNAVAILABLE.toString());
507 // verify the router exists
508 if (!routerInterface.routerExists(routerUUID))
509 throw new BadRequestException("Router does not exist");
510 NeutronRouter target = routerInterface.getRouter(routerUUID);
513 * remove by subnet id. Collect information about the impacted router for the response and
514 * remove the port corresponding to the gateway IP address of the subnet
516 if (input.getPortUUID() == null &&
517 input.getSubnetUUID() != null) {
518 NeutronPort port = portInterface.getGatewayPort(input.getSubnetUUID());
520 throw new ResourceNotFoundException("Port UUID not found");
521 input.setPortUUID(port.getID());
522 input.setID(target.getID());
523 input.setTenantID(target.getTenantID());
525 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
526 if (instances != null) {
527 if (instances.length > 0) {
528 for (Object instance : instances) {
529 INeutronRouterAware service = (INeutronRouterAware) instance;
530 int status = service.canDetachInterface(target, input);
531 if (status < 200 || status > 299)
532 return Response.status(status).build();
535 throw new ServiceUnavailableException("No providers registered. Please try again later");
538 throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
541 // reset the port ownership
542 port.setDeviceID(null);
543 port.setDeviceOwner(null);
545 target.removeInterface(input.getPortUUID());
546 if (instances != null) {
547 for (Object instance : instances) {
548 INeutronRouterAware service = (INeutronRouterAware) instance;
549 service.neutronRouterInterfaceDetached(target, input);
552 return Response.status(200).entity(input).build();
556 * remove by port id. collect information about the impacted router for the response
557 * remove the interface and reset the port ownership
559 if (input.getPortUUID() != null &&
560 input.getSubnetUUID() == null) {
561 NeutronRouter_Interface targetInterface = target.getInterfaces().get(input.getPortUUID());
562 if (targetInterface == null) {
563 throw new ResourceNotFoundException("Router interface not found for given Port UUID");
565 input.setSubnetUUID(targetInterface.getSubnetUUID());
566 input.setID(target.getID());
567 input.setTenantID(target.getTenantID());
568 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
569 if (instances != null) {
570 if (instances.length > 0) {
571 for (Object instance : instances) {
572 INeutronRouterAware service = (INeutronRouterAware) instance;
573 int status = service.canDetachInterface(target, input);
574 if (status < 200 || status > 299)
575 return Response.status(status).build();
578 throw new ServiceUnavailableException("No providers registered. Please try again later");
581 throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
583 NeutronPort port = portInterface.getPort(input.getPortUUID());
584 port.setDeviceID(null);
585 port.setDeviceOwner(null);
586 target.removeInterface(input.getPortUUID());
587 for (Object instance : instances) {
588 INeutronRouterAware service = (INeutronRouterAware) instance;
589 service.neutronRouterInterfaceDetached(target, input);
591 return Response.status(200).entity(input).build();
595 * remove by both port and subnet ID. Verify that the first fixed IP of the port is a valid
596 * IP address for the subnet, and then remove the interface, collecting information about the
597 * impacted router for the response and reset port ownership
599 if (input.getPortUUID() != null &&
600 input.getSubnetUUID() != null) {
601 NeutronPort port = portInterface.getPort(input.getPortUUID());
603 throw new ResourceNotFoundException("Port UUID not found");
605 if (port.getFixedIPs() == null) {
606 throw new ResourceNotFoundException("Port UUID has no fixed IPs");
608 NeutronSubnet subnet = subnetInterface.getSubnet(input.getSubnetUUID());
609 if (subnet == null) {
610 throw new ResourceNotFoundException("Subnet UUID not found");
612 if (!subnet.isValidIP(port.getFixedIPs().get(0).getIpAddress()))
613 throw new ResourceConflictException("Target Port IP not in Target Subnet");
614 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
615 if (instances != null) {
616 if (instances.length > 0) {
617 for (Object instance : instances) {
618 INeutronRouterAware service = (INeutronRouterAware) instance;
619 int status = service.canDetachInterface(target, input);
620 if (status < 200 || status > 299)
621 return Response.status(status).build();
624 throw new ServiceUnavailableException("No providers registered. Please try again later");
627 throw new ServiceUnavailableException("Couldn't get providers list. Please try again later");
629 input.setID(target.getID());
630 input.setTenantID(target.getTenantID());
631 port.setDeviceID(null);
632 port.setDeviceOwner(null);
633 target.removeInterface(input.getPortUUID());
634 if (instances != null) {
635 for (Object instance : instances) {
636 INeutronRouterAware service = (INeutronRouterAware) instance;
637 service.canDetachInterface(target, input);
639 } for (Object instance : instances) {
640 INeutronRouterAware service = (INeutronRouterAware) instance;
641 service.neutronRouterInterfaceDetached(target, input);
643 return Response.status(200).entity(input).build();
646 // have to specify either a port ID or a subnet ID
647 throw new BadRequestException("Must specify port id or subnet id or both");