3 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
5 * This program and the accompanying materials are made available under the
6 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7 * and is available at http://www.eclipse.org/legal/epl-v10.html
10 package org.opendaylight.controller.containermanager.northbound;
12 import java.util.ArrayList;
13 import java.util.HashSet;
14 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.PUT;
21 import javax.ws.rs.Path;
22 import javax.ws.rs.PathParam;
23 import javax.ws.rs.Produces;
24 import javax.ws.rs.QueryParam;
25 import javax.ws.rs.core.Context;
26 import javax.ws.rs.core.MediaType;
27 import javax.ws.rs.core.Response;
28 import javax.ws.rs.core.SecurityContext;
29 import javax.ws.rs.core.UriInfo;
30 import javax.ws.rs.ext.ContextResolver;
32 import org.codehaus.enunciate.jaxrs.ResponseCode;
33 import org.codehaus.enunciate.jaxrs.StatusCodes;
34 import org.codehaus.enunciate.jaxrs.TypeHint;
35 import org.opendaylight.controller.containermanager.ContainerConfig;
36 import org.opendaylight.controller.containermanager.ContainerFlowConfig;
37 import org.opendaylight.controller.containermanager.IContainerAuthorization;
38 import org.opendaylight.controller.containermanager.IContainerManager;
39 import org.opendaylight.controller.northbound.commons.RestMessages;
40 import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
41 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
42 import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
43 import org.opendaylight.controller.northbound.commons.exception.ResourceForbiddenException;
44 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
45 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
46 import org.opendaylight.controller.northbound.commons.query.QueryContext;
47 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
48 import org.opendaylight.controller.sal.authorization.Privilege;
49 import org.opendaylight.controller.sal.authorization.UserLevel;
50 import org.opendaylight.controller.sal.utils.GlobalConstants;
51 import org.opendaylight.controller.sal.utils.ServiceHelper;
52 import org.opendaylight.controller.sal.utils.Status;
53 import org.opendaylight.controller.usermanager.IUserManager;
56 * Container Manager Northbound API
60 * Authentication scheme : <b>HTTP Basic</b><br>
61 * Authentication realm : <b>opendaylight</b><br>
62 * Transport : <b>HTTP and HTTPS</b><br>
64 * HTTPS Authentication is disabled by default. Administrator can enable it in
65 * tomcat-server.xml after adding a proper keystore / SSL certificate from a
66 * trusted authority.<br>
68 * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
72 public class ContainerManagerNorthbound {
73 private String username;
74 private QueryContext queryContext;
77 public void setQueryContext(ContextResolver<QueryContext> queryCtxResolver) {
78 if (queryCtxResolver != null) {
79 queryContext = queryCtxResolver.getContext(QueryContext.class);
84 public void setSecurityContext(SecurityContext context) {
85 if (context != null && context.getUserPrincipal() != null) {
86 username = context.getUserPrincipal().getName();
90 protected String getUserName() {
94 private IContainerManager getContainerManager() {
95 IContainerManager containerMgr = (IContainerManager) ServiceHelper.getGlobalInstance(IContainerManager.class, this);
96 if (containerMgr == null) {
97 throw new InternalServerErrorException(RestMessages.INTERNALERROR.toString());
102 private void handleNameMismatch(String name, String nameinURL) {
103 if (name == null || nameinURL == null) {
104 throw new BadRequestException(RestMessages.INVALIDJSON.toString());
107 if (name.equalsIgnoreCase(nameinURL)) {
110 throw new BadRequestException(RestMessages.INVALIDJSON.toString());
116 * Get all the containers configured in the system
118 * @return a List of all {@link org.opendaylight.controller.containermanager.ContainerConfig}
125 * http://localhost:8080/controller/nb/v2/containermanager/containers
127 * Response body in XML:
128 * <containerConfig-list>
129 *    <containerConfig>
130 *       <container>black</container>
131 *       <staticVlan>10</staticVlan>
132 *       <nodeConnectors>OF|1@OF|00:00:00:00:00:00:00:01</nodeConnectors>
133 *       <nodeConnectors>OF|23@OF|00:00:00:00:00:00:20:21</nodeConnectors>
134 *       <flowSpecs>
135 *        <name>tcp</name>
136 *        <protocol>TCP</protocol>
137 *       </flowSpecs>
138 *     </containerConfig>
139 *     <containerConfig>
140 *       <container>red</container>
141 *       <staticVlan>20</staticVlan>
142 *       <nodeConnectors>OF|1@OF|00:00:00:00:00:00:00:01</nodeConnectors>
143 *       <nodeConnectors>OF|23@OF|00:00:00:00:00:00:20:21</nodeConnectors>
144 *       <flowSpecs>
145 *        <name>udp</name>
146 *        <protocol>UDP</protocol>
147 *       </flowSpecs>
148 *     </containerConfig>
149 * </containerConfig-list>
151 * Response body in JSON:
152 * { "containerConfig" : [
153 * { "container" : "black",
154 * "nodeConnectors" : [
155 * "OF|1@OF|00:00:00:00:00:00:00:01", "OF|23@OF|00:00:00:00:00:00:20:21"
157 * "staticVlan" : "10",
160 * "protocol": "UDP" }
163 * { "container" : "red",
164 * "nodeConnectors" : [
165 * "OF|1@OF|00:00:00:00:00:00:00:01",
166 * "OF|23@OF|00:00:00:00:00:00:20:21"
168 * "staticVlan" : "20",
181 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
182 @TypeHint(ContainerConfigs.class)
183 @StatusCodes({ @ResponseCode(code = 200, condition = "Operation successful"),
184 @ResponseCode(code = 401, condition = "User is not authorized to perform this operation"),
185 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
186 public ContainerConfigs viewAllContainers(@QueryParam("_q") String queryString) {
188 handleNetworkAuthorization(getUserName());
190 IContainerManager containerManager = getContainerManager();
191 ContainerConfigs result = new ContainerConfigs(
192 containerManager.getContainerConfigList());
193 if (queryString != null) {
194 queryContext.createQuery(queryString, ContainerConfigs.class)
195 .filter(result, ContainerConfig.class);
201 * Get the container configuration for container name requested
204 * name of the Container (eg. blue)
205 * @return a List of {@link org.opendaylight.controller.containermanager.ContainerConfig}
212 * http://localhost:8080/controller/nb/v2/containermanager/container/blue
214 * Response body in XML:
215 * <containerConfig>
216 *     <container>blue</container>
217 *     <staticVlan>10</staticVlan>
218 *     <nodeConnectors>OF|1@OF|00:00:00:00:00:00:00:01</nodeConnectors>
219 *     <nodeConnectors>OF|23@OF|00:00:00:00:00:00:20:21</nodeConnectors>
220 * </containerConfig>
222 * Response body in JSON:
224 * "containerConfig": [
226 * "container": "yellow",
227 * "staticVlan": "10",
228 * "nodeConnectors": [
229 * "OF|1@OF|00:00:00:00:00:00:00:01",
230 * "OF|2@OF|00:00:00:00:00:00:00:02"
238 @Path("/container/{container}")
240 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
241 @TypeHint(ContainerConfig.class)
242 @StatusCodes({ @ResponseCode(code = 200, condition = "Operation successful"),
243 @ResponseCode(code = 401, condition = "User is not authorized to perform this operation"),
244 @ResponseCode(code = 403, condition = "Operation forbidden on default"),
245 @ResponseCode(code = 404, condition = "The container is not found") })
246 public ContainerConfigs viewContainer(@PathParam(value = "container") String container) {
248 handleContainerAuthorization(container, getUserName());
249 handleForbiddenOnDefault(container);
251 handleContainerNotExists(container);
253 IContainerManager containerManager = getContainerManager();
254 List<ContainerConfig> containerConfigs = new ArrayList<ContainerConfig>();
255 containerConfigs.add(containerManager.getContainerConfig(container));
256 return new ContainerConfigs(containerConfigs);
264 * name of the Container (eg. yellow)
265 * @param containerConfig
266 * details of the container as specified by:
267 * {@link org.opendaylight.controller.containermanager.ContainerConfig}
268 * @return Response as dictated by the HTTP Response Status code
275 * http://localhost:8080/controller/nb/v2/containermanager/container/yellow
277 * Request body in XML:
278 * <containerConfig>
279 *     <container>yellow</container>
280 *     <staticVlan>10</staticVlan>
281 *     <nodeConnectors></nodeConnectors>
282 * </containerConfig>
284 * Request body in JSON:
286 * "container" : "yellow",
287 * "nodeConnectors" : [
288 * "OF|1@OF|00:00:00:00:00:00:00:01",
289 * "OF|23@OF|00:00:00:00:00:00:20:21"
291 * "staticVlan" : "10"
296 @Path("/container/{container}")
298 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
299 @StatusCodes({ @ResponseCode(code = 201, condition = "Container created successfully"),
300 @ResponseCode(code = 400, condition = "Invalid Container configuration."),
301 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
302 @ResponseCode(code = 403, condition = "Operation forbidden on default"),
303 @ResponseCode(code = 404, condition = "Container Name is not found"),
304 @ResponseCode(code = 409, condition = "Failed to create Container due to Conflicting Name"),
305 @ResponseCode(code = 500, condition = "Failure Reason included in HTTP Error response") })
306 public Response createContainer(@Context UriInfo uriInfo,
307 @PathParam(value = "container") String container,
308 @TypeHint(ContainerConfig.class) ContainerConfig containerConfig) {
310 handleAdminAuthorization(getUserName());
311 handleContainerExists(container);
313 handleNameMismatch(containerConfig.getContainerName(), container);
314 handleForbiddenOnDefault(container);
316 IContainerManager containerManager = getContainerManager();
317 Status status = containerManager.addContainer(containerConfig);
318 if (status.isSuccess()) {
319 NorthboundUtils.auditlog("Container", username, "added", container);
320 return Response.created(uriInfo.getRequestUri()).build();
322 return NorthboundUtils.getResponse(status);
329 * name of the Container (eg. green)
330 * @return Response as dictated by the HTTP Response code
337 * http://localhost:8080/controller/nb/v2/containermanager/container/green
341 @Path("/container/{container}")
344 @ResponseCode(code = 204, condition = "Container deleted successfully"),
345 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
346 @ResponseCode(code = 403, condition = "Operation forbidden on default"),
347 @ResponseCode(code = 404, condition = "The container is not found") })
348 public Response removeContainer(@PathParam(value = "container") String container) {
350 handleAdminAuthorization(getUserName());
351 handleForbiddenOnDefault(container);
352 handleContainerNotExists(container);
353 IContainerManager containerManager = getContainerManager();
354 Status status = containerManager.removeContainer(container);
355 if (status.isSuccess()) {
356 NorthboundUtils.auditlog("Container", username, "removed", container);
357 return Response.noContent().build();
359 return NorthboundUtils.getResponse(status);
363 * Get flowspec within a given container
366 * name of the Container (eg. green)
368 * name of the flowspec (eg. ssh)
369 * @return flowspec detail as specified by:
370 * {@link org.opendaylight.controller.containermanager.ContainerFlowConfig}
377 * http://localhost:8080/controller/nb/v2/containermanager/container/green/flowspec/ssh
379 * Response body in XML:
380 * <flow-spec-config>
381 *     <name>ssh</name>
382 *     <dlVlan>52</dlVlan>
383 *     <nwSrc>10.0.0.101</nwSrc>
384 *     <nwDst>10.0.0.102</nwDst>
385 *     <protocol>IPv4</protocol>
386 *     <tpSrc>80</tpSrc>
387 *     <tpDst>100</tpDst>
388 * </flow-spec-config>
390 * Response body in JSON:
392 * "protocol" : "IPv4",
394 * "nwDst" : "10.0.0.102",
396 * "nwSrc" : "10.0.0.101",
403 @Path("/container/{container}/flowspec/{flowspec}")
405 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
406 @TypeHint(ContainerFlowConfig.class)
407 @StatusCodes({ @ResponseCode(code = 200, condition = "Operation successful"),
408 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
409 @ResponseCode(code = 404, condition = "The container is not found"),
410 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
411 public ContainerFlowConfig viewContainerFlowSpec(@PathParam(value = "container") String container,
412 @PathParam(value = "flowspec") String flowspec) {
414 handleContainerAuthorization(container, getUserName());
415 handleForbiddenOnDefault(container);
417 handleContainerNotExists(container);
418 IContainerManager containerManager = getContainerManager();
419 List<ContainerFlowConfig> flowSpecs = containerManager.getContainerFlows(container);
421 for (ContainerFlowConfig containerFlowConfig : flowSpecs) {
422 if (containerFlowConfig.equalsByName(flowspec)) {
423 return containerFlowConfig;
426 throw new ResourceNotFoundException("Flow Spec not found");
430 * Get all the flowspec in a given container
433 * name of the Container (eg. red)
434 * @return list of all flowspec configured for a container. Flowspec as
436 * {@link org.opendaylight.controller.containermanager.ContainerFlowConfig}
443 * http://localhost:8080/controller/nb/v2/containermanager/container/red/flowspec
445 * Response body in XML:
446 * <flow-spec-configs>
447 *     <flow-spec-config>
448 *       <name>ssh</name>
449 *       <dlVlan>52</dlVlan>
450 *       <nwSrc>10.0.0.101</nwSrc>
451 *       <nwDst>10.0.0.102</nwDst>
452 *       <protocol>IPv4</protocol>
453 *       <tpSrc>23</tpSrc>
454 *       <tpDst>100</tpDst>
455 *     </flow-spec-config>
456 *     <flow-spec-config>
457 *       <name>http2</name>
458 *       <dlVlan>123</dlVlan>
459 *       <nwSrc>10.0.0.201</nwSrc>
460 *       <nwDst>10.0.0.202</nwDst>
461 *       <protocol></protocol>
462 *       <tpSrc>80</tpSrc>
463 *       <tpDst>100</tpDst>
464 *     </flow-spec-config>
465 * </flow-spec-configs>
467 * Response body in JSON:
469 * "flow-spec-config": [
473 * "nwSrc": "10.0.0.201",
474 * "nwDst": "10.0.0.202",
482 * "nwSrc": "10.0.0.101",
483 * "nwDst": "10.0.0.102",
484 * "protocol": "IPv4",
493 @Path("/container/{container}/flowspecs")
495 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
496 @TypeHint(FlowSpecConfigs.class)
497 @StatusCodes({ @ResponseCode(code = 200, condition = "Operation successful"),
498 @ResponseCode(code = 404, condition = "The container is not found"),
499 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
500 public FlowSpecConfigs viewContainerFlowSpecs(@PathParam(value = "container") String container,
501 @QueryParam("_q") String queryString) {
503 handleContainerAuthorization(container, getUserName());
504 handleForbiddenOnDefault(container);
506 handleContainerNotExists(container);
508 IContainerManager containerManager = getContainerManager();
509 FlowSpecConfigs result = new FlowSpecConfigs(
510 containerManager.getContainerFlows(container));
511 if (queryString != null) {
512 queryContext.createQuery(queryString, FlowSpecConfigs.class)
513 .filter(result, ContainerFlowConfig.class);
519 * Add flowspec to a container
522 * name of the container (eg. purple)
524 * name of the flowspec (eg. http)
526 * configuration as specified by:
527 * {@link org.opendaylight.controller.containermanager.ContainerFlowConfig}
529 * @return Response as dictated by the HTTP Response code
536 * http://localhost:8080/controller/nb/v2/containermanager/container/purple/flowspec/http
538 * Request body in XML:
539 * <flow-spec-config>
540 *     <name>http</name>
541 *     <dlVlan>25</dlVlan>
542 *     <nwSrc>10.0.0.101</nwSrc>
543 *     <nwDst>10.0.0.102</nwDst>
544 *     <protocol></protocol>
545 *     <tpSrc>80</tpSrc>
546 *     <tpDst>100</tpDst>
547 * </flow-spec-config>
549 * Request body in JSON:
553 * "nwSrc" : "10.0.0.101",
554 * "nwDst" : "10.0.0.102",
562 @Path("/container/{container}/flowspec/{flowspec}")
564 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
566 @ResponseCode(code = 201, condition = "FlowSpec created successfully"),
567 @ResponseCode(code = 400, condition = "Invalid flowspec configuration"),
568 @ResponseCode(code = 404, condition = "The container is not found"),
569 @ResponseCode(code = 409, condition = "Container Entry already exists"),
570 @ResponseCode(code = 500, condition = "Failed to create Flow specifications. Failure Reason included in HTTP Error response") })
571 public Response createFlowSpec(@Context UriInfo uriInfo,
572 @PathParam(value = "container") String container,
573 @PathParam(value = "flowspec") String flowspec,
574 @TypeHint(ContainerFlowConfig.class) ContainerFlowConfig containerFlowConfig) {
576 handleAdminAuthorization(getUserName());
577 handleForbiddenOnDefault(container);
579 handleContainerNotExists(container);
580 handleNameMismatch(containerFlowConfig.getName(), flowspec);
582 IContainerManager containerManager = getContainerManager();
583 List<ContainerFlowConfig> list = new ArrayList<ContainerFlowConfig>();
584 list.add(containerFlowConfig);
585 Status status = containerManager.addContainerFlows(container, list);
586 if (status.isSuccess()) {
587 NorthboundUtils.auditlog("Flow Spec", username, "added", containerFlowConfig.getName());
588 return Response.created(uriInfo.getRequestUri()).build();
590 return NorthboundUtils.getResponse(status);
594 * Remove flowspec from a container
597 * name of the flowspec (eg. telnet)
599 * name of the Container (eg. black)
600 * @return Response as dictated by the HTTP Response code
607 * http://localhost:8080/controller/nb/v2/containermanager/container/black/flowspec/telnet
611 @Path("/container/{container}/flowspec/{flowspec}")
614 @ResponseCode(code = 204, condition = "Flow Spec deleted successfully"),
615 @ResponseCode(code = 400, condition = "Invalid flowspec configuration"),
616 @ResponseCode(code = 404, condition = "Container or Container Entry not found"),
617 @ResponseCode(code = 406, condition = "Cannot operate on Default Container when other Containers are active"),
618 @ResponseCode(code = 500, condition = "Failed to delete Flowspec. Failure Reason included in HTTP Error response"),
619 @ResponseCode(code = 503, condition = "One or more of Controller service is unavailable") })
620 public Response removeFlowSpec(@PathParam(value = "container") String container,
621 @PathParam(value = "flowspec") String flowspec) {
623 handleAdminAuthorization(getUserName());
624 handleForbiddenOnDefault(container);
626 handleContainerNotExists(container);
628 IContainerManager containerManager = getContainerManager();
629 Set<String> set = new HashSet<String>();
631 Status status = containerManager.removeContainerFlows(container, set);
632 if (status.isSuccess()) {
633 NorthboundUtils.auditlog("Flow Spec", username, "added", flowspec);
634 return Response.noContent().build();
636 return NorthboundUtils.getResponse(status);
640 * Add node connectors to a container
643 * name of the container (eg. green)
645 * The list of strings each representing a node connector in the form "<Port Type>|<Port id>@<Node Type>|<Node id>", as "OF|1@OF|00:00:00:ab:00:00:00:01"
646 * @return response as dictated by the HTTP Status code
653 * http://localhost:8080/controller/nb/v2/containermanager/container/green/nodeconnector
655 * Request body in XML:
656 * <nodeConnectors>
657 * <nodeConnectors>OF|1@OF|00:00:00:00:00:00:00:01</nodeConnectors>
658 * <nodeConnectors>OF|2@OF|00:00:00:00:00:00:00:01</nodeConnectors>
659 * <nodeConnectors>OF|3@OF|00:00:00:00:00:00:00:22</nodeConnectors>
660 * <nodeConnectors>OF|4@OF|00:00:00:00:00:00:00:22</nodeConnectors>
661 * </nodeConnectors>
663 * Request body in JSON:
665 * "nodeConnectors" : [
666 * "OF|1@OF|00:00:00:00:00:00:00:01",
667 * "OF|2@OF|00:00:00:00:00:00:00:01",
668 * "OF|3@OF|00:00:00:00:00:00:00:22",
669 * "OF|4@OF|00:00:00:00:00:00:00:22"
675 @Path("/container/{container}/nodeconnector/")
677 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
678 @TypeHint(Response.class)
680 @ResponseCode(code = 200, condition = "NodeConnectors added successfully"),
681 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
682 @ResponseCode(code = 403, condition = "Operation forbidden on default"),
683 @ResponseCode(code = 404, condition = "The Container is not found"),
684 @ResponseCode(code = 409, condition = "Container Entry already exists"),
685 @ResponseCode(code = 500, condition = "Failed to create nodeconnectors. Failure Reason included in HTTP Error response") })
686 public Response addNodeConnectors(@PathParam(value = "container") String container,
687 @TypeHint(StringList.class) StringList list) {
689 handleAdminAuthorization(getUserName());
690 handleForbiddenOnDefault(container);
691 handleContainerNotExists(container);
693 IContainerManager containerManager = getContainerManager();
694 Status status = containerManager.addContainerEntry(container, list.getList());
695 if (status.isSuccess()) {
696 NorthboundUtils.auditlog("Node ", username, "added", " Ports:" + list.getList());
698 return NorthboundUtils.getResponse(status);
702 * Remove node connectors from a container
705 * name of the container (eg. red)
707 * The list of strings each representing a node connector in the form "<Port Type>|<Port id>@<Node Type>|<Node id>", as "OF|1@OF|00:00:00:ab:00:00:00:01"
708 * @return response as dictated by the HTTP Status code
715 * http://localhost:8080/controller/nb/v2/containermanager/container/red/nodeconnector
717 * Request body in XML:
718 * <nodeConnectors>
719 * <nodeConnectors>OF|1@OF|00:00:00:00:00:00:00:01</nodeConnectors>
720 * <nodeConnectors>OF|2@OF|00:00:00:00:00:00:00:01</nodeConnectors>
721 * <nodeConnectors>OF|3@OF|00:00:00:00:00:00:00:22</nodeConnectors>
722 * <nodeConnectors>OF|4@OF|00:00:00:00:00:00:00:22</nodeConnectors>
723 * </nodeConnectors>
725 * Request body in JSON:
727 * "nodeConnectors" : [
728 * "OF|1@OF|00:00:00:00:00:00:00:01",
729 * "OF|2@OF|00:00:00:00:00:00:00:01",
730 * "OF|3@OF|00:00:00:00:00:00:00:22",
731 * "OF|4@OF|00:00:00:00:00:00:00:22"
737 @Path("/container/{container}/nodeconnector/")
739 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
741 @ResponseCode(code = 204, condition = "Container Entry deleted successfully"),
742 @ResponseCode(code = 400, condition = "Invalid Container Entry configuration"),
743 @ResponseCode(code = 404, condition = "The Container is not found"),
744 @ResponseCode(code = 406, condition = "Cannot operate on Default Container when other Containers are active"),
745 @ResponseCode(code = 500, condition = "Failed to delete node connector. Failure Reason included in HTTP Error response") })
746 public Response removeNodeConnectors(@PathParam(value = "container") String container,
747 @TypeHint(StringList.class) StringList portList) {
749 handleAdminAuthorization(getUserName());
750 handleForbiddenOnDefault(container);
751 handleContainerNotExists(container);
753 IContainerManager containerManager = getContainerManager();
754 Status status = containerManager.removeContainerEntry(container, portList.getList());
755 if (status.isSuccess()) {
756 NorthboundUtils.auditlog("Node", username, "removed", " Ports:" + portList.getList());
757 return Response.noContent().build();
759 return NorthboundUtils.getResponse(status);
763 * Check If the function is not allowed on default container, Throw a
764 * ResourceForbiddenException exception if forbidden
766 private void handleForbiddenOnDefault(String container) {
767 if (container.equalsIgnoreCase(GlobalConstants.DEFAULT.toString())) {
768 throw new ResourceForbiddenException(RestMessages.NODEFAULT.toString() + ": " + container);
773 * Check if container exists, Throw a ResourceNotFoundException exception if it
776 private void handleContainerNotExists(String container) {
777 IContainerManager containerManager = getContainerManager();
778 if (!containerManager.doesContainerExist(container)) {
779 throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString() + ": " + container);
783 private void handleContainerExists(String container) {
784 IContainerManager containerManager = getContainerManager();
785 if (containerManager.doesContainerExist(container)) {
786 throw new ResourceConflictException(RestMessages.RESOURCECONFLICT.toString() + ": " + container);
790 private void handleAdminAuthorization(String userName) {
791 IUserManager usrMgr = (IUserManager) ServiceHelper.getGlobalInstance(IUserManager.class, this);
793 UserLevel level = usrMgr.getUserLevel(userName);
794 if (level.ordinal() <= UserLevel.NETWORKADMIN.ordinal()) {
798 throw new UnauthorizedException("User is not authorized to perform this operation");
801 private void handleNetworkAuthorization(String userName) {
802 IUserManager usrMgr = (IUserManager) ServiceHelper.getGlobalInstance(IUserManager.class, this);
804 UserLevel level = usrMgr.getUserLevel(userName);
805 if (level.ordinal() <= UserLevel.NETWORKOPERATOR.ordinal()) {
808 throw new UnauthorizedException("User is not authorized to perform this operation");
811 private void handleContainerAuthorization(String container, String userName) {
812 IContainerAuthorization auth = (IContainerAuthorization) ServiceHelper.getGlobalInstance(
813 IContainerAuthorization.class, this);
815 UserLevel level = auth.getUserLevel(userName);
816 if (level.ordinal() <= UserLevel.NETWORKOPERATOR.ordinal()) {
820 Privilege current = (auth == null) ? Privilege.NONE : auth.getResourcePrivilege(userName, container);
822 if (current.ordinal() > Privilege.NONE.ordinal()) {
825 throw new UnauthorizedException("User is not authorized to perform this operation");