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) {
67 username = context.getUserPrincipal().getName();
71 protected String getUserName() {
75 private ISwitchManager getIfSwitchManagerService(String containerName) {
76 IContainerManager containerManager = (IContainerManager) ServiceHelper
77 .getGlobalInstance(IContainerManager.class, this);
78 if (containerManager == null) {
79 throw new ServiceUnavailableException("Container "
80 + RestMessages.SERVICEUNAVAILABLE.toString());
83 boolean found = false;
84 List<String> containerNames = containerManager.getContainerNames();
85 for (String cName : containerNames) {
86 if (cName.trim().equalsIgnoreCase(containerName.trim())) {
93 throw new ResourceNotFoundException(containerName + " "
94 + RestMessages.NOCONTAINER.toString());
97 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
98 .getInstance(ISwitchManager.class, containerName, this);
100 if (switchManager == null) {
101 throw new ServiceUnavailableException("Switch Manager "
102 + RestMessages.SERVICEUNAVAILABLE.toString());
105 return switchManager;
110 * Retrieve a list of all the nodes and their properties in the network
112 * @param containerName
113 * Name of the Container (Eg. 'default')
114 * @return A list of Pair each pair represents a
115 * {@link org.opendaylight.controller.sal.core.Node} and Set of
116 * {@link org.opendaylight.controller.sal.core.Property} attached to
124 * http://localhost:8080/controller/nb/v2/switchmanager/default/nodes
127 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
129 *    <nodeProperties>
130 *       <node>
131 *          <id>00:00:00:00:00:00:00:02</id>
132 *          <type>OF</type>
133 *       </node>
134 *       <properties>
135 *          <tables>
136 *             <value>-1</value>
137 *          </tables>
138 *          <description>
139 *             <value>Switch2</value>
140 *          </description>
141 *          <actions>
142 *             <value>4095</value>
143 *          </actions>
144 *          <macAddress>
145 *             <value>00:00:00:00:00:02</value>
146 *          </macAddress>
147 *          <capabilities>
148 *             <value>199</value>
149 *          </capabilities>
150 *          <timeStamp>
151 *             <value>1377291227877</value>
152 *             <name>connectedSince</name>
153 *          </timeStamp>
154 *          <buffers>
155 *             <value>256</value>
156 *          </buffers>
157 *       </properties>
158 *    </nodeProperties>
162 * {"nodeProperties":[{"node":{"id":"00:00:00:00:00:00:00:02","type":"OF"},"properties":{"tables":{"value":"-1"},
163 * "description":{"value":"None"},"actions":{"value":"4095"},"macAddress":{"value":"00:00:00:00:00:02"},"capabilities"
164 * :{"value":"199"},"timeStamp":{"value":"1377291227877","name":"connectedSince"},"buffers":{"value":"256"}}}]}
168 @Path("/{containerName}/nodes")
170 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
171 @TypeHint(Nodes.class)
173 @ResponseCode(code = 200, condition = "Operation successful"),
174 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
175 @ResponseCode(code = 404, condition = "The containerName is not found"),
176 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
177 public Nodes getNodes(@PathParam("containerName") String containerName) {
179 if (!isValidContainer(containerName)) {
180 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
183 if (!NorthboundUtils.isAuthorized(
184 getUserName(), containerName, Privilege.READ, this)) {
185 throw new UnauthorizedException(
186 "User is not authorized to perform this operation on container "
190 ISwitchManager switchManager = getIfSwitchManagerService(containerName);
191 if (switchManager == null) {
192 throw new ServiceUnavailableException("Switch Manager "
193 + RestMessages.SERVICEUNAVAILABLE.toString());
196 List<NodeProperties> res = new ArrayList<NodeProperties>();
197 Set<Node> nodes = switchManager.getNodes();
199 return new Nodes(res);
202 for (Node node : nodes) {
203 Map<String, Property> propMap = switchManager.getNodeProps(node);
204 if (propMap == null) {
207 Set<Property> props = new HashSet<Property>(propMap.values());
209 NodeProperties nodeProps = new NodeProperties(node, props);
213 return new Nodes(res);
217 * Add a Description, Tier and Forwarding mode property to a node. This
218 * method returns a non-successful response if a node by that name already
221 * @param containerName
222 * Name of the Container (Eg. 'default')
224 * Type of the node being programmed (Eg. 'OF')
226 * Node Identifier as specified by
227 * {@link org.opendaylight.controller.sal.core.Node} (Eg.
228 * '00:00:00:00:00:00:00:03')
229 * @param propertyName
230 * Name of the Property. Properties that can be configured are:
231 * description, forwarding(only for default container) and tier
232 * @param propertyValue
233 * Value of the Property. Description can be any string (Eg.
234 * 'Node1'), valid values for tier are non negative numbers, and
235 * valid values for forwarding are 0 for reactive and 1 for
236 * proactive forwarding.
237 * @return Response as dictated by the HTTP Response Status code
244 * http://localhost:8080/controller/nb/v2/switchmanager/default/node/OF/00:00:00:00:00:00:00:03/property/description/Switch3
249 @Path("/{containerName}/node/{nodeType}/{nodeId}/property/{propertyName}/{propertyValue}")
251 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
252 @TypeHint(Response.class)
254 @ResponseCode(code = 201, condition = "Operation successful"),
255 @ResponseCode(code = 400, condition = "The nodeId or configuration is invalid"),
256 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
257 @ResponseCode(code = 404, condition = "The Container Name or node or configuration name is not found"),
258 @ResponseCode(code = 406, condition = "The property cannot be configured in non-default container"),
259 @ResponseCode(code = 409, condition = "Unable to update configuration due to cluster conflict or conflicting description property"),
260 @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
261 public Response addNodeProperty(
262 @Context UriInfo uriInfo,
263 @PathParam("containerName") String containerName,
264 @PathParam("nodeType") String nodeType,
265 @PathParam("nodeId") String nodeId,
266 @PathParam("propertyName") String propertyName,
267 @PathParam("propertyValue") String propertyValue) {
269 if (!isValidContainer(containerName)) {
270 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
272 if (!NorthboundUtils.isAuthorized(
273 getUserName(), containerName, Privilege.WRITE, this)) {
274 throw new UnauthorizedException(
275 "User is not authorized to perform this operation on container "
278 ISwitchManager switchManager = getIfSwitchManagerService(containerName);
279 if (switchManager == null) {
280 throw new ServiceUnavailableException("Switch Manager "
281 + RestMessages.SERVICEUNAVAILABLE.toString());
284 handleNodeAvailability(containerName, nodeType, nodeId);
285 Node node = Node.fromString(nodeType, nodeId);
286 Property prop = switchManager.createProperty(propertyName, propertyValue);
288 throw new ResourceNotFoundException("Property with name " + propertyName + " does not exist.");
290 SwitchConfig switchConfig = switchManager.getSwitchConfig(node.toString());
291 Map<String, Property> nodeProperties = (switchConfig == null) ? new HashMap<String, Property>()
292 : new HashMap<String, Property>(switchConfig.getNodeProperties());
293 nodeProperties.put(prop.getName(), prop);
294 SwitchConfig newSwitchConfig = new SwitchConfig(node.toString(), nodeProperties);
295 Status status = switchManager.updateNodeConfig(newSwitchConfig);
296 if (status.isSuccess()) {
297 return Response.created(uriInfo.getRequestUri()).build();
299 return NorthboundUtils.getResponse(status);
303 * Delete a property of a node
305 * @param containerName
306 * Name of the Container (Eg. 'SliceRed')
308 * Type of the node being programmed (Eg. 'OF')
310 * Node Identifier as specified by
311 * {@link org.opendaylight.controller.sal.core.Node}
312 * (Eg. '00:00:00:00:00:03:01:02')
313 * @param propertyName
314 * Name of the Property. Properties that can be deleted are
315 * description, forwarding(only in default container) and tier.
316 * @return Response as dictated by the HTTP Response Status code
323 * http://localhost:8080/controller/nb/v2/switchmanager/default/node/OF/00:00:00:00:00:00:00:03/property/forwarding
328 @Path("/{containerName}/node/{nodeType}/{nodeId}/property/{propertyName}")
330 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
332 @ResponseCode(code = 204, condition = "Property removed successfully"),
333 @ResponseCode(code = 400, condition = "The nodeId or configuration is invalid"),
334 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
335 @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
336 @ResponseCode(code = 409, condition = "Unable to delete property due to cluster conflict"),
337 @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
338 public Response deleteNodeProperty(
339 @PathParam("containerName") String containerName,
340 @PathParam("nodeType") String nodeType,
341 @PathParam("nodeId") String nodeId,
342 @PathParam("propertyName") String propertyName) {
344 if (!isValidContainer(containerName)) {
345 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
347 if (!NorthboundUtils.isAuthorized(
348 getUserName(), containerName, Privilege.WRITE, this)) {
349 throw new UnauthorizedException(
350 "User is not authorized to perform this operation on container "
353 ISwitchManager switchManager = getIfSwitchManagerService(containerName);
354 if (switchManager == null) {
355 throw new ServiceUnavailableException("Switch Manager "
356 + RestMessages.SERVICEUNAVAILABLE.toString());
359 handleNodeAvailability(containerName, nodeType, nodeId);
360 Node node = Node.fromString(nodeType, nodeId);
362 SwitchConfig switchConfig = switchManager.getSwitchConfig(node.toString());
364 if (switchConfig == null) {
365 status = new Status(StatusCode.NOTFOUND, "Switch Configuration does not exist");
367 Map<String, Property> nodeProperties = new HashMap<String, Property>(switchConfig.getNodeProperties());
368 if (!nodeProperties.containsKey(propertyName.toLowerCase())) {
369 String msg = "Property " + propertyName + " does not exist or not configured for switch " + nodeId;
370 status = new Status(StatusCode.NOTFOUND, msg);
372 nodeProperties.remove(propertyName.toLowerCase());
373 SwitchConfig newSwitchConfig = new SwitchConfig(node.toString(), nodeProperties);
374 status = switchManager.updateNodeConfig(newSwitchConfig);
375 if(status.isSuccess()){
376 NorthboundUtils.auditlog("Node Property", username, "removed", propertyName + " from " + nodeId, containerName);
377 return Response.noContent().build();
381 return NorthboundUtils.getResponse(status);
386 * Retrieve a list of all the nodeconnectors and their properties in a given
389 * @param containerName
390 * The container for which we want to retrieve the list (Eg.
393 * Type of the node being programmed (Eg. 'OF')
395 * Node Identifier as specified by
396 * {@link org.opendaylight.controller.sal.core.Node} (Eg.
397 * '00:00:00:00:00:00:00:03')
398 * @return A List of Pair each pair represents a
399 * {@link org.opendaylight.controller.sal.core.NodeConnector} and
401 * {@link org.opendaylight.controller.sal.core.Property} attached to
409 * http://localhost:8080/controller/nb/v2/switchmanager/default/node/OF/00:00:00:00:00:00:00:01
412 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
414 *    <nodeConnectorProperties>
415 *       <nodeconnector>
416 *          <node>
417 *             <id>00:00:00:00:00:00:00:01</id>
418 *             <type>OF</type>
419 *          </node>
420 *          <id>2</id>
421 *          <type>OF</type>
422 *       </nodeconnector>
423 *       <properties>
424 *          <state>
425 *             <value>1</value>
426 *          </state>
427 *          <config>
428 *             <value>1</value>
429 *          </config>
430 *          <name>
431 *             <value>L1_2-C2_1</value>
432 *          </name>
433 *       </properties>
434 *    </nodeConnectorProperties>
438 * {"nodeConnectorProperties":[{"nodeconnector":{"node":{"id":"00:00:00:00:00:00:00:01","type":"OF"},"id":"2","type":"OF"},
439 * "properties":{"state":{"value":"1"},"config":{"value":"1"},"name":{"value":"L1_2-C2_1"}}}]}
443 @Path("/{containerName}/node/{nodeType}/{nodeId}")
445 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
446 @TypeHint(NodeConnectors.class)
448 @ResponseCode(code = 200, condition = "Operation successful"),
449 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
450 @ResponseCode(code = 404, condition = "The containerName is not found"),
451 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
452 public NodeConnectors getNodeConnectors(
453 @PathParam("containerName") String containerName,
454 @PathParam("nodeType") String nodeType,
455 @PathParam("nodeId") String nodeId) {
457 if (!isValidContainer(containerName)) {
458 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
460 if (!NorthboundUtils.isAuthorized(
461 getUserName(), containerName, Privilege.READ, this)) {
462 throw new UnauthorizedException(
463 "User is not authorized to perform this operation on container "
467 ISwitchManager switchManager = getIfSwitchManagerService(containerName);
468 if (switchManager == null) {
469 throw new ServiceUnavailableException("Switch Manager "
470 + RestMessages.SERVICEUNAVAILABLE.toString());
473 handleNodeAvailability(containerName, nodeType, nodeId);
474 Node node = Node.fromString(nodeType, nodeId);
475 List<NodeConnectorProperties> res = new ArrayList<NodeConnectorProperties>();
476 Set<NodeConnector> ncs = switchManager.getNodeConnectors(node);
481 for (NodeConnector nc : ncs) {
482 Map<String, Property> propMap = switchManager
483 .getNodeConnectorProps(nc);
484 if (propMap == null) {
487 Set<Property> props = new HashSet<Property>(propMap.values());
488 NodeConnectorProperties ncProps = new NodeConnectorProperties(nc,
493 return new NodeConnectors(res);
497 * Add node-connector property to a node connector. This method returns a
498 * non-successful response if a node connector by the given name already
501 * @param containerName
502 * Name of the Container (Eg. 'default')
504 * Type of the node being programmed (Eg. 'OF')
506 * Node Identifier as specified by
507 * {@link org.opendaylight.controller.sal.core.Node}
508 * (Eg. '00:00:00:00:00:00:00:03')
509 * @param nodeConnectorType
510 * Type of the node connector being programmed (Eg. 'OF')
511 * @param nodeConnectorId
512 * NodeConnector Identifier as specified by
513 * {@link org.opendaylight.controller.sal.core.NodeConnector}
515 * @param propertyName
516 * Name of the Property specified by
517 * {@link org.opendaylight.controller.sal.core.Property} and its
519 * Property that can be configured is bandwidth
520 * @param propertyValue
521 * Value of the Property specified by
522 * {@link org.opendaylight.controller.sal.core.Property} and its
524 * @return Response as dictated by the HTTP Response Status code
531 * http://localhost:8080/controller/nb/v2/switchmanager/default/nodeconnector/OF/00:00:00:00:00:00:00:01/OF/2/property/bandwidth/1
536 @Path("/{containerName}/nodeconnector/{nodeType}/{nodeId}/{nodeConnectorType}/{nodeConnectorId}/property/{propertyName}/{propertyValue}")
538 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
540 @ResponseCode(code = 201, condition = "Operation successful"),
541 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
542 @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
543 @ResponseCode(code = 409, condition = "Unable to add property due to cluster conflict"),
544 @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
545 public Response addNodeConnectorProperty(
546 @Context UriInfo uriInfo,
547 @PathParam("containerName") String containerName,
548 @PathParam("nodeType") String nodeType,
549 @PathParam("nodeId") String nodeId,
550 @PathParam("nodeConnectorType") String nodeConnectorType,
551 @PathParam("nodeConnectorId") String nodeConnectorId,
552 @PathParam("propertyName") String propertyName,
553 @PathParam("propertyValue") String propertyValue) {
555 if (!isValidContainer(containerName)) {
556 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
558 if (!NorthboundUtils.isAuthorized(
559 getUserName(), containerName, Privilege.WRITE, this)) {
560 throw new UnauthorizedException(
561 "User is not authorized to perform this operation on container "
565 ISwitchManager switchManager = getIfSwitchManagerService(containerName);
566 if (switchManager == null) {
567 throw new ServiceUnavailableException("Switch Manager "
568 + RestMessages.SERVICEUNAVAILABLE.toString());
571 handleNodeAvailability(containerName, nodeType, nodeId);
572 Node node = Node.fromString(nodeType, nodeId);
574 handleNodeConnectorAvailability(containerName, node, nodeConnectorType,
576 NodeConnector nc = NodeConnector
577 .fromStringNoNode(nodeConnectorType, nodeConnectorId, node);
579 Property prop = switchManager.createProperty(propertyName, propertyValue);
581 throw new ResourceNotFoundException(
582 RestMessages.INVALIDDATA.toString());
585 Status ret = switchManager.addNodeConnectorProp(nc, prop);
586 if (ret.isSuccess()) {
587 return Response.created(uriInfo.getRequestUri()).build();
589 throw new InternalServerErrorException(ret.getDescription());
593 * Delete a property of a node connector
595 * @param containerName
596 * Name of the Container (Eg. 'default')
598 * Type of the node being programmed (Eg. 'OF')
600 * Node Identifier as specified by
601 * {@link org.opendaylight.controller.sal.core.Node}
602 * (Eg. '00:00:00:00:00:00:00:01')
603 * @param nodeConnectorType
604 * Type of the node connector being programmed (Eg. 'OF')
605 * @param nodeConnectorId
606 * NodeConnector Identifier as specified by
607 * {@link org.opendaylight.controller.sal.core.NodeConnector}
609 * @param propertyName
610 * Name of the Property specified by
611 * {@link org.opendaylight.controller.sal.core.Property} and its
612 * extended classes. Property that can be deleted is bandwidth
613 * @return Response as dictated by the HTTP Response Status code
620 * http://localhost:8080/controller/nb/v2/switchmanager/default/nodeconnector/OF/00:00:00:00:00:00:00:01/OF/2/property/bandwidth
625 @Path("/{containerName}/nodeconnector/{nodeType}/{nodeId}/{nodeConnectorType}/{nodeConnectorId}/property/{propertyName}")
627 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
629 @ResponseCode(code = 204, condition = "Property removed successfully"),
630 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
631 @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
632 @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
633 public Response deleteNodeConnectorProperty(
634 @PathParam("containerName") String containerName,
635 @PathParam("nodeType") String nodeType,
636 @PathParam("nodeId") String nodeId,
637 @PathParam("nodeConnectorType") String nodeConnectorType,
638 @PathParam("nodeConnectorId") String nodeConnectorId,
639 @PathParam("propertyName") String propertyName) {
641 if (!isValidContainer(containerName)) {
642 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
644 if (!NorthboundUtils.isAuthorized(
645 getUserName(), containerName, Privilege.WRITE, this)) {
646 throw new UnauthorizedException(
647 "User is not authorized to perform this operation on container "
651 ISwitchManager switchManager = getIfSwitchManagerService(containerName);
652 if (switchManager == null) {
653 throw new ServiceUnavailableException("Switch Manager "
654 + RestMessages.SERVICEUNAVAILABLE.toString());
657 handleNodeAvailability(containerName, nodeType, nodeId);
658 Node node = Node.fromString(nodeType, nodeId);
660 handleNodeConnectorAvailability(containerName, node, nodeConnectorType,
662 NodeConnector nc = NodeConnector
663 .fromStringNoNode(nodeConnectorType, nodeConnectorId, node);
664 Status ret = switchManager.removeNodeConnectorProp(nc, propertyName);
665 if (ret.isSuccess()) {
666 NorthboundUtils.auditlog("Node Connector Property", username, "removed", nc + " from " + nodeConnectorId, containerName);
667 return Response.noContent().build();
669 throw new ResourceNotFoundException(ret.getDescription());
673 * Save the current switch configurations
675 * @param containerName
676 * Name of the Container (Eg. 'default')
677 * @return Response as dictated by the HTTP Response Status code
684 * http://localhost:8080/controller/nb/v2/switchmanager/default/save
688 @Path("/{containerName}/save")
690 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
692 @ResponseCode(code = 200, condition = "Operation successful"),
693 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
694 @ResponseCode(code = 404, condition = "The containerName is not found"),
695 @ResponseCode(code = 500, condition = "Failed to save switch configuration. Failure Reason included in HTTP Error response"),
696 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
697 public Response saveSwitchConfig(
698 @PathParam("containerName") String containerName) {
700 if (!isValidContainer(containerName)) {
701 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
703 if (!NorthboundUtils.isAuthorized(
704 getUserName(), containerName, Privilege.WRITE, this)) {
705 throw new UnauthorizedException(
706 "User is not authorized to perform this operation on container "
709 ISwitchManager switchManager = getIfSwitchManagerService(containerName);
710 if (switchManager == null) {
711 throw new ServiceUnavailableException("Switch Manager "
712 + RestMessages.SERVICEUNAVAILABLE.toString());
715 Status ret = switchManager.saveSwitchConfig();
716 if (ret.isSuccess()) {
717 return Response.ok().build();
719 throw new InternalServerErrorException(ret.getDescription());
722 private Node handleNodeAvailability(String containerName, String nodeType,
725 Node node = Node.fromString(nodeType, nodeId);
727 throw new ResourceNotFoundException(nodeId + " : "
728 + RestMessages.NONODE.toString());
731 ISwitchManager sm = (ISwitchManager) ServiceHelper.getInstance(
732 ISwitchManager.class, containerName, this);
735 throw new ServiceUnavailableException("Switch Manager "
736 + RestMessages.SERVICEUNAVAILABLE.toString());
739 if (!sm.getNodes().contains(node)) {
740 throw new ResourceNotFoundException(node.toString() + " : "
741 + RestMessages.NONODE.toString());
746 private void handleNodeConnectorAvailability(String containerName,
747 Node node, String nodeConnectorType, String nodeConnectorId) {
749 NodeConnector nc = NodeConnector.fromStringNoNode(nodeConnectorType,
750 nodeConnectorId, node);
752 throw new ResourceNotFoundException(nc + " : "
753 + RestMessages.NORESOURCE.toString());
756 ISwitchManager sm = (ISwitchManager) ServiceHelper.getInstance(
757 ISwitchManager.class, containerName, this);
760 throw new ServiceUnavailableException("Switch Manager "
761 + RestMessages.SERVICEUNAVAILABLE.toString());
764 if (!sm.getNodeConnectors(node).contains(nc)) {
765 throw new ResourceNotFoundException(nc.toString() + " : "
766 + RestMessages.NORESOURCE.toString());
770 private boolean isValidContainer(String containerName) {
771 if (containerName.equals(GlobalConstants.DEFAULT.toString())) {
774 IContainerManager containerManager = (IContainerManager) ServiceHelper
775 .getGlobalInstance(IContainerManager.class, this);
776 if (containerManager == null) {
777 throw new InternalServerErrorException(
778 RestMessages.INTERNALERROR.toString());
780 if (containerManager.getContainerNames().contains(containerName)) {