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();
202 * Creates new Routers */
205 @Produces({ MediaType.APPLICATION_JSON })
206 @Consumes({ MediaType.APPLICATION_JSON })
207 //@TypeHint(OpenStackRouters.class)
209 @ResponseCode(code = HttpURLConnection.HTTP_CREATED, condition = "Created"),
210 @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
211 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
212 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
213 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
214 public Response createRouters(final NeutronRouterRequest input) {
215 NeutronCRUDInterfaces interfaces = getNeutronInterfaces(true);
216 INeutronRouterCRUD routerInterface = interfaces.getRouterInterface();
217 INeutronNetworkCRUD networkInterface = interfaces.getNetworkInterface();
218 if (input.isSingleton()) {
219 NeutronRouter singleton = input.getSingleton();
222 * verify that the router doesn't already exist (issue: is deeper inspection necessary?)
223 * if there is external gateway information provided, verify that the specified network
224 * exists and has been designated as "router:external"
226 if (routerInterface.routerExists(singleton.getID())) {
227 throw new BadRequestException("router UUID already exists");
229 if (singleton.getExternalGatewayInfo() != null) {
230 String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();
231 if (!networkInterface.networkExists(externNetworkPtr)) {
232 throw new BadRequestException("External Network Pointer doesn't exist");
234 NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);
235 if (!externNetwork.isRouterExternal()) {
236 throw new BadRequestException("External Network Pointer isn't marked as router:external");
239 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
240 if (instances != null) {
241 if (instances.length > 0) {
242 for (Object instance : instances) {
243 INeutronRouterAware service = (INeutronRouterAware) instance;
244 int status = service.canCreateRouter(singleton);
245 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
246 return Response.status(status).build();
250 throw new ServiceUnavailableException(NO_PROVIDERS);
253 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
257 * add router to the cache
259 routerInterface.addRouter(singleton);
260 if (instances != null) {
261 for (Object instance : instances) {
262 INeutronRouterAware service = (INeutronRouterAware) instance;
263 service.neutronRouterCreated(singleton);
269 * only singleton router creates supported
271 throw new BadRequestException("Only singleton router creates supported");
273 return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build();
277 * Updates a Router */
279 @Path("{routerUUID}")
281 @Produces({ MediaType.APPLICATION_JSON })
282 @Consumes({ MediaType.APPLICATION_JSON })
283 //@TypeHint(OpenStackRouters.class)
285 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
286 @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
287 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
288 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
289 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
290 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
291 public Response updateRouter(
292 @PathParam("routerUUID") String routerUUID,
293 NeutronRouterRequest input
295 NeutronCRUDInterfaces interfaces = getNeutronInterfaces(true);
296 INeutronRouterCRUD routerInterface = interfaces.getRouterInterface();
297 INeutronNetworkCRUD networkInterface = interfaces.getNetworkInterface();
300 * router has to exist and only a single delta can be supplied
302 if (!routerInterface.routerExists(routerUUID)) {
303 throw new ResourceNotFoundException(UUID_NO_EXIST);
305 if (!input.isSingleton()) {
306 throw new BadRequestException("Only single router deltas supported");
308 NeutronRouter singleton = input.getSingleton();
309 NeutronRouter original = routerInterface.getRouter(routerUUID);
312 * attribute changes blocked by Neutron
314 if (singleton.getID() != null || singleton.getTenantID() != null ||
315 singleton.getStatus() != null) {
316 throw new BadRequestException("Request attribute change not allowed");
319 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
320 if (instances != null) {
321 if (instances.length > 0) {
322 for (Object instance : instances) {
323 INeutronRouterAware service = (INeutronRouterAware) instance;
324 int status = service.canUpdateRouter(singleton, original);
325 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
326 return Response.status(status).build();
330 throw new ServiceUnavailableException(NO_PROVIDERS);
333 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
336 * if the external gateway info is being changed, verify that the new network
337 * exists and has been designated as an external network
339 if (singleton.getExternalGatewayInfo() != null) {
340 String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();
341 if (!networkInterface.networkExists(externNetworkPtr)) {
342 throw new BadRequestException("External Network Pointer does not exist");
344 NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);
345 if (!externNetwork.isRouterExternal()) {
346 throw new BadRequestException("External Network Pointer isn't marked as router:external");
351 * update the router entry and return the modified object
353 routerInterface.updateRouter(routerUUID, singleton);
354 NeutronRouter updatedRouter = routerInterface.getRouter(routerUUID);
355 if (instances != null) {
356 for (Object instance : instances) {
357 INeutronRouterAware service = (INeutronRouterAware) instance;
358 service.neutronRouterUpdated(updatedRouter);
361 return Response.status(HttpURLConnection.HTTP_OK).entity(
362 new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();
367 * Deletes a Router */
369 @Path("{routerUUID}")
372 @ResponseCode(code = HttpURLConnection.HTTP_NO_CONTENT, condition = "No Content"),
373 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
374 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
375 @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
376 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
377 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
378 public Response deleteRouter(
379 @PathParam("routerUUID") String routerUUID) {
380 INeutronRouterCRUD routerInterface = getNeutronInterfaces(false).getRouterInterface();
383 * verify that the router exists and is not in use before removing it
385 if (!routerInterface.routerExists(routerUUID)) {
386 throw new ResourceNotFoundException(UUID_NO_EXIST);
388 if (routerInterface.routerInUse(routerUUID)) {
389 throw new ResourceConflictException("Router UUID in Use");
391 NeutronRouter singleton = routerInterface.getRouter(routerUUID);
392 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
393 if (instances != null) {
394 if (instances.length > 0) {
395 for (Object instance : instances) {
396 INeutronRouterAware service = (INeutronRouterAware) instance;
397 int status = service.canDeleteRouter(singleton);
398 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
399 return Response.status(status).build();
403 throw new ServiceUnavailableException(NO_PROVIDERS);
406 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
408 routerInterface.removeRouter(routerUUID);
409 if (instances != null) {
410 for (Object instance : instances) {
411 INeutronRouterAware service = (INeutronRouterAware) instance;
412 service.neutronRouterDeleted(singleton);
415 return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build();
419 * Adds an interface to a router */
421 @Path("{routerUUID}/add_router_interface")
423 @Produces({ MediaType.APPLICATION_JSON })
424 @Consumes({ MediaType.APPLICATION_JSON })
425 //@TypeHint(OpenStackRouterInterfaces.class)
427 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
428 @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
429 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
430 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
431 @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
432 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
433 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
434 public Response addRouterInterface(
435 @PathParam("routerUUID") String routerUUID,
436 NeutronRouter_Interface input
438 NeutronCRUDInterfaces interfaces = getAttachInterfaces();
439 INeutronRouterCRUD routerInterface = interfaces.getRouterInterface();
440 INeutronPortCRUD portInterface = interfaces.getPortInterface();
441 INeutronSubnetCRUD subnetInterface = interfaces.getSubnetInterface();
444 * While the Neutron specification says that the router has to exist and the input can only specify either a subnet id
445 * 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
447 if (!routerInterface.routerExists(routerUUID)) {
448 throw new BadRequestException(UUID_NO_EXIST);
450 NeutronRouter target = routerInterface.getRouter(routerUUID);
451 if (input.getSubnetUUID() == null ||
452 input.getPortUUID() == null) {
453 throw new BadRequestException("Must specify at subnet id, port id or both");
456 // check that the port is part of the subnet
457 NeutronSubnet targetSubnet = subnetInterface.getSubnet(input.getSubnetUUID());
458 if (targetSubnet == null) {
459 throw new BadRequestException("Subnet id doesn't exist");
461 NeutronPort targetPort = portInterface.getPort(input.getPortUUID());
462 if (targetPort == null) {
463 throw new BadRequestException("Port id doesn't exist");
465 if (!targetSubnet.getPortsInSubnet().contains(targetPort)) {
466 throw new BadRequestException("Port id not part of subnet id");
469 if (targetPort.getFixedIPs().size() != 1) {
470 throw new BadRequestException("Port id must have a single fixedIP address");
472 if (targetPort.getDeviceID() != null && !targetPort.getDeviceID().equals(routerUUID)) {
473 throw new ResourceConflictException("Target Port already allocated to a different device id");
475 if (targetPort.getDeviceOwner() != null &&
476 !targetPort.getDeviceOwner().equalsIgnoreCase(ROUTER_INTERFACE_STR) &&
477 !targetPort.getDeviceOwner().equalsIgnoreCase(ROUTER_GATEWAY_STR)) {
478 throw new ResourceConflictException("Target Port already allocated to non-router interface");
480 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
481 if (instances != null) {
482 if (instances.length > 0) {
483 for (Object instance : instances) {
484 INeutronRouterAware service = (INeutronRouterAware) instance;
485 int status = service.canAttachInterface(target, input);
486 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
487 return Response.status(status).build();
491 throw new ServiceUnavailableException(NO_PROVIDERS);
494 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
497 //mark the port device id and device owner fields
498 if (targetPort.getDeviceOwner() == null || targetPort.getDeviceOwner().isEmpty()) {
499 targetPort.setDeviceOwner(ROUTER_INTERFACE_STR);
501 targetPort.setDeviceID(routerUUID);
503 target.addInterface(input.getPortUUID(), input);
504 if (instances != null) {
505 for (Object instance : instances) {
506 INeutronRouterAware service = (INeutronRouterAware) instance;
507 service.neutronRouterInterfaceAttached(target, input);
511 return Response.status(HttpURLConnection.HTTP_OK).entity(input).build();
515 * Removes an interface to a router */
517 @Path("{routerUUID}/remove_router_interface")
519 @Produces({ MediaType.APPLICATION_JSON })
520 @Consumes({ MediaType.APPLICATION_JSON })
521 //@TypeHint(OpenStackRouterInterfaces.class)
523 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
524 @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
525 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
526 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
527 @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
528 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
529 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
530 public Response removeRouterInterface(
531 @PathParam("routerUUID") String routerUUID,
532 NeutronRouter_Interface input
534 NeutronCRUDInterfaces interfaces = getAttachInterfaces();
535 INeutronRouterCRUD routerInterface = interfaces.getRouterInterface();
536 INeutronPortCRUD portInterface = interfaces.getPortInterface();
537 INeutronSubnetCRUD subnetInterface = interfaces.getSubnetInterface();
539 // verify the router exists
540 if (!routerInterface.routerExists(routerUUID)) {
541 throw new BadRequestException("Router does not exist");
543 NeutronRouter target = routerInterface.getRouter(routerUUID);
546 * remove by subnet id. Collect information about the impacted router for the response and
547 * remove the port corresponding to the gateway IP address of the subnet
549 if (input.getPortUUID() == null &&
550 input.getSubnetUUID() != null) {
551 NeutronPort port = portInterface.getGatewayPort(input.getSubnetUUID());
553 throw new ResourceNotFoundException("Port UUID not found");
555 input.setPortUUID(port.getID());
556 input.setID(target.getID());
557 input.setTenantID(target.getTenantID());
559 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
560 if (instances != null) {
561 if (instances.length > 0) {
562 for (Object instance : instances) {
563 INeutronRouterAware service = (INeutronRouterAware) instance;
564 int status = service.canDetachInterface(target, input);
565 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
566 return Response.status(status).build();
570 throw new ServiceUnavailableException(NO_PROVIDERS);
573 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
576 // reset the port ownership
577 port.setDeviceID(null);
578 port.setDeviceOwner(null);
580 target.removeInterface(input.getPortUUID());
581 if (instances != null) {
582 for (Object instance : instances) {
583 INeutronRouterAware service = (INeutronRouterAware) instance;
584 service.neutronRouterInterfaceDetached(target, input);
587 return Response.status(HttpURLConnection.HTTP_OK).entity(input).build();
591 * remove by port id. collect information about the impacted router for the response
592 * remove the interface and reset the port ownership
594 if (input.getPortUUID() != null &&
595 input.getSubnetUUID() == null) {
596 NeutronRouter_Interface targetInterface = target.getInterfaces().get(input.getPortUUID());
597 if (targetInterface == null) {
598 throw new ResourceNotFoundException("Router interface not found for given Port UUID");
600 input.setSubnetUUID(targetInterface.getSubnetUUID());
601 input.setID(target.getID());
602 input.setTenantID(target.getTenantID());
603 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
604 if (instances != null) {
605 if (instances.length > 0) {
606 for (Object instance : instances) {
607 INeutronRouterAware service = (INeutronRouterAware) instance;
608 int status = service.canDetachInterface(target, input);
609 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
610 return Response.status(status).build();
614 throw new ServiceUnavailableException(NO_PROVIDERS);
617 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
619 NeutronPort port = portInterface.getPort(input.getPortUUID());
620 port.setDeviceID(null);
621 port.setDeviceOwner(null);
622 target.removeInterface(input.getPortUUID());
623 for (Object instance : instances) {
624 INeutronRouterAware service = (INeutronRouterAware) instance;
625 service.neutronRouterInterfaceDetached(target, input);
627 return Response.status(HttpURLConnection.HTTP_OK).entity(input).build();
631 * remove by both port and subnet ID. Verify that the first fixed IP of the port is a valid
632 * IP address for the subnet, and then remove the interface, collecting information about the
633 * impacted router for the response and reset port ownership
635 if (input.getPortUUID() != null &&
636 input.getSubnetUUID() != null) {
637 NeutronPort port = portInterface.getPort(input.getPortUUID());
639 throw new ResourceNotFoundException("Port UUID not found");
641 if (port.getFixedIPs() == null) {
642 throw new ResourceNotFoundException("Port UUID has no fixed IPs");
644 NeutronSubnet subnet = subnetInterface.getSubnet(input.getSubnetUUID());
645 if (subnet == null) {
646 throw new ResourceNotFoundException("Subnet UUID not found");
648 if (!subnet.isValidIP(port.getFixedIPs().get(0).getIpAddress())) {
649 throw new ResourceConflictException("Target Port IP not in Target Subnet");
651 Object[] instances = NeutronUtil.getInstances(INeutronRouterAware.class, this);
652 if (instances != null) {
653 if (instances.length > 0) {
654 for (Object instance : instances) {
655 INeutronRouterAware service = (INeutronRouterAware) instance;
656 int status = service.canDetachInterface(target, input);
657 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
658 return Response.status(status).build();
662 throw new ServiceUnavailableException(NO_PROVIDERS);
665 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
667 input.setID(target.getID());
668 input.setTenantID(target.getTenantID());
669 port.setDeviceID(null);
670 port.setDeviceOwner(null);
671 target.removeInterface(input.getPortUUID());
672 if (instances != null) {
673 for (Object instance : instances) {
674 INeutronRouterAware service = (INeutronRouterAware) instance;
675 service.canDetachInterface(target, input);
677 } for (Object instance : instances) {
678 INeutronRouterAware service = (INeutronRouterAware) instance;
679 service.neutronRouterInterfaceDetached(target, input);
681 return Response.status(HttpURLConnection.HTTP_OK).entity(input).build();
684 // have to specify either a port ID or a subnet ID
685 throw new BadRequestException("Must specify port id or subnet id or both");