X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnorthbound%2Ftopology%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Ftopology%2Fnorthbound%2FTopologyNorthboundJAXRS.java;h=427aa1c1deaaf98c86fa3ecd072757bc6331892c;hb=494d528befd3908cc1b5f1c7706d34414819ef03;hp=10480bc4ec3f153312b6d1f7cae0f0bf658772a1;hpb=59cc8f34c24d81a8890a94c11dedd4b21caa0adf;p=controller.git diff --git a/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyNorthboundJAXRS.java b/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyNorthboundJAXRS.java index 10480bc4ec..427aa1c1de 100644 --- a/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyNorthboundJAXRS.java +++ b/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyNorthboundJAXRS.java @@ -17,7 +17,7 @@ import java.util.concurrent.ConcurrentMap; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; -import javax.ws.rs.POST; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -25,7 +25,6 @@ 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.xml.bind.JAXBElement; import org.codehaus.enunciate.jaxrs.ResponseCode; import org.codehaus.enunciate.jaxrs.StatusCodes; @@ -37,6 +36,7 @@ import org.opendaylight.controller.northbound.commons.exception.UnauthorizedExce import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils; import org.opendaylight.controller.sal.authorization.Privilege; import org.opendaylight.controller.sal.core.Edge; +import org.opendaylight.controller.sal.core.NodeConnector; import org.opendaylight.controller.sal.core.Property; import org.opendaylight.controller.sal.utils.ServiceHelper; import org.opendaylight.controller.sal.utils.Status; @@ -45,18 +45,14 @@ import org.opendaylight.controller.topologymanager.TopologyUserLinkConfig; /** * Topology Northbound REST API - * + * *
*
* Authentication scheme : HTTP Basic
* Authentication realm : opendaylight
* Transport : HTTP and HTTPS
*
- * HTTPS Authentication is disabled by default. Administrator can enable it in - * tomcat-server.xml after adding a proper keystore / SSL certificate from a - * trusted authority.
- * More info : - * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration + * HTTPS Authentication is disabled by default. */ @Path("/") @@ -66,7 +62,9 @@ public class TopologyNorthboundJAXRS { @Context public void setSecurityContext(SecurityContext context) { - username = context.getUserPrincipal().getName(); + if (context != null && context.getUserPrincipal() != null) { + username = context.getUserPrincipal().getName(); + } } protected String getUserName() { @@ -74,41 +72,191 @@ public class TopologyNorthboundJAXRS { } /** - * + * * Retrieve the Topology - * + * * @param containerName - * The container for which we want to retrieve the topology - * - * @return A List of EdgeProps each EdgeProp represent an Edge of the grap + * The container for which we want to retrieve the topology (Eg. + * 'default') + * + * @return A List of EdgeProps each EdgeProp represent an Edge of the graph * with the corresponding properties attached to it. + * + *
+     *
+     * Example:
+     *
+     * Request URL:
+     * http://localhost:8080/controller/nb/v2/topology/default
+     *
+     * Response body in XML:
+     * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+     * <topology>
+     *     <edgeProperties>
+     *         <edge>
+     *             <tailNodeConnector>
+     *                 <node>
+     *                     <id>00:00:00:00:00:00:00:02</id>
+     *                     <type>OF</type>
+     *                 </node>
+     *                 <id>2</id>
+     *                 <type>OF</type>
+     *             </tailNodeConnector>
+     *             <headNodeConnector>
+     *                 <node>
+     *                     <id>00:00:00:00:00:00:00:51</id>
+     *                     <type>OF</type>
+     *                 </node>
+     *                 <id>2</id>
+     *                 <type>OF</type>
+     *             </headNodeConnector>
+     *         </edge>
+     *         <properties>
+     *             <state>
+     *                 <value>1</value>
+     *             </state>
+     *             <config>
+     *                 <value>1</value>
+     *             </config>
+     *             <name>
+     *                 <value>C1_2-L2_2</value>
+     *             </name>
+     *             <timeStamp>
+     *                 <value>1377279422032</value>
+     *                 <name>creation</name>
+     *             </timeStamp>
+     *         </properties>
+     *     </edgeProperties>
+     *     <edgeProperties>
+     *         <edge>
+     *             <tailNodeConnector>
+     *                 <node>
+     *                     <id>00:00:00:00:00:00:00:51</id>
+     *                     <type>OF</type>
+     *                 </node>
+     *                 <id>2</id>
+     *                 <type>OF</type>
+     *             </tailNodeConnector>
+     *             <headNodeConnector>
+     *                 <node>
+     *                     <id>00:00:00:00:00:00:00:02</id>
+     *                     <type>OF</type>
+     *                 </node>
+     *                 <id>2</id>
+     *                 <type>OF</type>
+     *             </headNodeConnector>
+     *         </edge>
+     *         <properties>
+     *             <state>
+     *                 <value>1</value>
+     *             </state>
+     *             <name>
+     *                 <value>L2_2-C1_2</value>
+     *             </name>
+     *             <config>
+     *                 <value>1</value>
+     *             </config>
+     *             <timeStamp>
+     *                 <value>1377279423564</value>
+     *                 <name>creation</name>
+     *             </timeStamp>
+     *         </properties>
+     *     </edgeProperties>
+     * </topology>
+     *
+     * Response body in JSON:
+     * {
+     *    "edgeProperties":[
+     *       {
+     *          "edge":{
+     *             "tailNodeConnector":{
+     *                "node":{
+     *                   "id":"00:00:00:00:00:00:00:02",
+     *                   "type":"OF"
+     *                },
+     *                "id":"2",
+     *                "type":"OF"
+     *             },
+     *             "headNodeConnector":{
+     *                "node":{
+     *                   "id":"00:00:00:00:00:00:00:51",
+     *                   "type":"OF"
+     *                },
+     *                "id":"2",
+     *                "type":"OF"
+     *             }
+     *          },
+     *          "properties":{
+     *             "timeStamp": {
+     *                "value": 1379527162648,
+     *                "name": "creation",
+     *             },
+     *             "name": {
+     *                "value": "s2-eth3"
+     *             },
+     *             "state": {
+     *                "value": 1
+     *             },
+     *             "config": {
+     *                "value": 1
+     *             },
+     *             "bandwidth": {
+     *                "value": 10000000000
+     *             }
+     *          }
+     *       },
+     *       {
+     *          "edge":{
+     *             "tailNodeConnector":{
+     *                "node":{
+     *                   "id":"00:00:00:00:00:00:00:51",
+     *                   "type":"OF"
+     *                },
+     *                "id":"2",
+     *                "type":"OF"
+     *             },
+     *             "headNodeConnector":{
+     *                "node":{
+     *                   "id":"00:00:00:00:00:00:00:02",
+     *                   "type":"OF"
+     *                },
+     *                "id":"2",
+     *                "type":"OF"
+     *             }
+     *           },
+     *           "properties":{
+     *             "timeStamp": {
+     *                "value": 1379527162648,
+     *                "name": "creation",
+     *             }
+     *          }
+     *        }
+     *     ]
+     *  }
+     * 
*/ @Path("/{containerName}") @GET @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @TypeHint(Topology.class) - @StatusCodes({ @ResponseCode(code = 404, condition = "The Container Name passed was not found") }) + @StatusCodes({ @ResponseCode(code = 404, condition = "The Container Name was not found") }) public Topology getTopology(@PathParam("containerName") String containerName) { - if (!NorthboundUtils.isAuthorized( - getUserName(), containerName, Privilege.READ, this)) { - throw new UnauthorizedException( - "User is not authorized to perform this operation on container " - + containerName); + if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) { + throw new UnauthorizedException("User is not authorized to perform this operation on container " + + containerName); } - ITopologyManager topologyManager = (ITopologyManager) ServiceHelper - .getInstance(ITopologyManager.class, containerName, this); + ITopologyManager topologyManager = (ITopologyManager) ServiceHelper.getInstance(ITopologyManager.class, + containerName, this); if (topologyManager == null) { - throw new ResourceNotFoundException( - RestMessages.NOCONTAINER.toString()); + throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString()); } Map> topo = topologyManager.getEdges(); if (topo != null) { List res = new ArrayList(); for (Map.Entry> entry : topo.entrySet()) { - EdgeProperties el = new EdgeProperties(entry.getKey(), - entry.getValue()); + EdgeProperties el = new EdgeProperties(entry.getKey(), entry.getValue()); res.add(el); } return new Topology(res); @@ -119,38 +267,65 @@ public class TopologyNorthboundJAXRS { /** * Retrieve the user configured links - * + * * @param containerName * The container for which we want to retrieve the user links - * + * (Eg. 'default') + * * @return A List of user configured links + * + *
+     *
+     * Example:
+     *
+     * Request URL:
+     * http://localhost:8080/controller/nb/v2/topology/default/userLinks
+     *
+     * Response body in XML:
+     * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+     * <list>
+     * <userLinks>
+     * <status>Success</status>
+     * <name>link1</name>
+     * <srcNodeConnector>OF|2@OF|00:00:00:00:00:00:00:02</srcNodeConnector>
+     * <dstNodeConnector>OF|2@OF|00:00:00:00:00:00:00:51</dstNodeConnector>
+     * </userLinks>
+     * </list>
+     *
+     * Response body in JSON:
+    * {
+     *   "userLinks": [
+     *    {
+     *      "status": "Success",
+     *      "name": "link1",
+     *      "srcNodeConnector": "OF|2@OF|00:00:00:00:00:00:00:02",
+     *      "dstNodeConnector": "OF|5@OF|00:00:00:00:00:00:00:05"
+     *    }
+     *  ]
+     * }
+     *
+     * 
*/ - @Path("/{containerName}/userLink") + @Path("/{containerName}/userLinks") @GET @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @TypeHint(TopologyUserLinks.class) - @StatusCodes({ @ResponseCode(code = 404, condition = "The Container Name passed was not found") }) - public TopologyUserLinks getUserLinks( - @PathParam("containerName") String containerName) { - - if (!NorthboundUtils.isAuthorized( - getUserName(), containerName, Privilege.READ, this)) { - throw new UnauthorizedException( - "User is not authorized to perform this operation on container " - + containerName); + @StatusCodes({ @ResponseCode(code = 404, condition = "The Container Name was not found") }) + public TopologyUserLinks getUserLinks(@PathParam("containerName") String containerName) { + + if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) { + throw new UnauthorizedException("User is not authorized to perform this operation on container " + + containerName); } - ITopologyManager topologyManager = (ITopologyManager) ServiceHelper - .getInstance(ITopologyManager.class, containerName, this); + ITopologyManager topologyManager = (ITopologyManager) ServiceHelper.getInstance(ITopologyManager.class, + containerName, this); if (topologyManager == null) { - throw new ResourceNotFoundException( - RestMessages.NOCONTAINER.toString()); + throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString()); } - ConcurrentMap userLinks = topologyManager - .getUserLinks(); + ConcurrentMap userLinks = topologyManager.getUserLinks(); if ((userLinks != null) && (userLinks.values() != null)) { - List res = new ArrayList( - userLinks.values()); + List res = new ArrayList(userLinks.values()); return new TopologyUserLinks(res); } @@ -159,42 +334,74 @@ public class TopologyNorthboundJAXRS { /** * Add an User Link - * + * * @param containerName - * Name of the Container. The base Container is "default". + * Name of the Container (Eg. 'default') + * @param name + * Name of the user link * @param TopologyUserLinkConfig * in JSON or XML format * @return Response as dictated by the HTTP Response Status code + * + *
+     *
+     * Example:
+     *
+     * Request URL:
+     * http://localhost:8080/controller/nb/v2/topology/default/userLink/link1
+     *
+     * Request body in XML:
+     * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+     * <topologyUserLinkConfig>
+     * <status>Success</status>
+     * <name>link1</name>
+     * <srcNodeConnector>OF|2@OF|00:00:00:00:00:00:00:02</srcNodeConnector>
+     * <dstNodeConnector>OF|2@OF|00:00:00:00:00:00:00:51</dstNodeConnector>
+     * </topologyUserLinkConfig>
+     *
+     * Request body in JSON:
+     * {
+     *    "status":"Success",
+     *    "name":"link1",
+     *    "srcNodeConnector":"OF|2@OF|00:00:00:00:00:00:00:02",
+     *    "dstNodeConnector":"OF|2@OF|00:00:00:00:00:00:00:51"
+     * }
+     *
+     * 
*/ - - @Path("/{containerName}/userLink") - @POST + @Path("/{containerName}/userLink/{name}") + @PUT @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @StatusCodes({ - @ResponseCode(code = 201, condition = "User Link added successfully"), - @ResponseCode(code = 404, condition = "The Container Name passed was not found"), - @ResponseCode(code = 409, condition = "Failed to add User Link due to Conflicting Name"), - @ResponseCode(code = 500, condition = "Failed to add User Link. Failure Reason included in HTTP Error response"), - @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") }) - public Response addUserLink( - @PathParam(value = "containerName") String containerName, - @TypeHint(TopologyUserLinkConfig.class) JAXBElement userLinkConfig) { - - if (!NorthboundUtils.isAuthorized( - getUserName(), containerName, Privilege.WRITE, this)) { - throw new UnauthorizedException( - "User is not authorized to perform this operation on container " - + containerName); + @ResponseCode(code = 201, condition = "User Link added successfully"), + @ResponseCode(code = 404, condition = "The Container Name was not found"), + @ResponseCode(code = 409, condition = "Failed to add User Link due to Conflicting Name"), + @ResponseCode(code = 500, condition = "Failed to add User Link. Failure Reason included in HTTP Error response"), + @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") }) + public Response addUserLink(@PathParam(value = "containerName") String containerName, + @PathParam(value = "name") String name, + @TypeHint(TopologyUserLinkConfig.class) TopologyUserLinkConfig userLinkConfig) { + + if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) { + throw new UnauthorizedException("User is not authorized to perform this operation on container " + + containerName); } - ITopologyManager topologyManager = (ITopologyManager) ServiceHelper - .getInstance(ITopologyManager.class, containerName, this); + ITopologyManager topologyManager = (ITopologyManager) ServiceHelper.getInstance(ITopologyManager.class, + containerName, this); if (topologyManager == null) { - throw new ResourceNotFoundException( - RestMessages.NOCONTAINER.toString()); + throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString()); } - Status status = topologyManager.addUserLink(userLinkConfig.getValue()); + Status status = topologyManager.addUserLink(userLinkConfig); if (status.isSuccess()) { + NorthboundUtils + .auditlog( + "User Link",username,"added", userLinkConfig.getName() + " from " + NorthboundUtils.getPortName( + NodeConnector.fromString(userLinkConfig.getSrcNodeConnector()), + containerName, this) + " to " + + NorthboundUtils.getPortName(NodeConnector.fromString + (userLinkConfig.getDstNodeConnector()),containerName, this), containerName); return Response.status(Response.Status.CREATED).build(); } throw new InternalServerErrorException(status.getDescription()); @@ -202,43 +409,46 @@ public class TopologyNorthboundJAXRS { /** * Delete an User Link - * + * * @param containerName - * Name of the Container. The base Container is "default". + * Name of the Container (Eg. 'default') * @param name - * Name of the Link Configuration + * Name of the Link Configuration (Eg. 'config1') * @return Response as dictated by the HTTP Response Status code + * + *
+     *
+     * Example:
+     *
+     * Request URL:
+     * http://localhost:8080/controller/nb/v2/topology/default/userLink/config1
+     *
+     * 
*/ - @Path("/{containerName}/userLink/{name}") @DELETE @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) - @StatusCodes({ - @ResponseCode(code = 200, condition = "Operation successful"), - @ResponseCode(code = 404, condition = "The Container Name or Link Configuration Name was not found"), - @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") }) - public Response deleteUserLink( - @PathParam("containerName") String containerName, - @PathParam("name") String name) { - - if (!NorthboundUtils.isAuthorized( - getUserName(), containerName, Privilege.WRITE, this)) { - throw new UnauthorizedException( - "User is not authorized to perform this operation on container " - + containerName); + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @StatusCodes({ @ResponseCode(code = 204, condition = "User link removed successfully"), + @ResponseCode(code = 404, condition = "The Container Name or Link Configuration Name was not found"), + @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") }) + public Response deleteUserLink(@PathParam("containerName") String containerName, @PathParam("name") String name) { + + if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) { + throw new UnauthorizedException("User is not authorized to perform this operation on container " + + containerName); } - ITopologyManager topologyManager = (ITopologyManager) ServiceHelper - .getInstance(ITopologyManager.class, containerName, this); + ITopologyManager topologyManager = (ITopologyManager) ServiceHelper.getInstance(ITopologyManager.class, + containerName, this); if (topologyManager == null) { - throw new ResourceNotFoundException( - RestMessages.NOCONTAINER.toString()); + throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString()); } Status ret = topologyManager.deleteUserLink(name); if (ret.isSuccess()) { - return Response.ok().build(); + NorthboundUtils.auditlog("User Link", username, "removed", name, containerName); + return Response.noContent().build(); } - throw new ResourceNotFoundException(ret.getDescription()); + return NorthboundUtils.getResponse(ret); } - }