2 * Copyright (c) 2013 Cisco Systems, Inc. and others. 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.controller.switchmanager.northbound;
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.List;
18 import javax.ws.rs.Consumes;
19 import javax.ws.rs.DELETE;
20 import javax.ws.rs.GET;
21 import javax.ws.rs.POST;
22 import javax.ws.rs.PUT;
23 import javax.ws.rs.Path;
24 import javax.ws.rs.PathParam;
25 import javax.ws.rs.Produces;
26 import javax.ws.rs.core.Context;
27 import javax.ws.rs.core.MediaType;
28 import javax.ws.rs.core.Response;
29 import javax.ws.rs.core.SecurityContext;
30 import javax.ws.rs.core.UriInfo;
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.IContainerManager;
36 import org.opendaylight.controller.northbound.commons.RestMessages;
37 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
38 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
39 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
40 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
41 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
42 import org.opendaylight.controller.sal.authorization.Privilege;
43 import org.opendaylight.controller.sal.core.Node;
44 import org.opendaylight.controller.sal.core.NodeConnector;
45 import org.opendaylight.controller.sal.core.Property;
46 import org.opendaylight.controller.sal.utils.GlobalConstants;
47 import org.opendaylight.controller.sal.utils.ServiceHelper;
48 import org.opendaylight.controller.sal.utils.Status;
49 import org.opendaylight.controller.sal.utils.StatusCode;
50 import org.opendaylight.controller.switchmanager.ISwitchManager;
51 import org.opendaylight.controller.switchmanager.SwitchConfig;
54 * The class provides Northbound REST APIs to access the nodes, node connectors
55 * and their properties.
60 public class SwitchNorthbound {
62 private String username;
65 public void setSecurityContext(SecurityContext context) {
66 if (context != null && context.getUserPrincipal() != null) username = context.getUserPrincipal().getName();
69 protected String getUserName() {
73 private ISwitchManager getIfSwitchManagerService(String containerName) {
74 IContainerManager containerManager = (IContainerManager) ServiceHelper
75 .getGlobalInstance(IContainerManager.class, this);
76 if (containerManager == null) {
77 throw new ServiceUnavailableException("Container "
78 + RestMessages.SERVICEUNAVAILABLE.toString());
81 boolean found = false;
82 List<String> containerNames = containerManager.getContainerNames();
83 for (String cName : containerNames) {
84 if (cName.trim().equalsIgnoreCase(containerName.trim())) {
91 throw new ResourceNotFoundException(containerName + " "
92 + RestMessages.NOCONTAINER.toString());
95 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
96 .getInstance(ISwitchManager.class, containerName, this);
98 if (switchManager == null) {
99 throw new ServiceUnavailableException("Switch Manager "
100 + RestMessages.SERVICEUNAVAILABLE.toString());
103 return switchManager;
108 * Retrieve a list of all the nodes and their properties in the network
110 * @param containerName
111 * Name of the Container (Eg. 'default')
112 * @return A list of Pair each pair represents a
113 * {@link org.opendaylight.controller.sal.core.Node} and Set of
114 * {@link org.opendaylight.controller.sal.core.Property} attached to
122 * http://localhost:8080/controller/nb/v2/switch/default/nodes
125 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
127 *    <nodeProperties>
128 *       <node>
129 *          <id>00:00:00:00:00:00:00:02</id>
130 *          <type>OF</type>
131 *       </node>
132 *       <properties>
133 *          <tables>
134 *             <value>-1</value>
135 *          </tables>
136 *          <description>
137 *             <value>Switch2</value>
138 *          </description>
139 *          <actions>
140 *             <value>4095</value>
141 *          </actions>
142 *          <macAddress>
143 *             <value>00:00:00:00:00:02</value>
144 *          </macAddress>
145 *          <capabilities>
146 *             <value>199</value>
147 *          </capabilities>
148 *          <timeStamp>
149 *             <value>1377291227877</value>
150 *             <name>connectedSince</name>
151 *          </timeStamp>
152 *          <buffers>
153 *             <value>256</value>
154 *          </buffers>
155 *       </properties>
156 *    </nodeProperties>
160 * {"nodeProperties":[{"node":{"id":"00:00:00:00:00:00:00:02","type":"OF"},"properties":{"tables":{"value":"-1"},
161 * "description":{"value":"None"},"actions":{"value":"4095"},"macAddress":{"value":"00:00:00:00:00:02"},"capabilities"
162 * :{"value":"199"},"timeStamp":{"value":"1377291227877","name":"connectedSince"},"buffers":{"value":"256"}}}]}
166 @Path("/{containerName}/nodes")
168 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
169 @TypeHint(Nodes.class)
171 @ResponseCode(code = 200, condition = "Operation successful"),
172 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
173 @ResponseCode(code = 404, condition = "The containerName is not found"),
174 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
175 public Nodes getNodes(@PathParam("containerName") String containerName) {
177 if (!isValidContainer(containerName)) {
178 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
181 if (!NorthboundUtils.isAuthorized(
182 getUserName(), containerName, Privilege.READ, this)) {
183 throw new UnauthorizedException(
184 "User is not authorized to perform this operation on container "
188 ISwitchManager switchManager = getIfSwitchManagerService(containerName);
189 if (switchManager == null) {
190 throw new ServiceUnavailableException("Switch Manager "
191 + RestMessages.SERVICEUNAVAILABLE.toString());
194 List<NodeProperties> res = new ArrayList<NodeProperties>();
195 Set<Node> nodes = switchManager.getNodes();
200 for (Node node : nodes) {
201 Map<String, Property> propMap = switchManager.getNodeProps(node);
202 if (propMap == null) {
205 Set<Property> props = new HashSet<Property>(propMap.values());
207 NodeProperties nodeProps = new NodeProperties(node, props);
211 return new Nodes(res);
215 * Add a Description, Tier and Forwarding mode property to a node.
217 * @param containerName
218 * Name of the Container (Eg. 'default')
220 * Type of the node being programmed (Eg. 'OF')
222 * Node Identifier as specified by
223 * {@link org.opendaylight.controller.sal.core.Node}
224 * (Eg. '00:00:00:00:00:00:00:03')
225 * @param propertyName
226 * Name of the Property. Properties that can be
227 * configured are: description, forwarding(only for default
228 * container) and tier
229 * @param propertyValue
230 * Value of the Property. Description can be any string (Eg. 'Node1'),
231 * valid values for tier are 0, 1 and 2, and valid values for forwarding are 0 for
232 * reactive and 1 for proactive forwarding.
233 * @return Response as dictated by the HTTP Response Status code
240 * http://localhost:8080/controller/nb/v2/switch/default/node/OF/00:00:00:00:00:00:00:03/property/description/Switch3
245 @Path("/{containerName}/node/{nodeType}/{nodeId}/property/{propertyName}/{propertyValue}")
247 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
248 @TypeHint(Response.class)
250 @ResponseCode(code = 201, condition = "Operation successful"),
251 @ResponseCode(code = 400, condition = "The nodeId or configuration is invalid"),
252 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
253 @ResponseCode(code = 404, condition = "The Container Name or node or configuration name is not found"),
254 @ResponseCode(code = 406, condition = "The property cannot be configured in non-default container"),
255 @ResponseCode(code = 409, condition = "Unable to update configuration due to cluster conflict or conflicting description property"),
256 @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
257 public Response addNodeProperty(
258 @Context UriInfo uriInfo,
259 @PathParam("containerName") String containerName,
260 @PathParam("nodeType") String nodeType,
261 @PathParam("nodeId") String nodeId,
262 @PathParam("propertyName") String propertyName,
263 @PathParam("propertyValue") String propertyValue) {
265 if (!isValidContainer(containerName)) {
266 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
268 if (!NorthboundUtils.isAuthorized(
269 getUserName(), containerName, Privilege.WRITE, this)) {
270 throw new UnauthorizedException(
271 "User is not authorized to perform this operation on container "
274 ISwitchManager switchManager = getIfSwitchManagerService(containerName);
275 if (switchManager == null) {
276 throw new ServiceUnavailableException("Switch Manager "
277 + RestMessages.SERVICEUNAVAILABLE.toString());
280 handleNodeAvailability(containerName, nodeType, nodeId);
281 Node node = Node.fromString(nodeType, nodeId);
282 Property prop = switchManager.createProperty(propertyName, propertyValue);
284 throw new ResourceNotFoundException("Property with name " + propertyName + " does not exist.");
286 SwitchConfig switchConfig = switchManager.getSwitchConfig(node.toString());
287 Map<String, Property> nodeProperties = (switchConfig == null) ? new HashMap<String, Property>()
288 : new HashMap<String, Property>(switchConfig.getNodeProperties());
289 nodeProperties.put(prop.getName(), prop);
290 SwitchConfig newSwitchConfig = new SwitchConfig(node.toString(), nodeProperties);
291 Status status = switchManager.updateNodeConfig(newSwitchConfig);
292 if (status.isSuccess()) {
293 return Response.created(uriInfo.getRequestUri()).build();
295 return NorthboundUtils.getResponse(status);
299 * Delete a property of a node
301 * @param containerName
302 * Name of the Container (Eg. 'SliceRed')
304 * Type of the node being programmed (Eg. 'OF')
306 * Node Identifier as specified by
307 * {@link org.opendaylight.controller.sal.core.Node}
308 * (Eg. '00:00:00:00:00:03:01:02')
309 * @param propertyName
310 * Name of the Property. Properties that can be deleted are
311 * description, forwarding(only in default container) and tier.
312 * @return Response as dictated by the HTTP Response Status code
319 * http://localhost:8080/controller/nb/v2/switch/default/node/OF/00:00:00:00:00:00:00:03/property/forwarding
324 @Path("/{containerName}/node/{nodeType}/{nodeId}/property/{propertyName}")
326 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
328 @ResponseCode(code = 200, condition = "Operation successful"),
329 @ResponseCode(code = 400, condition = "The nodeId or configuration is invalid"),
330 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
331 @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
332 @ResponseCode(code = 409, condition = "Unable to delete property due to cluster conflict"),
333 @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
334 public Response deleteNodeProperty(
335 @PathParam("containerName") String containerName,
336 @PathParam("nodeType") String nodeType,
337 @PathParam("nodeId") String nodeId,
338 @PathParam("propertyName") String propertyName) {
340 if (!isValidContainer(containerName)) {
341 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
343 if (!NorthboundUtils.isAuthorized(
344 getUserName(), containerName, Privilege.WRITE, this)) {
345 throw new UnauthorizedException(
346 "User is not authorized to perform this operation on container "
349 ISwitchManager switchManager = getIfSwitchManagerService(containerName);
350 if (switchManager == null) {
351 throw new ServiceUnavailableException("Switch Manager "
352 + RestMessages.SERVICEUNAVAILABLE.toString());
355 handleNodeAvailability(containerName, nodeType, nodeId);
356 Node node = Node.fromString(nodeType, nodeId);
358 SwitchConfig switchConfig = switchManager.getSwitchConfig(node.toString());
360 if (switchConfig == null) {
361 status = new Status(StatusCode.NOTFOUND, "Switch Configuration does not exist");
363 Map<String, Property> nodeProperties = new HashMap<String, Property>(switchConfig.getNodeProperties());
364 if (!nodeProperties.containsKey(propertyName.toLowerCase())) {
365 String msg = "Property " + propertyName + " does not exist or not configured for switch " + nodeId;
366 status = new Status(StatusCode.NOTFOUND, msg);
368 nodeProperties.remove(propertyName.toLowerCase());
369 SwitchConfig newSwitchConfig = new SwitchConfig(node.toString(), nodeProperties);
370 status = switchManager.updateNodeConfig(newSwitchConfig);
371 if(status.isSuccess()){
372 NorthboundUtils.auditlog("Static Route", username, "updated", nodeId, containerName);
376 return NorthboundUtils.getResponse(status);
381 * Retrieve a list of all the nodeconnectors and their properties in a given
384 * @param containerName
385 * The container for which we want to retrieve the list (Eg.
388 * Type of the node being programmed (Eg. 'OF')
390 * Node Identifier as specified by
391 * {@link org.opendaylight.controller.sal.core.Node} (Eg.
392 * '00:00:00:00:00:00:00:03')
393 * @return A List of Pair each pair represents a
394 * {@link org.opendaylight.controller.sal.core.NodeConnector} and
396 * {@link org.opendaylight.controller.sal.core.Property} attached to
404 * http://localhost:8080/controller/nb/v2/switch/default/node/OF/00:00:00:00:00:00:00:01
407 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
409 *    <nodeConnectorProperties>
410 *       <nodeconnector>
411 *          <node>
412 *             <id>00:00:00:00:00:00:00:01</id>
413 *             <type>OF</type>
414 *          </node>
415 *          <id>2</id>
416 *          <type>OF</type>
417 *       </nodeconnector>
418 *       <properties>
419 *          <state>
420 *             <value>1</value>
421 *          </state>
422 *          <config>
423 *             <value>1</value>
424 *          </config>
425 *          <name>
426 *             <value>L1_2-C2_1</value>
427 *          </name>
428 *       </properties>
429 *    </nodeConnectorProperties>
433 * {"nodeConnectorProperties":[{"nodeconnector":{"node":{"id":"00:00:00:00:00:00:00:01","type":"OF"},"id":"2","type":"OF"},
434 * "properties":{"state":{"value":"1"},"config":{"value":"1"},"name":{"value":"L1_2-C2_1"}}}]}
438 @Path("/{containerName}/node/{nodeType}/{nodeId}")
440 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
441 @TypeHint(NodeConnectors.class)
443 @ResponseCode(code = 200, condition = "Operation successful"),
444 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
445 @ResponseCode(code = 404, condition = "The containerName is not found"),
446 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
447 public NodeConnectors getNodeConnectors(
448 @PathParam("containerName") String containerName,
449 @PathParam("nodeType") String nodeType,
450 @PathParam("nodeId") String nodeId) {
452 if (!isValidContainer(containerName)) {
453 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
455 if (!NorthboundUtils.isAuthorized(
456 getUserName(), containerName, Privilege.READ, this)) {
457 throw new UnauthorizedException(
458 "User is not authorized to perform this operation on container "
462 ISwitchManager switchManager = getIfSwitchManagerService(containerName);
463 if (switchManager == null) {
464 throw new ServiceUnavailableException("Switch Manager "
465 + RestMessages.SERVICEUNAVAILABLE.toString());
468 handleNodeAvailability(containerName, nodeType, nodeId);
469 Node node = Node.fromString(nodeType, nodeId);
470 List<NodeConnectorProperties> res = new ArrayList<NodeConnectorProperties>();
471 Set<NodeConnector> ncs = switchManager.getNodeConnectors(node);
476 for (NodeConnector nc : ncs) {
477 Map<String, Property> propMap = switchManager
478 .getNodeConnectorProps(nc);
479 if (propMap == null) {
482 Set<Property> props = new HashSet<Property>(propMap.values());
483 NodeConnectorProperties ncProps = new NodeConnectorProperties(nc,
488 return new NodeConnectors(res);
492 * Add Bandwidth property to a node connector
494 * @param containerName
495 * Name of the Container (Eg. 'default')
497 * Type of the node being programmed (Eg. 'OF')
499 * Node Identifier as specified by
500 * {@link org.opendaylight.controller.sal.core.Node}
501 * (Eg. '00:00:00:00:00:00:00:03')
502 * @param nodeConnectorType
503 * Type of the node connector being programmed (Eg. 'OF')
504 * @param nodeConnectorId
505 * NodeConnector Identifier as specified by
506 * {@link org.opendaylight.controller.sal.core.NodeConnector}
508 * @param propertyName
509 * Name of the Property specified by
510 * {@link org.opendaylight.controller.sal.core.Property} and its
512 * Property that can be configured is bandwidth
513 * @param propertyValue
514 * Value of the Property specified by
515 * {@link org.opendaylight.controller.sal.core.Property} and its
517 * @return Response as dictated by the HTTP Response Status code
524 * http://localhost:8080/controller/nb/v2/switch/default/nodeconnector/OF/00:00:00:00:00:00:00:01/OF/2/property/bandwidth/1
529 @Path("/{containerName}/nodeconnector/{nodeType}/{nodeId}/{nodeConnectorType}/{nodeConnectorId}/property/{propertyName}/{propertyValue}")
531 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
533 @ResponseCode(code = 201, condition = "Operation successful"),
534 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
535 @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
536 @ResponseCode(code = 409, condition = "Unable to add property due to cluster conflict"),
537 @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
538 public Response addNodeConnectorProperty(
539 @Context UriInfo uriInfo,
540 @PathParam("containerName") String containerName,
541 @PathParam("nodeType") String nodeType,
542 @PathParam("nodeId") String nodeId,
543 @PathParam("nodeConnectorType") String nodeConnectorType,
544 @PathParam("nodeConnectorId") String nodeConnectorId,
545 @PathParam("propertyName") String propertyName,
546 @PathParam("propertyValue") String propertyValue) {
548 if (!isValidContainer(containerName)) {
549 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
551 if (!NorthboundUtils.isAuthorized(
552 getUserName(), containerName, Privilege.WRITE, this)) {
553 throw new UnauthorizedException(
554 "User is not authorized to perform this operation on container "
558 ISwitchManager switchManager = getIfSwitchManagerService(containerName);
559 if (switchManager == null) {
560 throw new ServiceUnavailableException("Switch Manager "
561 + RestMessages.SERVICEUNAVAILABLE.toString());
564 handleNodeAvailability(containerName, nodeType, nodeId);
565 Node node = Node.fromString(nodeType, nodeId);
567 handleNodeConnectorAvailability(containerName, node, nodeConnectorType,
569 NodeConnector nc = NodeConnector
570 .fromStringNoNode(nodeConnectorType, nodeConnectorId, node);
572 Property prop = switchManager.createProperty(propertyName, propertyValue);
574 throw new ResourceNotFoundException(
575 RestMessages.INVALIDDATA.toString());
578 Status ret = switchManager.addNodeConnectorProp(nc, prop);
579 if (ret.isSuccess()) {
580 return Response.created(uriInfo.getRequestUri()).build();
582 throw new InternalServerErrorException(ret.getDescription());
586 * Delete a property of a node connector
588 * @param containerName
589 * Name of the Container (Eg. 'default')
591 * Type of the node being programmed (Eg. 'OF')
593 * Node Identifier as specified by
594 * {@link org.opendaylight.controller.sal.core.Node}
595 * (Eg. '00:00:00:00:00:00:00:01')
596 * @param nodeConnectorType
597 * Type of the node connector being programmed (Eg. 'OF')
598 * @param nodeConnectorId
599 * NodeConnector Identifier as specified by
600 * {@link org.opendaylight.controller.sal.core.NodeConnector}
602 * @param propertyName
603 * Name of the Property specified by
604 * {@link org.opendaylight.controller.sal.core.Property} and its
605 * extended classes. Property that can be deleted is bandwidth
606 * @return Response as dictated by the HTTP Response Status code
613 * http://localhost:8080/controller/nb/v2/switch/default/nodeconnector/OF/00:00:00:00:00:00:00:01/OF/2/property/bandwidth
618 @Path("/{containerName}/nodeconnector/{nodeType}/{nodeId}/{nodeConnectorType}/{nodeConnectorId}/property/{propertyName}")
620 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
622 @ResponseCode(code = 200, condition = "Operation successful"),
623 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
624 @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
625 @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
626 public Response deleteNodeConnectorProperty(
627 @PathParam("containerName") String containerName,
628 @PathParam("nodeType") String nodeType,
629 @PathParam("nodeId") String nodeId,
630 @PathParam("nodeConnectorType") String nodeConnectorType,
631 @PathParam("nodeConnectorId") String nodeConnectorId,
632 @PathParam("propertyName") String propertyName) {
634 if (!isValidContainer(containerName)) {
635 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
637 if (!NorthboundUtils.isAuthorized(
638 getUserName(), containerName, Privilege.WRITE, this)) {
639 throw new UnauthorizedException(
640 "User is not authorized to perform this operation on container "
644 ISwitchManager switchManager = getIfSwitchManagerService(containerName);
645 if (switchManager == null) {
646 throw new ServiceUnavailableException("Switch Manager "
647 + RestMessages.SERVICEUNAVAILABLE.toString());
650 handleNodeAvailability(containerName, nodeType, nodeId);
651 Node node = Node.fromString(nodeType, nodeId);
653 handleNodeConnectorAvailability(containerName, node, nodeConnectorType,
655 NodeConnector nc = NodeConnector
656 .fromStringNoNode(nodeConnectorType, nodeConnectorId, node);
657 Status ret = switchManager.removeNodeConnectorProp(nc, propertyName);
658 if (ret.isSuccess()) {
659 NorthboundUtils.auditlog("Node Connector Property", username, "removed", nc + " from " + nodeConnectorId, containerName);
660 return Response.ok().build();
662 throw new ResourceNotFoundException(ret.getDescription());
666 * Save the current switch configurations
668 * @param containerName
669 * Name of the Container (Eg. 'default')
670 * @return Response as dictated by the HTTP Response Status code
677 * http://localhost:8080/controller/nb/v2/switch/default/switch-config
681 @Path("/{containerName}/switch-config")
683 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
685 @ResponseCode(code = 200, condition = "Operation successful"),
686 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
687 @ResponseCode(code = 404, condition = "The containerName is not found"),
688 @ResponseCode(code = 500, condition = "Failed to save switch configuration. Failure Reason included in HTTP Error response"),
689 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
690 public Response saveSwitchConfig(
691 @PathParam("containerName") String containerName) {
693 if (!isValidContainer(containerName)) {
694 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
696 if (!NorthboundUtils.isAuthorized(
697 getUserName(), containerName, Privilege.WRITE, this)) {
698 throw new UnauthorizedException(
699 "User is not authorized to perform this operation on container "
702 ISwitchManager switchManager = getIfSwitchManagerService(containerName);
703 if (switchManager == null) {
704 throw new ServiceUnavailableException("Switch Manager "
705 + RestMessages.SERVICEUNAVAILABLE.toString());
708 Status ret = switchManager.saveSwitchConfig();
709 if (ret.isSuccess()) {
710 return Response.ok().build();
712 throw new InternalServerErrorException(ret.getDescription());
715 private Node handleNodeAvailability(String containerName, String nodeType,
718 Node node = Node.fromString(nodeType, nodeId);
720 throw new ResourceNotFoundException(nodeId + " : "
721 + RestMessages.NONODE.toString());
724 ISwitchManager sm = (ISwitchManager) ServiceHelper.getInstance(
725 ISwitchManager.class, containerName, this);
728 throw new ServiceUnavailableException("Switch Manager "
729 + RestMessages.SERVICEUNAVAILABLE.toString());
732 if (!sm.getNodes().contains(node)) {
733 throw new ResourceNotFoundException(node.toString() + " : "
734 + RestMessages.NONODE.toString());
739 private void handleNodeConnectorAvailability(String containerName,
740 Node node, String nodeConnectorType, String nodeConnectorId) {
742 NodeConnector nc = NodeConnector.fromStringNoNode(nodeConnectorType,
743 nodeConnectorId, node);
745 throw new ResourceNotFoundException(nc + " : "
746 + RestMessages.NORESOURCE.toString());
749 ISwitchManager sm = (ISwitchManager) ServiceHelper.getInstance(
750 ISwitchManager.class, containerName, this);
753 throw new ServiceUnavailableException("Switch Manager "
754 + RestMessages.SERVICEUNAVAILABLE.toString());
757 if (!sm.getNodeConnectors(node).contains(nc)) {
758 throw new ResourceNotFoundException(nc.toString() + " : "
759 + RestMessages.NORESOURCE.toString());
763 private boolean isValidContainer(String containerName) {
764 if (containerName.equals(GlobalConstants.DEFAULT.toString())) {
767 IContainerManager containerManager = (IContainerManager) ServiceHelper
768 .getGlobalInstance(IContainerManager.class, this);
769 if (containerManager == null) {
770 throw new InternalServerErrorException(
771 RestMessages.INTERNALERROR.toString());
773 if (containerManager.getContainerNames().contains(containerName)) {