Support for FIQL queries on REST retreive operations
[controller.git] / opendaylight / northbound / topology / src / main / java / org / opendaylight / controller / topology / northbound / TopologyNorthboundJAXRS.java
index 461f452d188611cb02f3d9312c2b58f6ea3f4f59..3773070504a0fa4be1e107e422793b52085217d2 100644 (file)
@@ -21,10 +21,12 @@ import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 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.ext.ContextResolver;
 
 import org.codehaus.enunciate.jaxrs.ResponseCode;
 import org.codehaus.enunciate.jaxrs.StatusCodes;
@@ -33,6 +35,7 @@ import org.opendaylight.controller.northbound.commons.RestMessages;
 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
+import org.opendaylight.controller.northbound.commons.query.QueryContext;
 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
 import org.opendaylight.controller.sal.authorization.Privilege;
 import org.opendaylight.controller.sal.core.Edge;
@@ -59,7 +62,14 @@ import org.opendaylight.controller.topologymanager.TopologyUserLinkConfig;
 public class TopologyNorthboundJAXRS {
 
     private String username;
+    private QueryContext queryContext;
 
+    @Context
+    public void setQueryContext(ContextResolver<QueryContext> queryCtxResolver) {
+      if (queryCtxResolver != null) {
+        queryContext = queryCtxResolver.getContext(QueryContext.class);
+      }
+    }
     @Context
     public void setSecurityContext(SecurityContext context) {
         if (context != null && context.getUserPrincipal() != null) {
@@ -86,10 +96,10 @@ public class TopologyNorthboundJAXRS {
      *
      * Example:
      *
-     * RequestURL:
+     * Request URL:
      * http://localhost:8080/controller/nb/v2/topology/default
      *
-     * Response in XML:
+     * Response body in XML:
      * &lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
      * &lt;topology&gt;
      *     &lt;edgeProperties&gt;
@@ -164,14 +174,75 @@ public class TopologyNorthboundJAXRS {
      *     &lt;/edgeProperties&gt;
      * &lt;/topology&gt;
      *
-     * Response 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":"1377278961017","name":"creation"}}},
-     * {"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":"1377278961018","name":"creation"}}}]}
-     *
+     * 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",
+     *             }
+     *          }
+     *        }
+     *     ]
+     *  }
      * </pre>
      */
     @Path("/{containerName}")
@@ -179,7 +250,8 @@ public class TopologyNorthboundJAXRS {
     @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) {
+    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 "
@@ -192,16 +264,21 @@ public class TopologyNorthboundJAXRS {
         }
 
         Map<Edge, Set<Property>> topo = topologyManager.getEdges();
-        if (topo != null) {
-            List<EdgeProperties> res = new ArrayList<EdgeProperties>();
-            for (Map.Entry<Edge, Set<Property>> entry : topo.entrySet()) {
-                EdgeProperties el = new EdgeProperties(entry.getKey(), entry.getValue());
-                res.add(el);
-            }
-            return new Topology(res);
+        if (topo == null) {
+            return null;
+        }
+        List<EdgeProperties> res = new ArrayList<EdgeProperties>();
+        for (Map.Entry<Edge, Set<Property>> entry : topo.entrySet()) {
+            EdgeProperties el = new EdgeProperties(entry.getKey(), entry.getValue());
+            res.add(el);
         }
+        Topology result = new Topology(res);
 
-        return null;
+        if (queryString != null) {
+            queryContext.createQuery(queryString, Topology.class)
+                .filter(result, EdgeProperties.class);
+        }
+        return result;
     }
 
     /**
@@ -217,23 +294,31 @@ public class TopologyNorthboundJAXRS {
      *
      * Example:
      *
-     * RequestURL:
+     * Request URL:
      * http://localhost:8080/controller/nb/v2/topology/default/userLinks
      *
-     * Response in XML:
+     * Response body in XML:
      * &lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
-     * &lt;topologyUserLinks&gt;
+     * &lt;list&gt;
      * &lt;userLinks&gt;
      * &lt;status&gt;Success&lt;/status&gt;
      * &lt;name&gt;link1&lt;/name&gt;
      * &lt;srcNodeConnector&gt;OF|2@OF|00:00:00:00:00:00:00:02&lt;/srcNodeConnector&gt;
      * &lt;dstNodeConnector&gt;OF|2@OF|00:00:00:00:00:00:00:51&lt;/dstNodeConnector&gt;
      * &lt;/userLinks&gt;
-     * &lt;/topologyUserLinks&gt;
+     * &lt;/list&gt;
      *
-     * Response in JSON:
-     * {"userLinks":{"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"}}
+     * 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"
+     *    }
+     *  ]
+     * }
      *
      * </pre>
      */
@@ -242,7 +327,8 @@ public class TopologyNorthboundJAXRS {
     @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) {
+    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 "
@@ -255,12 +341,16 @@ public class TopologyNorthboundJAXRS {
         }
 
         ConcurrentMap<String, TopologyUserLinkConfig> userLinks = topologyManager.getUserLinks();
-        if ((userLinks != null) && (userLinks.values() != null)) {
-            List<TopologyUserLinkConfig> res = new ArrayList<TopologyUserLinkConfig>(userLinks.values());
-            return new TopologyUserLinks(res);
+        if ((userLinks == null) || (userLinks.values() == null)) {
+            return null;
         }
-
-        return null;
+        TopologyUserLinks result = new TopologyUserLinks(
+                new ArrayList<TopologyUserLinkConfig>(userLinks.values()));
+        if (queryString != null) {
+            queryContext.createQuery(queryString, TopologyUserLinks.class)
+                .filter(result, TopologyUserLinkConfig.class);
+        }
+        return result;
     }
 
     /**
@@ -278,20 +368,25 @@ public class TopologyNorthboundJAXRS {
      *
      * Example:
      *
-     * RequestURL:
+     * Request URL:
      * http://localhost:8080/controller/nb/v2/topology/default/userLink/link1
      *
-     * Request in XML:
+     * Request body in XML:
      * &lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
-     * &lt;topologyUserLinks&gt;
+     * &lt;topologyUserLinkConfig&gt;
      * &lt;status&gt;Success&lt;/status&gt;
      * &lt;name&gt;link1&lt;/name&gt;
      * &lt;srcNodeConnector&gt;OF|2@OF|00:00:00:00:00:00:00:02&lt;/srcNodeConnector&gt;
      * &lt;dstNodeConnector&gt;OF|2@OF|00:00:00:00:00:00:00:51&lt;/dstNodeConnector&gt;
-     * &lt;/topologyUserLinks&gt;
+     * &lt;/topologyUserLinkConfig&gt;
      *
-     * Request 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"}
+     * 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"
+     * }
      *
      * </pre>
      */
@@ -346,7 +441,7 @@ public class TopologyNorthboundJAXRS {
      *
      * Example:
      *
-     * RequestURL:
+     * Request URL:
      * http://localhost:8080/controller/nb/v2/topology/default/userLink/config1
      *
      * </pre>