queryCtxResolver) {
+ if (queryCtxResolver != null) {
+ queryContext = queryCtxResolver.getContext(QueryContext.class);
+ }
+ }
+ @Context
+ public void setSecurityContext(SecurityContext context) {
+ if (context != null && context.getUserPrincipal() != null) {
+ username = context.getUserPrincipal().getName();
+ }
+ }
+
+ protected String getUserName() {
+ return username;
+ }
+
+ /**
+ *
+ * Retrieve the Topology
+ *
+ * @param containerName
+ * 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 was not found") })
+ public Topology getTopology(@PathParam("containerName") String containerName,
+ @QueryParam("_q") String queryString) {
+
+ 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);
+ if (topologyManager == null) {
+ throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
+ }
+
+ Map> topo = topologyManager.getEdges();
+ if (topo == null) {
+ return null;
+ }
+ List res = new ArrayList();
+ for (Map.Entry> entry : topo.entrySet()) {
+ EdgeProperties el = new EdgeProperties(entry.getKey(), entry.getValue());
+ res.add(el);
+ }
+ Topology result = new Topology(res);
+
+ if (queryString != null) {
+ queryContext.createQuery(queryString, Topology.class)
+ .filter(result, EdgeProperties.class);
+ }
+ return result;
+ }
+
+ /**
+ * 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}/userLinks")
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ @TypeHint(TopologyUserLinks.class)
+ @StatusCodes({ @ResponseCode(code = 404, condition = "The Container Name was not found") })
+ public TopologyUserLinks getUserLinks(@PathParam("containerName") String containerName,
+ @QueryParam("_q") String queryString) {
+
+ 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);
+ if (topologyManager == null) {
+ throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
+ }
+
+ ConcurrentMap userLinks = topologyManager.getUserLinks();
+ if ((userLinks == null) || (userLinks.values() == null)) {
+ return null;
+ }
+ TopologyUserLinks result = new TopologyUserLinks(
+ new ArrayList(userLinks.values()));
+ if (queryString != null) {
+ queryContext.createQuery(queryString, TopologyUserLinks.class)
+ .filter(result, TopologyUserLinkConfig.class);
+ }
+ return result;
+ }
+
+ /**
+ * Add an User Link
+ *
+ * @param containerName
+ * 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/{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 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);
+ if (topologyManager == null) {
+ throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
+ }
+
+ 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());
+ }
+
+ /**
+ * Delete an User Link
+ *
+ * @param containerName
+ * Name of the Container (Eg. 'default')
+ * @param name
+ * 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 })
+ @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);
+ if (topologyManager == null) {
+ throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
+ }
+
+ Status ret = topologyManager.deleteUserLink(name);
+ if (ret.isSuccess()) {
+ NorthboundUtils.auditlog("User Link", username, "removed", name, containerName);
+ return Response.noContent().build();
+ }
+ return NorthboundUtils.getResponse(ret);
+ }
+}