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.net.HttpURLConnection;
13 import java.util.ArrayList;
14 import java.util.Iterator;
15 import java.util.List;
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;
29 import org.codehaus.enunciate.jaxrs.ResponseCode;
30 import org.codehaus.enunciate.jaxrs.StatusCodes;
31 import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
32 import org.opendaylight.neutron.spi.INeutronPortCRUD;
33 import org.opendaylight.neutron.spi.INeutronRouterAware;
34 import org.opendaylight.neutron.spi.INeutronRouterCRUD;
35 import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
36 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
37 import org.opendaylight.neutron.spi.NeutronNetwork;
38 import org.opendaylight.neutron.spi.NeutronPort;
39 import org.opendaylight.neutron.spi.NeutronRouter;
40 import org.opendaylight.neutron.spi.NeutronRouter_Interface;
41 import org.opendaylight.neutron.spi.NeutronSubnet;
45 * Neutron Northbound REST APIs.<br>
46 * This class provides REST APIs for managing neutron routers
50 * Authentication scheme : <b>HTTP Basic</b><br>
51 * Authentication realm : <b>opendaylight</b><br>
52 * Transport : <b>HTTP and HTTPS</b><br>
54 * HTTPS Authentication is disabled by default. Administrator can enable it in
55 * tomcat-server.xml after adding a proper keystore / SSL certificate from a
56 * trusted authority.<br>
58 * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
63 public class NeutronRoutersNorthbound {
64 static final String ROUTER_INTERFACE_STR = "network:router_interface";
65 static final String ROUTER_GATEWAY_STR = "network:router_gateway";
66 private static final int HTTP_OK_BOTTOM = 200;
67 private static final int HTTP_OK_TOP = 299;
68 private static final String INTERFACE_NAME = "Router CRUD Interface";
69 private static final String UUID_NO_EXIST = "Router UUID does not exist.";
70 private static final String NO_PROVIDERS = "No providers registered. Please try again later";
71 private static final String NO_PROVIDER_LIST = "Couldn't get providers list. Please try again later";
73 private NeutronRouter extractFields(NeutronRouter o, List<String> fields) {
74 return o.extractFields(fields);
77 private NeutronCRUDInterfaces getNeutronInterfaces(boolean flag) {
78 NeutronCRUDInterfaces answer = new NeutronCRUDInterfaces().fetchINeutronRouterCRUD(this);
79 if (answer.getRouterInterface() == null) {
80 throw new ServiceUnavailableException(INTERFACE_NAME
81 + RestMessages.SERVICEUNAVAILABLE.toString());
84 answer = answer.fetchINeutronNetworkCRUD(this);
85 if (answer.getNetworkInterface() == null) {
86 throw new ServiceUnavailableException("Network CRUD Interface "
87 + RestMessages.SERVICEUNAVAILABLE.toString());
93 private NeutronCRUDInterfaces getAttachInterfaces() {
94 NeutronCRUDInterfaces answer = new NeutronCRUDInterfaces().fetchINeutronRouterCRUD(this);
95 if (answer.getRouterInterface() == null) {
96 throw new ServiceUnavailableException(INTERFACE_NAME
97 + RestMessages.SERVICEUNAVAILABLE.toString());
99 answer = answer.fetchINeutronPortCRUD(this).fetchINeutronSubnetCRUD(this);
100 if (answer.getPortInterface() == null) {
101 throw new ServiceUnavailableException("Port CRUD Interface "
102 + RestMessages.SERVICEUNAVAILABLE.toString());
104 if (answer.getSubnetInterface() == null) {
105 throw new ServiceUnavailableException("Subnet CRUD Interface "
106 + RestMessages.SERVICEUNAVAILABLE.toString());
112 * Returns a list of all Routers */
115 @Produces({ MediaType.APPLICATION_JSON })
116 //@TypeHint(OpenStackRouters.class)
118 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
119 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
120 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
121 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
122 public Response listRouters(
124 @QueryParam("fields") List<String> fields,
125 // note: openstack isn't clear about filtering on lists, so we aren't handling them
126 @QueryParam("id") String queryID,
127 @QueryParam("name") String queryName,
128 @QueryParam("admin_state_up") String queryAdminStateUp,
129 @QueryParam("status") String queryStatus,
130 @QueryParam("tenant_id") String queryTenantID,
131 @QueryParam("external_gateway_info") String queryExternalGatewayInfo,
133 @QueryParam("limit") String limit,
134 @QueryParam("marker") String marker,
135 @QueryParam("page_reverse") String pageReverse
136 // sorting not supported
138 INeutronRouterCRUD routerInterface = getNeutronInterfaces(false).getRouterInterface();
139 if (routerInterface == null) {
140 throw new ServiceUnavailableException(INTERFACE_NAME
141 + RestMessages.SERVICEUNAVAILABLE.toString());
143 List<NeutronRouter> allRouters = routerInterface.getAllRouters();
144 List<NeutronRouter> ans = new ArrayList<NeutronRouter>();
145 Iterator<NeutronRouter> i = allRouters.iterator();
146 while (i.hasNext()) {
147 NeutronRouter oSS = i.next();
148 if ((queryID == null || queryID.equals(oSS.getID())) &&
149 (queryName == null || queryName.equals(oSS.getName())) &&
150 (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&
151 (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&
152 (queryExternalGatewayInfo == null || queryExternalGatewayInfo.equals(oSS.getExternalGatewayInfo())) &&
153 (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {
154 if (fields.size() > 0) {
155 ans.add(extractFields(oSS,fields));
161 //TODO: apply pagination to results
162 return Response.status(HttpURLConnection.HTTP_OK).entity(
163 new NeutronRouterRequest(ans)).build();
167 * Returns a specific Router */
169 @Path("{routerUUID}")
171 @Produces({ MediaType.APPLICATION_JSON })
172 //@TypeHint(OpenStackRouters.class)
174 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
175 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
176 @ResponseCode(code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
177 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
178 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
179 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
180 public Response showRouter(
181 @PathParam("routerUUID") String routerUUID,
183 @QueryParam("fields") List<String> fields) {
184 INeutronRouterCRUD routerInterface = getNeutronInterfaces(false).getRouterInterface();
185 if (routerInterface == null) {
186 throw new ServiceUnavailableException(INTERFACE_NAME
187 + RestMessages.SERVICEUNAVAILABLE.toString());
189 if (!routerInterface.routerExists(routerUUID)) {
190 throw new ResourceNotFoundException(UUID_NO_EXIST);
192 if (fields.size() > 0) {
193 NeutronRouter ans = routerInterface.getRouter(routerUUID);
194 return Response.status(HttpURLConnection.HTTP_OK).entity(
195 new NeutronRouterRequest(extractFields(ans, fields))).build();
197 return Response.status(HttpURLConnection.HTTP_OK).entity(
198 new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();
203 * Creates new Routers */
206 @Produces({ MediaType.APPLICATION_JSON })
207 @Consumes({ MediaType.APPLICATION_JSON })
208 //@TypeHint(OpenStackRouters.class)
210 @ResponseCode(code = HttpURLConnection.HTTP_CREATED, condition = "Created"),
211 @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
212 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
213 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
214 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
215 public Response createRouters(final NeutronRouterRequest input) {
216 NeutronCRUDInterfaces interfaces = getNeutronInterfaces(true);
217 INeutronRouterCRUD routerInterface = interfaces.getRouterInterface();
218 INeutronNetworkCRUD networkInterface = interfaces.getNetworkInterface();
219 if (input.isSingleton()) {
220 NeutronRouter singleton = input.getSingleton();
223 * verify that the router doesn't already exist (issue: is deeper inspection necessary?)
224 * if there is external gateway information provided, verify that the specified network
225 * exists and has been designated as "router:external"
227 if (routerInterface.routerExists(singleton.getID())) {
228 throw new BadRequestException("router UUID already exists");
230 if (singleton.getExternalGatewayInfo() != null) {
231 String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();
232 if (!networkInterface.networkExists(externNetworkPtr)) {
233 throw new BadRequestException("External Network Pointer doesn't exist");
235 NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);
236 if (!externNetwork.isRouterExternal()) {
237 throw new BadRequestException("External Network Pointer isn't marked as router:external");
240 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
241 if (instances != null) {
242 if (instances.length > 0) {
243 for (Object instance : instances) {
244 INeutronRouterAware service = (INeutronRouterAware) instance;
245 int status = service.canCreateRouter(singleton);
246 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
247 return Response.status(status).build();
251 throw new ServiceUnavailableException(NO_PROVIDERS);
254 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
258 * add router to the cache
260 routerInterface.addRouter(singleton);
261 if (instances != null) {
262 for (Object instance : instances) {
263 INeutronRouterAware service = (INeutronRouterAware) instance;
264 service.neutronRouterCreated(singleton);
270 * only singleton router creates supported
272 throw new BadRequestException("Only singleton router creates supported");
274 return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build();
278 * Updates a Router */
280 @Path("{routerUUID}")
282 @Produces({ MediaType.APPLICATION_JSON })
283 @Consumes({ MediaType.APPLICATION_JSON })
284 //@TypeHint(OpenStackRouters.class)
286 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
287 @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
288 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
289 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
290 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
291 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
292 public Response updateRouter(
293 @PathParam("routerUUID") String routerUUID,
294 NeutronRouterRequest input
296 NeutronCRUDInterfaces interfaces = getNeutronInterfaces(true);
297 INeutronRouterCRUD routerInterface = interfaces.getRouterInterface();
298 INeutronNetworkCRUD networkInterface = interfaces.getNetworkInterface();
301 * router has to exist and only a single delta can be supplied
303 if (!routerInterface.routerExists(routerUUID)) {
304 throw new ResourceNotFoundException(UUID_NO_EXIST);
306 if (!input.isSingleton()) {
307 throw new BadRequestException("Only single router deltas supported");
309 NeutronRouter singleton = input.getSingleton();
310 NeutronRouter original = routerInterface.getRouter(routerUUID);
313 * attribute changes blocked by Neutron
315 if (singleton.getID() != null || singleton.getTenantID() != null ||
316 singleton.getStatus() != null) {
317 throw new BadRequestException("Request attribute change not allowed");
320 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
321 if (instances != null) {
322 if (instances.length > 0) {
323 for (Object instance : instances) {
324 INeutronRouterAware service = (INeutronRouterAware) instance;
325 int status = service.canUpdateRouter(singleton, original);
326 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
327 return Response.status(status).build();
331 throw new ServiceUnavailableException(NO_PROVIDERS);
334 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
337 * if the external gateway info is being changed, verify that the new network
338 * exists and has been designated as an external network
340 if (singleton.getExternalGatewayInfo() != null) {
341 String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();
342 if (!networkInterface.networkExists(externNetworkPtr)) {
343 throw new BadRequestException("External Network Pointer does not exist");
345 NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);
346 if (!externNetwork.isRouterExternal()) {
347 throw new BadRequestException("External Network Pointer isn't marked as router:external");
352 * update the router entry and return the modified object
354 routerInterface.updateRouter(routerUUID, singleton);
355 NeutronRouter updatedRouter = routerInterface.getRouter(routerUUID);
356 if (instances != null) {
357 for (Object instance : instances) {
358 INeutronRouterAware service = (INeutronRouterAware) instance;
359 service.neutronRouterUpdated(updatedRouter);
362 return Response.status(HttpURLConnection.HTTP_OK).entity(
363 new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();
368 * Deletes a Router */
370 @Path("{routerUUID}")
373 @ResponseCode(code = HttpURLConnection.HTTP_NO_CONTENT, condition = "No Content"),
374 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
375 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
376 @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
377 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
378 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
379 public Response deleteRouter(
380 @PathParam("routerUUID") String routerUUID) {
381 INeutronRouterCRUD routerInterface = getNeutronInterfaces(false).getRouterInterface();
384 * verify that the router exists and is not in use before removing it
386 if (!routerInterface.routerExists(routerUUID)) {
387 throw new ResourceNotFoundException(UUID_NO_EXIST);
389 if (routerInterface.routerInUse(routerUUID)) {
390 throw new ResourceConflictException("Router UUID in Use");
392 NeutronRouter singleton = routerInterface.getRouter(routerUUID);
393 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
394 if (instances != null) {
395 if (instances.length > 0) {
396 for (Object instance : instances) {
397 INeutronRouterAware service = (INeutronRouterAware) instance;
398 int status = service.canDeleteRouter(singleton);
399 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
400 return Response.status(status).build();
404 throw new ServiceUnavailableException(NO_PROVIDERS);
407 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
409 routerInterface.removeRouter(routerUUID);
410 if (instances != null) {
411 for (Object instance : instances) {
412 INeutronRouterAware service = (INeutronRouterAware) instance;
413 service.neutronRouterDeleted(singleton);
416 return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build();
420 * Adds an interface to a router */
422 @Path("{routerUUID}/add_router_interface")
424 @Produces({ MediaType.APPLICATION_JSON })
425 @Consumes({ MediaType.APPLICATION_JSON })
426 //@TypeHint(OpenStackRouterInterfaces.class)
428 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
429 @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
430 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
431 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
432 @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
433 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
434 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
435 public Response addRouterInterface(
436 @PathParam("routerUUID") String routerUUID,
437 NeutronRouter_Interface input
439 NeutronCRUDInterfaces interfaces = getAttachInterfaces();
440 INeutronRouterCRUD routerInterface = interfaces.getRouterInterface();
441 INeutronPortCRUD portInterface = interfaces.getPortInterface();
442 INeutronSubnetCRUD subnetInterface = interfaces.getSubnetInterface();
445 * While the Neutron specification says that the router has to exist and the input can only specify either a subnet id
446 * 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
448 if (!routerInterface.routerExists(routerUUID)) {
449 throw new BadRequestException(UUID_NO_EXIST);
451 NeutronRouter target = routerInterface.getRouter(routerUUID);
452 if (input.getSubnetUUID() == null ||
453 input.getPortUUID() == null) {
454 throw new BadRequestException("Must specify at subnet id, port id or both");
457 // check that the port is part of the subnet
458 NeutronSubnet targetSubnet = subnetInterface.getSubnet(input.getSubnetUUID());
459 if (targetSubnet == null) {
460 throw new BadRequestException("Subnet id doesn't exist");
462 NeutronPort targetPort = portInterface.getPort(input.getPortUUID());
463 if (targetPort == null) {
464 throw new BadRequestException("Port id doesn't exist");
466 if (!targetSubnet.getPortsInSubnet().contains(targetPort)) {
467 throw new BadRequestException("Port id not part of subnet id");
470 if (targetPort.getFixedIPs().size() != 1) {
471 throw new BadRequestException("Port id must have a single fixedIP address");
473 if (targetPort.getDeviceID() != null && !targetPort.getDeviceID().equals(routerUUID)) {
474 throw new ResourceConflictException("Target Port already allocated to a different device id");
476 if (targetPort.getDeviceOwner() != null &&
477 !targetPort.getDeviceOwner().equalsIgnoreCase(ROUTER_INTERFACE_STR) &&
478 !targetPort.getDeviceOwner().equalsIgnoreCase(ROUTER_GATEWAY_STR)) {
479 throw new ResourceConflictException("Target Port already allocated to non-router interface");
481 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
482 if (instances != null) {
483 if (instances.length > 0) {
484 for (Object instance : instances) {
485 INeutronRouterAware service = (INeutronRouterAware) instance;
486 int status = service.canAttachInterface(target, input);
487 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
488 return Response.status(status).build();
492 throw new ServiceUnavailableException(NO_PROVIDERS);
495 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
498 //mark the port device id and device owner fields
499 if (targetPort.getDeviceOwner() == null || targetPort.getDeviceOwner().isEmpty()) {
500 targetPort.setDeviceOwner(ROUTER_INTERFACE_STR);
502 targetPort.setDeviceID(routerUUID);
504 target.addInterface(input.getPortUUID(), input);
505 if (instances != null) {
506 for (Object instance : instances) {
507 INeutronRouterAware service = (INeutronRouterAware) instance;
508 service.neutronRouterInterfaceAttached(target, input);
512 return Response.status(HttpURLConnection.HTTP_OK).entity(input).build();
516 * Removes an interface to a router */
518 @Path("{routerUUID}/remove_router_interface")
520 @Produces({ MediaType.APPLICATION_JSON })
521 @Consumes({ MediaType.APPLICATION_JSON })
522 //@TypeHint(OpenStackRouterInterfaces.class)
524 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
525 @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
526 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
527 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
528 @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
529 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
530 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
531 public Response removeRouterInterface(
532 @PathParam("routerUUID") String routerUUID,
533 NeutronRouter_Interface input
535 NeutronCRUDInterfaces interfaces = getAttachInterfaces();
536 INeutronRouterCRUD routerInterface = interfaces.getRouterInterface();
537 INeutronPortCRUD portInterface = interfaces.getPortInterface();
538 INeutronSubnetCRUD subnetInterface = interfaces.getSubnetInterface();
540 // verify the router exists
541 if (!routerInterface.routerExists(routerUUID)) {
542 throw new BadRequestException("Router does not exist");
544 NeutronRouter target = routerInterface.getRouter(routerUUID);
547 * remove by subnet id. Collect information about the impacted router for the response and
548 * remove the port corresponding to the gateway IP address of the subnet
550 if (input.getPortUUID() == null &&
551 input.getSubnetUUID() != null) {
552 NeutronPort port = portInterface.getGatewayPort(input.getSubnetUUID());
554 throw new ResourceNotFoundException("Port UUID not found");
556 input.setPortUUID(port.getID());
557 input.setID(target.getID());
558 input.setTenantID(target.getTenantID());
560 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
561 if (instances != null) {
562 if (instances.length > 0) {
563 for (Object instance : instances) {
564 INeutronRouterAware service = (INeutronRouterAware) instance;
565 int status = service.canDetachInterface(target, input);
566 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
567 return Response.status(status).build();
571 throw new ServiceUnavailableException(NO_PROVIDERS);
574 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
577 // reset the port ownership
578 port.setDeviceID(null);
579 port.setDeviceOwner(null);
581 target.removeInterface(input.getPortUUID());
582 if (instances != null) {
583 for (Object instance : instances) {
584 INeutronRouterAware service = (INeutronRouterAware) instance;
585 service.neutronRouterInterfaceDetached(target, input);
588 return Response.status(HttpURLConnection.HTTP_OK).entity(input).build();
592 * remove by port id. collect information about the impacted router for the response
593 * remove the interface and reset the port ownership
595 if (input.getPortUUID() != null &&
596 input.getSubnetUUID() == null) {
597 NeutronRouter_Interface targetInterface = target.getInterfaces().get(input.getPortUUID());
598 if (targetInterface == null) {
599 throw new ResourceNotFoundException("Router interface not found for given Port UUID");
601 input.setSubnetUUID(targetInterface.getSubnetUUID());
602 input.setID(target.getID());
603 input.setTenantID(target.getTenantID());
604 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
605 if (instances != null) {
606 if (instances.length > 0) {
607 for (Object instance : instances) {
608 INeutronRouterAware service = (INeutronRouterAware) instance;
609 int status = service.canDetachInterface(target, input);
610 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
611 return Response.status(status).build();
615 throw new ServiceUnavailableException(NO_PROVIDERS);
618 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
620 NeutronPort port = portInterface.getPort(input.getPortUUID());
621 port.setDeviceID(null);
622 port.setDeviceOwner(null);
623 target.removeInterface(input.getPortUUID());
624 for (Object instance : instances) {
625 INeutronRouterAware service = (INeutronRouterAware) instance;
626 service.neutronRouterInterfaceDetached(target, input);
628 return Response.status(HttpURLConnection.HTTP_OK).entity(input).build();
632 * remove by both port and subnet ID. Verify that the first fixed IP of the port is a valid
633 * IP address for the subnet, and then remove the interface, collecting information about the
634 * impacted router for the response and reset port ownership
636 if (input.getPortUUID() != null &&
637 input.getSubnetUUID() != null) {
638 NeutronPort port = portInterface.getPort(input.getPortUUID());
640 throw new ResourceNotFoundException("Port UUID not found");
642 if (port.getFixedIPs() == null) {
643 throw new ResourceNotFoundException("Port UUID has no fixed IPs");
645 NeutronSubnet subnet = subnetInterface.getSubnet(input.getSubnetUUID());
646 if (subnet == null) {
647 throw new ResourceNotFoundException("Subnet UUID not found");
649 if (!subnet.isValidIP(port.getFixedIPs().get(0).getIpAddress())) {
650 throw new ResourceConflictException("Target Port IP not in Target Subnet");
652 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
653 if (instances != null) {
654 if (instances.length > 0) {
655 for (Object instance : instances) {
656 INeutronRouterAware service = (INeutronRouterAware) instance;
657 int status = service.canDetachInterface(target, input);
658 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
659 return Response.status(status).build();
663 throw new ServiceUnavailableException(NO_PROVIDERS);
666 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
668 input.setID(target.getID());
669 input.setTenantID(target.getTenantID());
670 port.setDeviceID(null);
671 port.setDeviceOwner(null);
672 target.removeInterface(input.getPortUUID());
673 if (instances != null) {
674 for (Object instance : instances) {
675 INeutronRouterAware service = (INeutronRouterAware) instance;
676 service.canDetachInterface(target, input);
678 } for (Object instance : instances) {
679 INeutronRouterAware service = (INeutronRouterAware) instance;
680 service.neutronRouterInterfaceDetached(target, input);
682 return Response.status(HttpURLConnection.HTTP_OK).entity(input).build();
685 // have to specify either a port ID or a subnet ID
686 throw new BadRequestException("Must specify port id or subnet id or both");