e67d1b75686934b48fb15cb409bf0cdf5cd3d123
[controller.git] / opendaylight / northbound / switchmanager / src / main / java / org / opendaylight / controller / switchmanager / northbound / SwitchNorthbound.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.controller.switchmanager.northbound;
10
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Set;
17
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
31 import org.codehaus.enunciate.jaxrs.ResponseCode;
32 import org.codehaus.enunciate.jaxrs.StatusCodes;
33 import org.codehaus.enunciate.jaxrs.TypeHint;
34 import org.opendaylight.controller.containermanager.IContainerManager;
35 import org.opendaylight.controller.northbound.commons.RestMessages;
36 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
37 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
38 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
39 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
40 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
41 import org.opendaylight.controller.sal.authorization.Privilege;
42 import org.opendaylight.controller.sal.core.Node;
43 import org.opendaylight.controller.sal.core.NodeConnector;
44 import org.opendaylight.controller.sal.core.Property;
45 import org.opendaylight.controller.sal.utils.GlobalConstants;
46 import org.opendaylight.controller.sal.utils.ServiceHelper;
47 import org.opendaylight.controller.sal.utils.Status;
48 import org.opendaylight.controller.sal.utils.StatusCode;
49 import org.opendaylight.controller.switchmanager.ISwitchManager;
50 import org.opendaylight.controller.switchmanager.SwitchConfig;
51
52 /**
53  * The class provides Northbound REST APIs to access the nodes, node connectors
54  * and their properties.
55  *
56  */
57
58 @Path("/")
59 public class SwitchNorthbound {
60
61     private String username;
62
63     @Context
64     public void setSecurityContext(SecurityContext context) {
65         username = context.getUserPrincipal().getName();
66     }
67
68     protected String getUserName() {
69         return username;
70     }
71
72     private ISwitchManager getIfSwitchManagerService(String containerName) {
73         IContainerManager containerManager = (IContainerManager) ServiceHelper
74                 .getGlobalInstance(IContainerManager.class, this);
75         if (containerManager == null) {
76             throw new ServiceUnavailableException("Container "
77                     + RestMessages.SERVICEUNAVAILABLE.toString());
78         }
79
80         boolean found = false;
81         List<String> containerNames = containerManager.getContainerNames();
82         for (String cName : containerNames) {
83             if (cName.trim().equalsIgnoreCase(containerName.trim())) {
84                 found = true;
85                 break;
86             }
87         }
88
89         if (found == false) {
90             throw new ResourceNotFoundException(containerName + " "
91                     + RestMessages.NOCONTAINER.toString());
92         }
93
94         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
95                 .getInstance(ISwitchManager.class, containerName, this);
96
97         if (switchManager == null) {
98             throw new ServiceUnavailableException("Switch Manager "
99                     + RestMessages.SERVICEUNAVAILABLE.toString());
100         }
101
102         return switchManager;
103     }
104
105     /**
106      *
107      * Retrieve a list of all the nodes and their properties in the network
108      *
109      * @param containerName
110      *            The container for which we want to retrieve the list
111      * @return A list of Pair each pair represents a
112      *         {@link org.opendaylight.controller.sal.core.Node} and Set of
113      *         {@link org.opendaylight.controller.sal.core.Property} attached to
114      *         it.
115      */
116     @Path("/{containerName}/nodes")
117     @GET
118     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
119     @TypeHint(Nodes.class)
120     @StatusCodes({
121             @ResponseCode(code = 200, condition = "Operation successful"),
122             @ResponseCode(code = 404, condition = "The containerName is not found"),
123             @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
124     public Nodes getNodes(@PathParam("containerName") String containerName) {
125
126         if (!isValidContainer(containerName)) {
127             throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
128         }
129
130         if (!NorthboundUtils.isAuthorized(
131                 getUserName(), containerName, Privilege.READ, this)) {
132             throw new UnauthorizedException(
133                     "User is not authorized to perform this operation on container "
134                             + containerName);
135         }
136
137         ISwitchManager switchManager = getIfSwitchManagerService(containerName);
138         if (switchManager == null) {
139             throw new ServiceUnavailableException("Switch Manager "
140                     + RestMessages.SERVICEUNAVAILABLE.toString());
141         }
142
143         List<NodeProperties> res = new ArrayList<NodeProperties>();
144         Set<Node> nodes = switchManager.getNodes();
145         if (nodes == null) {
146             return null;
147         }
148
149         for (Node node : nodes) {
150             Map<String, Property> propMap = switchManager.getNodeProps(node);
151             if (propMap == null) {
152                 continue;
153             }
154             Set<Property> props = new HashSet<Property>(propMap.values());
155
156             NodeProperties nodeProps = new NodeProperties(node, props);
157             res.add(nodeProps);
158         }
159
160         return new Nodes(res);
161     }
162
163     /**
164      * Add a Name, Tier and Forwarding mode property to a node.
165      *
166      * <pre>
167      * Example Request:
168      *  http://localhost:8080/controller/nb/v2/switch/red/node/OF/00:00:00:00:00:03/property/description/Switch3
169      *  (Valid properties that can be configured are: description, forwarding(only for default container) and tier)
170      * </pre>
171      *
172      * @param containerName
173      *            Name of the Container
174      * @param nodeType
175      *            Type of the node being programmed
176      * @param nodeId
177      *            Node Identifier as specified by
178      *            {@link org.opendaylight.controller.sal.core.Node}
179      * @param propName
180      *            Name of the Property specified by
181      *            {@link org.opendaylight.controller.sal.core.Property} and its
182      *            extended classes
183      * @param propValue
184      *            Value of the Property specified by
185      *            {@link org.opendaylight.controller.sal.core.Property} and its
186      *            extended classes
187      * @return Response as dictated by the HTTP Response Status code
188      */
189
190     @Path("/{containerName}/node/{nodeType}/{nodeId}/property/{propName}/{propValue}")
191     @PUT
192     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
193     @TypeHint(Response.class)
194     @StatusCodes({
195             @ResponseCode(code = 200, condition = "Operation successful"),
196             @ResponseCode(code = 400, condition = "The nodeId or configuration is invalid"),
197             @ResponseCode(code = 404, condition = "The Container Name or node or configuration name is not found"),
198             @ResponseCode(code = 406, condition = "The property cannot be configured in non-default container"),
199             @ResponseCode(code = 409, condition = "Unable to update configuration due to cluster conflict"),
200             @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
201     public Response addNodeProperty(
202             @PathParam("containerName") String containerName,
203             @PathParam("nodeType") String nodeType,
204             @PathParam("nodeId") String nodeId,
205             @PathParam("propName") String propName,
206             @PathParam("propValue") String propValue) {
207
208         if (!isValidContainer(containerName)) {
209             throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
210         }
211         if (!NorthboundUtils.isAuthorized(
212                 getUserName(), containerName, Privilege.WRITE, this)) {
213             throw new UnauthorizedException(
214                     "User is not authorized to perform this operation on container "
215                             + containerName);
216         }
217         ISwitchManager switchManager = getIfSwitchManagerService(containerName);
218         if (switchManager == null) {
219             throw new ServiceUnavailableException("Switch Manager "
220                     + RestMessages.SERVICEUNAVAILABLE.toString());
221         }
222
223         handleNodeAvailability(containerName, nodeType, nodeId);
224         Node node = Node.fromString(nodeType, nodeId);
225         Property prop = switchManager.createProperty(propName, propValue);
226         if (prop == null) {
227             throw new ResourceNotFoundException("Property with name " + propName + " does not exist.");
228         }
229         SwitchConfig switchConfig = switchManager.getSwitchConfig(node.toString());
230         Map<String, Property> nodeProperties = (switchConfig == null) ? new HashMap<String, Property>()
231                 : new HashMap<String, Property>(switchConfig.getNodeProperties());
232         nodeProperties.put(prop.getName(), prop);
233         SwitchConfig newSwitchConfig = new SwitchConfig(node.toString(), nodeProperties);
234         Status status = switchManager.updateNodeConfig(newSwitchConfig);
235         return NorthboundUtils.getResponse(status);
236     }
237
238     /**
239      * Delete a property of a node
240      *
241      * <pre>
242      * Example Request:
243      *  http://localhost:8080/controller/nb/v2/switch/default/node/OF/00:00:00:00:00:03/property/forwarding
244      * </pre>
245      *
246      * @param containerName
247      *            Name of the Container
248      * @param nodeType
249      *            Type of the node being programmed
250      * @param nodeId
251      *            Node Identifier as specified by
252      *            {@link org.opendaylight.controller.sal.core.Node}
253      * @param propertyName
254      *            Name of the Property specified by
255      *            {@link org.opendaylight.controller.sal.core.Property} and its
256      *            extended classes
257      * @return Response as dictated by the HTTP Response Status code
258      */
259
260     @Path("/{containerName}/node/{nodeType}/{nodeId}/property/{propertyName}")
261     @DELETE
262     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
263     @StatusCodes({
264             @ResponseCode(code = 200, condition = "Operation successful"),
265             @ResponseCode(code = 400, condition = "The nodeId or configuration is invalid"),
266             @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
267             @ResponseCode(code = 409, condition = "Unable to delete property due to cluster conflict"),
268             @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
269     public Response deleteNodeProperty(
270             @PathParam("containerName") String containerName,
271             @PathParam("nodeType") String nodeType,
272             @PathParam("nodeId") String nodeId,
273             @PathParam("propertyName") String propertyName) {
274
275         if (!isValidContainer(containerName)) {
276             throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
277         }
278         if (!NorthboundUtils.isAuthorized(
279                 getUserName(), containerName, Privilege.WRITE, this)) {
280             throw new UnauthorizedException(
281                     "User is not authorized to perform this operation on container "
282                             + containerName);
283         }
284         ISwitchManager switchManager = getIfSwitchManagerService(containerName);
285         if (switchManager == null) {
286             throw new ServiceUnavailableException("Switch Manager "
287                     + RestMessages.SERVICEUNAVAILABLE.toString());
288         }
289
290         handleNodeAvailability(containerName, nodeType, nodeId);
291         Node node = Node.fromString(nodeType, nodeId);
292
293         SwitchConfig switchConfig = switchManager.getSwitchConfig(node.toString());
294         Status status;
295         if (switchConfig == null) {
296             status = new Status(StatusCode.NOTFOUND, "Switch Configuration does not exist");
297         } else {
298             Map<String, Property> nodeProperties = new HashMap<String, Property>(switchConfig.getNodeProperties());
299             if (!nodeProperties.containsKey(propertyName.toLowerCase())) {
300                 String msg = "Property " + propertyName + " does not exist or not configured for switch " + nodeId;
301                 status = new Status(StatusCode.NOTFOUND, msg);
302             } else {
303                 nodeProperties.remove(propertyName.toLowerCase());
304                 SwitchConfig newSwitchConfig = new SwitchConfig(node.toString(), nodeProperties);
305                 status = switchManager.updateNodeConfig(newSwitchConfig);
306                 if(status.isSuccess()){
307                     NorthboundUtils.auditlog("Static Route", username, "updated", nodeId, containerName);
308                 }
309             }
310         }
311         return NorthboundUtils.getResponse(status);
312     }
313
314     /**
315      *
316      * Retrieve a list of all the node connectors and their properties in a
317      * given node
318      *
319      * @param containerName
320      *            The container for which we want to retrieve the list
321      * @param nodeType
322      *            Type of the node being programmed
323      * @param nodeId
324      *            Node Identifier as specified by
325      *            {@link org.opendaylight.controller.sal.core.Node}
326      * @return A List of Pair each pair represents a
327      *         {@link org.opendaylight.controller.sal.core.NodeConnector} and
328      *         its corresponding
329      *         {@link org.opendaylight.controller.sal.core.Property} attached to
330      *         it.
331      */
332     @Path("/{containerName}/node/{nodeType}/{nodeId}")
333     @GET
334     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
335     @TypeHint(NodeConnectors.class)
336     @StatusCodes({
337             @ResponseCode(code = 200, condition = "Operation successful"),
338             @ResponseCode(code = 404, condition = "The containerName is not found"),
339             @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
340     public NodeConnectors getNodeConnectors(
341             @PathParam("containerName") String containerName,
342             @PathParam("nodeType") String nodeType,
343             @PathParam("nodeId") String nodeId) {
344
345         if (!isValidContainer(containerName)) {
346             throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
347         }
348         if (!NorthboundUtils.isAuthorized(
349                 getUserName(), containerName, Privilege.READ, this)) {
350             throw new UnauthorizedException(
351                     "User is not authorized to perform this operation on container "
352                             + containerName);
353         }
354
355         ISwitchManager switchManager = getIfSwitchManagerService(containerName);
356         if (switchManager == null) {
357             throw new ServiceUnavailableException("Switch Manager "
358                     + RestMessages.SERVICEUNAVAILABLE.toString());
359         }
360
361         handleNodeAvailability(containerName, nodeType, nodeId);
362         Node node = Node.fromString(nodeType, nodeId);
363         List<NodeConnectorProperties> res = new ArrayList<NodeConnectorProperties>();
364         Set<NodeConnector> ncs = switchManager.getNodeConnectors(node);
365         if (ncs == null) {
366             return null;
367         }
368
369         for (NodeConnector nc : ncs) {
370             Map<String, Property> propMap = switchManager
371                     .getNodeConnectorProps(nc);
372             if (propMap == null) {
373                 continue;
374             }
375             Set<Property> props = new HashSet<Property>(propMap.values());
376             NodeConnectorProperties ncProps = new NodeConnectorProperties(nc,
377                     props);
378             res.add(ncProps);
379         }
380
381         return new NodeConnectors(res);
382     }
383
384     /**
385      * Add a Name/Bandwidth property to a node connector
386      *
387      * @param containerName
388      *            Name of the Container
389      * @param nodeType
390      *            Type of the node being programmed
391      * @param nodeId
392      *            Node Identifier as specified by
393      *            {@link org.opendaylight.controller.sal.core.Node}
394      * @param nodeConnectorType
395      *            Type of the node connector being programmed
396      * @param nodeConnectorId
397      *            NodeConnector Identifier as specified by
398      *            {@link org.opendaylight.controller.sal.core.NodeConnector}
399      * @param propName
400      *            Name of the Property specified by
401      *            {@link org.opendaylight.controller.sal.core.Property} and its
402      *            extended classes
403      * @param propValue
404      *            Value of the Property specified by
405      *            {@link org.opendaylight.controller.sal.core.Property} and its
406      *            extended classes
407      * @return Response as dictated by the HTTP Response Status code
408      */
409
410     @Path("/{containerName}/nodeconnector/{nodeType}/{nodeId}/{nodeConnectorType}/{nodeConnectorId}/property/{propName}/{propValue}")
411     @PUT
412     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
413     @StatusCodes({
414             @ResponseCode(code = 200, condition = "Operation successful"),
415             @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
416             @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
417     public Response addNodeConnectorProperty(
418             @PathParam("containerName") String containerName,
419             @PathParam("nodeType") String nodeType,
420             @PathParam("nodeId") String nodeId,
421             @PathParam("nodeConnectorType") String nodeConnectorType,
422             @PathParam("nodeConnectorId") String nodeConnectorId,
423             @PathParam("propName") String propName,
424             @PathParam("propValue") String propValue) {
425
426         if (!isValidContainer(containerName)) {
427             throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
428         }
429         if (!NorthboundUtils.isAuthorized(
430                 getUserName(), containerName, Privilege.WRITE, this)) {
431             throw new UnauthorizedException(
432                     "User is not authorized to perform this operation on container "
433                             + containerName);
434         }
435
436         ISwitchManager switchManager = getIfSwitchManagerService(containerName);
437         if (switchManager == null) {
438             throw new ServiceUnavailableException("Switch Manager "
439                     + RestMessages.SERVICEUNAVAILABLE.toString());
440         }
441
442         handleNodeAvailability(containerName, nodeType, nodeId);
443         Node node = Node.fromString(nodeType, nodeId);
444
445         handleNodeConnectorAvailability(containerName, node, nodeConnectorType,
446                 nodeConnectorId);
447         NodeConnector nc = NodeConnector
448                 .fromStringNoNode(nodeConnectorType, nodeConnectorId, node);
449
450         Property prop = switchManager.createProperty(propName, propValue);
451         if (prop == null) {
452             throw new ResourceNotFoundException(
453                     RestMessages.INVALIDDATA.toString());
454         }
455
456         Status ret = switchManager.addNodeConnectorProp(nc, prop);
457         if (ret.isSuccess()) {
458             return Response.status(Response.Status.CREATED).build();
459         }
460         throw new InternalServerErrorException(ret.getDescription());
461     }
462
463     /**
464      * Delete a property of a node connector
465      *
466      * @param containerName
467      *            Name of the Container
468      * @param nodeType
469      *            Type of the node being programmed
470      * @param nodeId
471      *            Node Identifier as specified by
472      *            {@link org.opendaylight.controller.sal.core.Node}
473      * @param nodeConnectorType
474      *            Type of the node connector being programmed
475      * @param nodeConnectorId
476      *            NodeConnector Identifier as specified by
477      *            {@link org.opendaylight.controller.sal.core.NodeConnector}
478      * @param propertyName
479      *            Name of the Property specified by
480      *            {@link org.opendaylight.controller.sal.core.Property} and its
481      *            extended classes
482      * @return Response as dictated by the HTTP Response Status code
483      */
484
485     @Path("/{containerName}/nodeconnector/{nodeType}/{nodeId}/{nodeConnectorType}/{nodeConnectorId}/property/{propertyName}")
486     @DELETE
487     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
488     @StatusCodes({
489             @ResponseCode(code = 200, condition = "Operation successful"),
490             @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"),
491             @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
492     public Response deleteNodeConnectorProperty(
493             @PathParam("containerName") String containerName,
494             @PathParam("nodeType") String nodeType,
495             @PathParam("nodeId") String nodeId,
496             @PathParam("nodeConnectorType") String nodeConnectorType,
497             @PathParam("nodeConnectorId") String nodeConnectorId,
498             @PathParam("propertyName") String propertyName) {
499
500         if (!isValidContainer(containerName)) {
501             throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
502         }
503         if (!NorthboundUtils.isAuthorized(
504                 getUserName(), containerName, Privilege.WRITE, this)) {
505             throw new UnauthorizedException(
506                     "User is not authorized to perform this operation on container "
507                             + containerName);
508         }
509
510         ISwitchManager switchManager = getIfSwitchManagerService(containerName);
511         if (switchManager == null) {
512             throw new ServiceUnavailableException("Switch Manager "
513                     + RestMessages.SERVICEUNAVAILABLE.toString());
514         }
515
516         handleNodeAvailability(containerName, nodeType, nodeId);
517         Node node = Node.fromString(nodeType, nodeId);
518
519         handleNodeConnectorAvailability(containerName, node, nodeConnectorType,
520                 nodeConnectorId);
521         NodeConnector nc = NodeConnector
522                 .fromStringNoNode(nodeConnectorType, nodeConnectorId, node);
523         Status ret = switchManager.removeNodeConnectorProp(nc, propertyName);
524         if (ret.isSuccess()) {
525             NorthboundUtils.auditlog("Node Connector Property", username, "removed", nc + " from " + nodeConnectorId, containerName);
526             return Response.ok().build();
527         }
528         throw new ResourceNotFoundException(ret.getDescription());
529     }
530
531     /*    *//**
532      * Retrieve a list of Span ports that were configured previously.
533      *
534      * @param containerName
535      *            Name of the Container
536      * @return list of
537      *         {@link org.opendaylight.controller.switchmanager.SpanConfig}
538      *         resources
539      */
540     /*
541      * @Path("/span-config/{containerName}")
542      *
543      * @GET
544      *
545      * @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
546      *
547      * @StatusCodes( {
548      *
549      * @ResponseCode(code = 200, condition = "Operation successful"),
550      *
551      * @ResponseCode(code = 404, condition = "The containerName is not found"),
552      *
553      * @ResponseCode(code = 503, condition =
554      * "One or more of Controller Services are unavailable") }) public
555      * List<SpanConfig> getSpanConfigList(@PathParam("containerName") String
556      * containerName) { ISwitchManager switchManager = (ISwitchManager)
557      * getIfSwitchManagerService(containerName); if (switchManager == null) {
558      * throw new ServiceUnavailableException("Switch Manager " +
559      * RestMessages.SERVICEUNAVAILABLE.toString()); }
560      *
561      * return switchManager.getSpanConfigList(); }
562      *//**
563      * Add a span configuration
564      *
565      * @param containerName
566      *            Name of the Container
567      * @param config
568      *            {@link org.opendaylight.controller.switchmanager.SpanConfig}
569      *            in JSON or XML format
570      * @return Response as dictated by the HTTP Response Status code
571      */
572     /*
573      * @Path("/span-config/{containerName}")
574      *
575      * @PUT
576      *
577      * @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
578      *
579      * @StatusCodes( {
580      *
581      * @ResponseCode(code = 200, condition = "Operation successful"),
582      *
583      * @ResponseCode(code = 404, condition = "The containerName is not found"),
584      *
585      * @ResponseCode(code = 503, condition =
586      * "One or more of Controller Services are unavailable") }) public Response
587      * addSpanConfig(@PathParam("containerName") String containerName,
588      *
589      * @TypeHint(SubnetConfig.class) JAXBElement<SpanConfig> config) {
590      * ISwitchManager switchManager = (ISwitchManager)
591      * getIfSwitchManagerService(containerName); if (switchManager == null) {
592      * throw new ServiceUnavailableException("Switch Manager " +
593      * RestMessages.SERVICEUNAVAILABLE.toString()); }
594      *
595      * String ret = switchManager.addSpanConfig(config.getValue()); if
596      * (ret.equals(ReturnString.SUCCESS.toString())) { return
597      * Response.status(Response.Status.CREATED).build(); } throw new
598      * InternalServerErrorException(ret); }
599      *//**
600      * Delete a span configuration
601      *
602      * @param containerName
603      *            Name of the Container
604      * @param config
605      *            {@link org.opendaylight.controller.switchmanager.SpanConfig}
606      *            in JSON or XML format
607      * @return Response as dictated by the HTTP Response Status code
608      */
609     /*
610      * @Path("/span-config/{containerName}")
611      *
612      * @DELETE
613      *
614      * @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
615      *
616      * @StatusCodes( {
617      *
618      * @ResponseCode(code = 200, condition = "Operation successful"),
619      *
620      * @ResponseCode(code = 404, condition = "The containerName is not found"),
621      *
622      * @ResponseCode(code = 503, condition =
623      * "One or more of Controller Services are unavailable") }) public Response
624      * deleteSpanConfig(@PathParam("containerName") String containerName,
625      *
626      * @TypeHint(SubnetConfig.class) JAXBElement<SpanConfig> config) {
627      * ISwitchManager switchManager = (ISwitchManager)
628      * getIfSwitchManagerService(containerName); if (switchManager == null) {
629      * throw new ServiceUnavailableException("Switch Manager " +
630      * RestMessages.SERVICEUNAVAILABLE.toString()); }
631      *
632      * String ret = switchManager.removeSpanConfig(config.getValue()); if
633      * (ret.equals(ReturnString.SUCCESS.toString())) { return
634      * Response.ok().build(); } throw new ResourceNotFoundException(ret); }
635      */
636
637     /**
638      * Save the current switch configurations
639      *
640      * @param containerName
641      *            Name of the Container
642      * @return Response as dictated by the HTTP Response Status code
643      */
644     @Path("/{containerName}/switch-config")
645     @POST
646     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
647     @StatusCodes({
648             @ResponseCode(code = 200, condition = "Operation successful"),
649             @ResponseCode(code = 404, condition = "The containerName is not found"),
650             @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
651     public Response saveSwitchConfig(
652             @PathParam("containerName") String containerName) {
653
654         if (!isValidContainer(containerName)) {
655             throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
656         }
657         if (!NorthboundUtils.isAuthorized(
658                 getUserName(), containerName, Privilege.WRITE, this)) {
659             throw new UnauthorizedException(
660                     "User is not authorized to perform this operation on container "
661                             + containerName);
662         }
663         ISwitchManager switchManager = getIfSwitchManagerService(containerName);
664         if (switchManager == null) {
665             throw new ServiceUnavailableException("Switch Manager "
666                     + RestMessages.SERVICEUNAVAILABLE.toString());
667         }
668
669         Status ret = switchManager.saveSwitchConfig();
670         if (ret.isSuccess()) {
671             return Response.ok().build();
672         }
673         throw new InternalServerErrorException(ret.getDescription());
674     }
675
676     private Node handleNodeAvailability(String containerName, String nodeType,
677             String nodeId) {
678
679         Node node = Node.fromString(nodeType, nodeId);
680         if (node == null) {
681             throw new ResourceNotFoundException(nodeId + " : "
682                     + RestMessages.NONODE.toString());
683         }
684
685         ISwitchManager sm = (ISwitchManager) ServiceHelper.getInstance(
686                 ISwitchManager.class, containerName, this);
687
688         if (sm == null) {
689             throw new ServiceUnavailableException("Switch Manager "
690                     + RestMessages.SERVICEUNAVAILABLE.toString());
691         }
692
693         if (!sm.getNodes().contains(node)) {
694             throw new ResourceNotFoundException(node.toString() + " : "
695                     + RestMessages.NONODE.toString());
696         }
697         return node;
698     }
699
700     private void handleNodeConnectorAvailability(String containerName,
701             Node node, String nodeConnectorType, String nodeConnectorId) {
702
703         NodeConnector nc = NodeConnector.fromStringNoNode(nodeConnectorType,
704                 nodeConnectorId, node);
705         if (nc == null) {
706             throw new ResourceNotFoundException(nc + " : "
707                     + RestMessages.NORESOURCE.toString());
708         }
709
710         ISwitchManager sm = (ISwitchManager) ServiceHelper.getInstance(
711                 ISwitchManager.class, containerName, this);
712
713         if (sm == null) {
714             throw new ServiceUnavailableException("Switch Manager "
715                     + RestMessages.SERVICEUNAVAILABLE.toString());
716         }
717
718         if (!sm.getNodeConnectors(node).contains(nc)) {
719             throw new ResourceNotFoundException(nc.toString() + " : "
720                     + RestMessages.NORESOURCE.toString());
721         }
722     }
723
724     private boolean isValidContainer(String containerName) {
725         if (containerName.equals(GlobalConstants.DEFAULT.toString())) {
726             return true;
727         }
728         IContainerManager containerManager = (IContainerManager) ServiceHelper
729                 .getGlobalInstance(IContainerManager.class, this);
730         if (containerManager == null) {
731             throw new InternalServerErrorException(
732                     RestMessages.INTERNALERROR.toString());
733         }
734         if (containerManager.getContainerNames().contains(containerName)) {
735             return true;
736        }
737         return false;
738     }
739
740 }