X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnorthbound%2Fswitchmanager%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fswitchmanager%2Fnorthbound%2FSwitchNorthbound.java;h=f4d302b2d1b9cab1f96ea7501367ef532d7ff309;hb=refs%2Fchanges%2F49%2F1149%2F2;hp=d3b023512bebd5790559b7e047b813e0558395e9;hpb=9c8108faabf300747a2a5529dc7a8ef76e79c2bc;p=controller.git diff --git a/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/SwitchNorthbound.java b/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/SwitchNorthbound.java index d3b023512b..f4d302b2d1 100644 --- a/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/SwitchNorthbound.java +++ b/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/SwitchNorthbound.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.switchmanager.northbound; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -26,6 +27,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; +import javax.ws.rs.core.UriInfo; import org.codehaus.enunciate.jaxrs.ResponseCode; import org.codehaus.enunciate.jaxrs.StatusCodes; @@ -33,7 +35,6 @@ import org.codehaus.enunciate.jaxrs.TypeHint; import org.opendaylight.controller.containermanager.IContainerManager; import org.opendaylight.controller.northbound.commons.RestMessages; import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException; -import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException; import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException; import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException; import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException; @@ -45,7 +46,9 @@ import org.opendaylight.controller.sal.core.Property; import org.opendaylight.controller.sal.utils.GlobalConstants; import org.opendaylight.controller.sal.utils.ServiceHelper; import org.opendaylight.controller.sal.utils.Status; +import org.opendaylight.controller.sal.utils.StatusCode; import org.opendaylight.controller.switchmanager.ISwitchManager; +import org.opendaylight.controller.switchmanager.SwitchConfig; /** * The class provides Northbound REST APIs to access the nodes, node connectors @@ -60,7 +63,7 @@ public class SwitchNorthbound { @Context public void setSecurityContext(SecurityContext context) { - username = context.getUserPrincipal().getName(); + if (context != null && context.getUserPrincipal() != null) username = context.getUserPrincipal().getName(); } protected String getUserName() { @@ -105,11 +108,60 @@ public class SwitchNorthbound { * Retrieve a list of all the nodes and their properties in the network * * @param containerName - * The container for which we want to retrieve the list + * Name of the Container (Eg. 'default') * @return A list of Pair each pair represents a * {@link org.opendaylight.controller.sal.core.Node} and Set of * {@link org.opendaylight.controller.sal.core.Property} attached to * it. + * + *
+ * + * Example: + * + * RequestURL: + * http://localhost:8080/controller/nb/v2/switchmanager/default/nodes + * + * Response in XML: + * <?xml version="1.0" encoding="UTF-8" standalone="yes"?> + * <list> + * <nodeProperties> + * <node> + * <id>00:00:00:00:00:00:00:02</id> + * <type>OF</type> + * </node> + * <properties> + * <tables> + * <value>-1</value> + * </tables> + * <description> + * <value>Switch2</value> + * </description> + * <actions> + * <value>4095</value> + * </actions> + * <macAddress> + * <value>00:00:00:00:00:02</value> + * </macAddress> + * <capabilities> + * <value>199</value> + * </capabilities> + * <timeStamp> + * <value>1377291227877</value> + * <name>connectedSince</name> + * </timeStamp> + * <buffers> + * <value>256</value> + * </buffers> + * </properties> + * </nodeProperties> + * </list> + * + * Response in JSON: + * {"nodeProperties":[{"node":{"id":"00:00:00:00:00:00:00:02","type":"OF"},"properties":{"tables":{"value":"-1"}, + * "description":{"value":"None"},"actions":{"value":"4095"},"macAddress":{"value":"00:00:00:00:00:02"},"capabilities" + * :{"value":"199"},"timeStamp":{"value":"1377291227877","name":"connectedSince"},"buffers":{"value":"256"}}}]} + * + **/ @Path("/{containerName}/nodes") @GET @@ -117,10 +169,15 @@ public class SwitchNorthbound { @TypeHint(Nodes.class) @StatusCodes({ @ResponseCode(code = 200, condition = "Operation successful"), + @ResponseCode(code = 401, condition = "User not authorized to perform this operation"), @ResponseCode(code = 404, condition = "The containerName is not found"), @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) public Nodes getNodes(@PathParam("containerName") String containerName) { + if (!isValidContainer(containerName)) { + throw new ResourceNotFoundException("Container " + containerName + " does not exist."); + } + if (!NorthboundUtils.isAuthorized( getUserName(), containerName, Privilege.READ, this)) { throw new UnauthorizedException( @@ -137,7 +194,7 @@ public class SwitchNorthbound { List
+ * + * Example: + * + * RequestURL: + * http://localhost:8080/controller/nb/v2/switchmanager/default/node/OF/00:00:00:00:00:00:00:03/property/description/Switch3 + * + **/ - @Path("/{containerName}/node/{nodeType}/{nodeId}/property/{propName}/{propValue}") + @Path("/{containerName}/node/{nodeType}/{nodeId}/property/{propertyName}/{propertyValue}") @PUT @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @TypeHint(Response.class) @StatusCodes({ - @ResponseCode(code = 200, condition = "Operation successful"), - @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"), + @ResponseCode(code = 201, condition = "Operation successful"), + @ResponseCode(code = 400, condition = "The nodeId or configuration is invalid"), + @ResponseCode(code = 401, condition = "User not authorized to perform this operation"), + @ResponseCode(code = 404, condition = "The Container Name or node or configuration name is not found"), + @ResponseCode(code = 406, condition = "The property cannot be configured in non-default container"), + @ResponseCode(code = 409, condition = "Unable to update configuration due to cluster conflict or conflicting description property"), @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") }) public Response addNodeProperty( + @Context UriInfo uriInfo, @PathParam("containerName") String containerName, @PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId, - @PathParam("propName") String propName, - @PathParam("propValue") String propValue) { + @PathParam("propertyName") String propertyName, + @PathParam("propertyValue") String propertyValue) { + if (!isValidContainer(containerName)) { + throw new ResourceNotFoundException("Container " + containerName + " does not exist."); + } if (!NorthboundUtils.isAuthorized( getUserName(), containerName, Privilege.WRITE, this)) { throw new UnauthorizedException( "User is not authorized to perform this operation on container " + containerName); } - handleDefaultDisabled(containerName); - ISwitchManager switchManager = getIfSwitchManagerService(containerName); if (switchManager == null) { throw new ServiceUnavailableException("Switch Manager " @@ -206,40 +281,57 @@ public class SwitchNorthbound { handleNodeAvailability(containerName, nodeType, nodeId); Node node = Node.fromString(nodeType, nodeId); - - Property prop = switchManager.createProperty(propName, propValue); + Property prop = switchManager.createProperty(propertyName, propertyValue); if (prop == null) { - throw new ResourceNotFoundException( - RestMessages.INVALIDDATA.toString()); - } - - switchManager.setNodeProp(node, prop); - return Response.status(Response.Status.CREATED).build(); + throw new ResourceNotFoundException("Property with name " + propertyName + " does not exist."); + } + SwitchConfig switchConfig = switchManager.getSwitchConfig(node.toString()); + Map
+ * + * Example: + * + * RequestURL: + * http://localhost:8080/controller/nb/v2/switchmanager/default/node/OF/00:00:00:00:00:00:00:03/property/forwarding + * + **/ @Path("/{containerName}/node/{nodeType}/{nodeId}/property/{propertyName}") @DELETE @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @StatusCodes({ - @ResponseCode(code = 200, condition = "Operation successful"), + @ResponseCode(code = 204, condition = "Property removed successfully"), + @ResponseCode(code = 400, condition = "The nodeId or configuration is invalid"), + @ResponseCode(code = 401, condition = "User not authorized to perform this operation"), @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"), + @ResponseCode(code = 409, condition = "Unable to delete property due to cluster conflict"), @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") }) public Response deleteNodeProperty( @PathParam("containerName") String containerName, @@ -247,14 +339,15 @@ public class SwitchNorthbound { @PathParam("nodeId") String nodeId, @PathParam("propertyName") String propertyName) { + if (!isValidContainer(containerName)) { + throw new ResourceNotFoundException("Container " + containerName + " does not exist."); + } if (!NorthboundUtils.isAuthorized( getUserName(), containerName, Privilege.WRITE, this)) { throw new UnauthorizedException( "User is not authorized to perform this operation on container " + containerName); } - handleDefaultDisabled(containerName); - ISwitchManager switchManager = getIfSwitchManagerService(containerName); if (switchManager == null) { throw new ServiceUnavailableException("Switch Manager " @@ -263,30 +356,87 @@ public class SwitchNorthbound { handleNodeAvailability(containerName, nodeType, nodeId); Node node = Node.fromString(nodeType, nodeId); - Status ret = switchManager.removeNodeProp(node, propertyName); - if (ret.isSuccess()) { - return Response.ok().build(); + + SwitchConfig switchConfig = switchManager.getSwitchConfig(node.toString()); + Status status; + if (switchConfig == null) { + status = new Status(StatusCode.NOTFOUND, "Switch Configuration does not exist"); + } else { + Map
+ * + * Example: + * + * RequestURL: + * http://localhost:8080/controller/nb/v2/switchmanager/default/node/OF/00:00:00:00:00:00:00:01 + * + * Response in XML: + * <?xml version="1.0" encoding="UTF-8" standalone="yes"?> + * <list> + * <nodeConnectorProperties> + * <nodeconnector> + * <node> + * <id>00:00:00:00:00:00:00:01</id> + * <type>OF</type> + * </node> + * <id>2</id> + * <type>OF</type> + * </nodeconnector> + * <properties> + * <state> + * <value>1</value> + * </state> + * <config> + * <value>1</value> + * </config> + * <name> + * <value>L1_2-C2_1</value> + * </name> + * </properties> + * </nodeConnectorProperties> + * </list> + * + * Response in JSON: + * {"nodeConnectorProperties":[{"nodeconnector":{"node":{"id":"00:00:00:00:00:00:00:01","type":"OF"},"id":"2","type":"OF"}, + * "properties":{"state":{"value":"1"},"config":{"value":"1"},"name":{"value":"L1_2-C2_1"}}}]} + * + **/ @Path("/{containerName}/node/{nodeType}/{nodeId}") @GET @@ -294,6 +444,7 @@ public class SwitchNorthbound { @TypeHint(NodeConnectors.class) @StatusCodes({ @ResponseCode(code = 200, condition = "Operation successful"), + @ResponseCode(code = 401, condition = "User not authorized to perform this operation"), @ResponseCode(code = 404, condition = "The containerName is not found"), @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) public NodeConnectors getNodeConnectors( @@ -301,6 +452,9 @@ public class SwitchNorthbound { @PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId) { + if (!isValidContainer(containerName)) { + throw new ResourceNotFoundException("Container " + containerName + " does not exist."); + } if (!NorthboundUtils.isAuthorized( getUserName(), containerName, Privilege.READ, this)) { throw new UnauthorizedException( @@ -338,47 +492,67 @@ public class SwitchNorthbound { } /** - * Add a Name/Bandwidth property to a node connector + * Add node-connector property to a node connector. This method returns a + * non-successful response if a node connector by the given name already + * exists. * * @param containerName - * Name of the Container + * Name of the Container (Eg. 'default') * @param nodeType - * Type of the node being programmed + * Type of the node being programmed (Eg. 'OF') * @param nodeId * Node Identifier as specified by * {@link org.opendaylight.controller.sal.core.Node} + * (Eg. '00:00:00:00:00:00:00:03') * @param nodeConnectorType - * Type of the node connector being programmed + * Type of the node connector being programmed (Eg. 'OF') * @param nodeConnectorId * NodeConnector Identifier as specified by * {@link org.opendaylight.controller.sal.core.NodeConnector} - * @param propName + * (Eg. '2') + * @param propertyName * Name of the Property specified by * {@link org.opendaylight.controller.sal.core.Property} and its * extended classes - * @param propValue + * Property that can be configured is bandwidth + * @param propertyValue * Value of the Property specified by * {@link org.opendaylight.controller.sal.core.Property} and its * extended classes * @return Response as dictated by the HTTP Response Status code + * + *
+ * + * Example: + * + * RequestURL: + * http://localhost:8080/controller/nb/v2/switchmanager/default/nodeconnector/OF/00:00:00:00:00:00:00:01/OF/2/property/bandwidth/1 + * + **/ - @Path("/{containerName}/nodeconnector/{nodeType}/{nodeId}/{nodeConnectorType}/{nodeConnectorId}/property/{propName}/{propValue}") + @Path("/{containerName}/nodeconnector/{nodeType}/{nodeId}/{nodeConnectorType}/{nodeConnectorId}/property/{propertyName}/{propertyValue}") @PUT @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @StatusCodes({ - @ResponseCode(code = 200, condition = "Operation successful"), + @ResponseCode(code = 201, condition = "Operation successful"), + @ResponseCode(code = 401, condition = "User not authorized to perform this operation"), @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"), + @ResponseCode(code = 409, condition = "Unable to add property due to cluster conflict"), @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") }) public Response addNodeConnectorProperty( + @Context UriInfo uriInfo, @PathParam("containerName") String containerName, @PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId, @PathParam("nodeConnectorType") String nodeConnectorType, @PathParam("nodeConnectorId") String nodeConnectorId, - @PathParam("propName") String propName, - @PathParam("propValue") String propValue) { + @PathParam("propertyName") String propertyName, + @PathParam("propertyValue") String propertyValue) { + if (!isValidContainer(containerName)) { + throw new ResourceNotFoundException("Container " + containerName + " does not exist."); + } if (!NorthboundUtils.isAuthorized( getUserName(), containerName, Privilege.WRITE, this)) { throw new UnauthorizedException( @@ -386,8 +560,6 @@ public class SwitchNorthbound { + containerName); } - handleDefaultDisabled(containerName); - ISwitchManager switchManager = getIfSwitchManagerService(containerName); if (switchManager == null) { throw new ServiceUnavailableException("Switch Manager " @@ -402,7 +574,7 @@ public class SwitchNorthbound { NodeConnector nc = NodeConnector .fromStringNoNode(nodeConnectorType, nodeConnectorId, node); - Property prop = switchManager.createProperty(propName, propValue); + Property prop = switchManager.createProperty(propertyName, propertyValue); if (prop == null) { throw new ResourceNotFoundException( RestMessages.INVALIDDATA.toString()); @@ -410,7 +582,7 @@ public class SwitchNorthbound { Status ret = switchManager.addNodeConnectorProp(nc, prop); if (ret.isSuccess()) { - return Response.status(Response.Status.CREATED).build(); + return Response.created(uriInfo.getRequestUri()).build(); } throw new InternalServerErrorException(ret.getDescription()); } @@ -419,29 +591,41 @@ public class SwitchNorthbound { * Delete a property of a node connector * * @param containerName - * Name of the Container + * Name of the Container (Eg. 'default') * @param nodeType - * Type of the node being programmed + * Type of the node being programmed (Eg. 'OF') * @param nodeId * Node Identifier as specified by * {@link org.opendaylight.controller.sal.core.Node} + * (Eg. '00:00:00:00:00:00:00:01') * @param nodeConnectorType - * Type of the node connector being programmed + * Type of the node connector being programmed (Eg. 'OF') * @param nodeConnectorId * NodeConnector Identifier as specified by * {@link org.opendaylight.controller.sal.core.NodeConnector} + * (Eg. '1') * @param propertyName * Name of the Property specified by * {@link org.opendaylight.controller.sal.core.Property} and its - * extended classes + * extended classes. Property that can be deleted is bandwidth * @return Response as dictated by the HTTP Response Status code + * + *
+ * + * Example: + * + * RequestURL: + * http://localhost:8080/controller/nb/v2/switchmanager/default/nodeconnector/OF/00:00:00:00:00:00:00:01/OF/2/property/bandwidth + * + **/ @Path("/{containerName}/nodeconnector/{nodeType}/{nodeId}/{nodeConnectorType}/{nodeConnectorId}/property/{propertyName}") @DELETE @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @StatusCodes({ - @ResponseCode(code = 200, condition = "Operation successful"), + @ResponseCode(code = 204, condition = "Property removed successfully"), + @ResponseCode(code = 401, condition = "User not authorized to perform this operation"), @ResponseCode(code = 404, condition = "The Container Name or nodeId or configuration name is not found"), @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") }) public Response deleteNodeConnectorProperty( @@ -452,6 +636,9 @@ public class SwitchNorthbound { @PathParam("nodeConnectorId") String nodeConnectorId, @PathParam("propertyName") String propertyName) { + if (!isValidContainer(containerName)) { + throw new ResourceNotFoundException("Container " + containerName + " does not exist."); + } if (!NorthboundUtils.isAuthorized( getUserName(), containerName, Privilege.WRITE, this)) { throw new UnauthorizedException( @@ -459,8 +646,6 @@ public class SwitchNorthbound { + containerName); } - handleDefaultDisabled(containerName); - ISwitchManager switchManager = getIfSwitchManagerService(containerName); if (switchManager == null) { throw new ServiceUnavailableException("Switch Manager " @@ -476,134 +661,43 @@ public class SwitchNorthbound { .fromStringNoNode(nodeConnectorType, nodeConnectorId, node); Status ret = switchManager.removeNodeConnectorProp(nc, propertyName); if (ret.isSuccess()) { - return Response.ok().build(); + NorthboundUtils.auditlog("Node Connector Property", username, "removed", nc + " from " + nodeConnectorId, containerName); + return Response.noContent().build(); } throw new ResourceNotFoundException(ret.getDescription()); } - /* *//** - * Retrieve a list of Span ports that were configured previously. - * - * @param containerName - * Name of the Container - * @return list of - * {@link org.opendaylight.controller.switchmanager.SpanConfig} - * resources - */ - /* - * @Path("/span-config/{containerName}") - * - * @GET - * - * @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - * - * @StatusCodes( { - * - * @ResponseCode(code = 200, condition = "Operation successful"), - * - * @ResponseCode(code = 404, condition = "The containerName is not found"), - * - * @ResponseCode(code = 503, condition = - * "One or more of Controller Services are unavailable") }) public - * List
* - * @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + * Example: * - * @StatusCodes( { + * RequestURL: + * http://localhost:8080/controller/nb/v2/switchmanager/default/save * - * @ResponseCode(code = 200, condition = "Operation successful"), - * - * @ResponseCode(code = 404, condition = "The containerName is not found"), - * - * @ResponseCode(code = 503, condition = - * "One or more of Controller Services are unavailable") }) public Response - * addSpanConfig(@PathParam("containerName") String containerName, - * - * @TypeHint(SubnetConfig.class) JAXBElement*/ - /* - * @Path("/span-config/{containerName}") - * - * @DELETE - * - * @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - * - * @StatusCodes( { - * - * @ResponseCode(code = 200, condition = "Operation successful"), - * - * @ResponseCode(code = 404, condition = "The containerName is not found"), - * - * @ResponseCode(code = 503, condition = - * "One or more of Controller Services are unavailable") }) public Response - * deleteSpanConfig(@PathParam("containerName") String containerName, - * - * @TypeHint(SubnetConfig.class) JAXBElementconfig) { - * ISwitchManager switchManager = (ISwitchManager) - * getIfSwitchManagerService(containerName); if (switchManager == null) { - * throw new ServiceUnavailableException("Switch Manager " + - * RestMessages.SERVICEUNAVAILABLE.toString()); } - * - * String ret = switchManager.addSpanConfig(config.getValue()); if - * (ret.equals(ReturnString.SUCCESS.toString())) { return - * Response.status(Response.Status.CREATED).build(); } throw new - * InternalServerErrorException(ret); } - *//** - * Delete a span configuration - * - * @param containerName - * Name of the Container - * @param config - * {@link org.opendaylight.controller.switchmanager.SpanConfig} - * in JSON or XML format - * @return Response as dictated by the HTTP Response Status code + *