On 01/13/2014 01:50 PM, Royce Lv wrote:
Sheldon,
   As we discussed, pls refer to demo decorator of PATCH 2/8. If you want to support GET_LIST of some function without change model.py, pls wrap it with my decorator and it will work. Also, if guys agree, I will put all these wrap in a single patchset.
Just a suggestion.

Though I prefer the entry of  GET "method" to get and check query parameters, this is more simple.
 Then we can trust cherrypy without any test case for getting query parameters, And other developer do not need to get and check query parameters again.

You can use your way.


On 2014年01月11日 08:48, Sheldon wrote:
Not sure 'GET' method always mean "get_list"

I have tried just add validate_params at the entry of check 'GET', it can works well.


@@ -242,11 +245,13 @@ class Collection(object):
         return kimchi.template.render(get_class_name(self), data)
 
     @cherrypy.expose
-    def index(self, *args):
+    def index(self, *args, **argv):
         method = validate_method(('GET', 'POST'))
         if method == 'GET':
             try:
+                params = cherrypy.request.params
+                validate_params(params, self, 'get_list')
                 return self.get()
             except InvalidOperation, param:
                 error = "Invalid operation: '%s'" % param
                 raise cherrypy.HTTPError(400, error)

add a test for
/storagepools?pool_type=dir
and
storagepools/default/storagevolumes?volume_type=file

diff --git a/src/kimchi/API.json b/src/kimchi/API.json
index 19b1c51..fe3a85a 100644
--- a/src/kimchi/API.json
+++ b/src/kimchi/API.json
@@ -73,6 +73,26 @@
                 }
             }
         },
+        "storagepools_get_list": {
+            "type": "object",
+            "properties": {
+                "pool_type": {
+                    "description": "type of storagepools",
+                    "type": "string",
+                    "pattern": "^dir$"
+                }
+            }
+        },
+        "storagevolumes_get_list": {
+            "type": "object",
+            "properties": {
+                "volume_type": {
+                    "description": "type of storagevolumes",
+                    "type": "string",
+                    "pattern": "^file$"
+                }
+            }
+        },
         "vms_create": {
             "type": "object",
             "properties": {





$ curl -u <user>:<password> -H 'Content-type: application/json' -H 'Accept: application/json' -X GET http//localhost:8000/storagepools?pool_type=dir
[
  {
    "available":27511504896,
    "source":{},
    "state":"active",
    "capacity":195949113344,
    "name":"default",
    "nr_volumes":2,
    "path":"/home/shhfeng/var/lib/libvirt/images",
    "allocated":168437608448,
    "autostart":true,
    "type":"dir"
  },
  {
    "state":"active",
    "type":"kimchi-iso",
    "name":"kimchi_isos"
  }
]
$ curl -u <user>:<password> -H 'Content-type: application/json' -H 'Accept: application/json' -X GET http//localhost:8000/storagepools?pool_type=dirxxx
{
  "reason":"The server encountered an unexpected condition which prevented it from fulfilling the request.",
  "code":"500 Internal Server Error",
  "call_stack":"Traceback (most recent call last):\n  File \"/usr/lib/python2.7/site-packages/cherrypy/_cprequest.py\", line 656, in respond\n    response.body = self.handler()\n  File \"/usr/lib/python2.7/site-packages/cherrypy/lib/encoding.py\", line 188, in __call__\n    self.body = self.oldhandler(*args, **kwargs)\n  File \"/usr/lib/python2.7/site-packages/cherrypy/_cpdispatch.py\", line 34, in __call__\n    return self.callable(*self.args, **self.kwargs)\n  File \"/home/shhfeng/work/workdir/kimchi/src/kimchi/control/base.py\", line 254, in index\n    validate_params(cherrypy.request.params, self, 'get_list')\n  File \"/home/shhfeng/work/workdir/kimchi/src/kimchi/control/utils.py\", line 105, in validate_params\n    e.message for e in validator.iter_errors(request)))\nInvalidParameter: u'dirxxx' does not match u'^dir$'\n"


$ curl -u <user>:<password> -H 'Content-type: application/json' -H 'Accept: application/json' -X GET http//localhost:8000/storagepools/default/storagevolumes?volume_type=file
[
  {
    "capacity":21474836480,
    "name":"RHEL6.5.img",
    "format":"qcow2",
    "allocation":5200818176,
    "path":"/home/shhfeng/var/lib/libvirt/images/RHEL6.5.img",
    "type":"file"
  },
  {
    "capacity":21474836480,
    "name":"RHEL6.5.img.back",
    "format":"qcow2",
    "allocation":3681751040,
    "path":"/home/shhfeng/var/lib/libvirt/images/RHEL6.5.img.back",
    "type":"file"
  }
]
$ curl -u <user>:<password> -H 'Content-type: application/json' -H 'Accept: application/json' -X GET http//localhost:8000/storagepools/default/storagevolumes?volume_type=filexxx
{
  "reason":"The server encountered an unexpected condition which prevented it from fulfilling the request.",
  "code":"500 Internal Server Error",
  "call_stack":"Traceback (most recent call last):\n  File \"/usr/lib/python2.7/site-packages/cherrypy/_cprequest.py\", line 656, in respond\n    response.body = self.handler()\n  File \"/usr/lib/python2.7/site-packages/cherrypy/lib/encoding.py\", line 188, in __call__\n    self.body = self.oldhandler(*args, **kwargs)\n  File \"/usr/lib/python2.7/site-packages/cherrypy/_cpdispatch.py\", line 34, in __call__\n    return self.callable(*self.args, **self.kwargs)\n  File \"/home/shhfeng/work/workdir/kimchi/src/kimchi/control/base.py\", line 254, in index\n    validate_params(cherrypy.request.params, self, 'get_list')\n  File \"/home/shhfeng/work/workdir/kimchi/src/kimchi/control/utils.py\", line 105, in validate_params\n    e.message for e in validator.iter_errors(request)))\nInvalidParameter: u'filexxx' does not match u'^file$'\n"



On 01/08/2014 11:50 PM, lvroyce0210@gmail.com wrote:
From: Royce Lv <lvroyce@linux.vnet.ibm.com>

Add support for passing params for GET method,
we will call it like:
    GET /vms?state=running

Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com>
---
 src/kimchi/control/base.py         | 26 +++++++++++++++++++-------
 src/kimchi/control/storagepools.py |  4 ++--
 src/kimchi/control/utils.py        |  2 ++
 3 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/src/kimchi/control/base.py b/src/kimchi/control/base.py
index 185c8d8..73b70fb 100644
--- a/src/kimchi/control/base.py
+++ b/src/kimchi/control/base.py
@@ -28,7 +28,7 @@ import urllib2

 import kimchi.template
 from kimchi.control.utils import get_class_name, internal_redirect, model_fn
-from kimchi.control.utils import parse_request, validate_method
+from kimchi.control.utils import parse_request, parse_param, validate_method
 from kimchi.control.utils import validate_params
 from kimchi.exception import InvalidOperation, InvalidParameter
 from kimchi.exception import MissingParameter, NotFoundError,  OperationFailed
@@ -212,10 +212,11 @@ class Collection(object):

         return res.get()

-    def _get_resources(self):
+    def _get_resources(self, filter_params):
         try:
+            validate_params(filter_params, self, 'get_list')
             get_list = getattr(self.model, model_fn(self, 'get_list'))
-            idents = get_list(*self.model_args)
+            idents = get_list(*self.model_args, **filter_params)
             res_list = []
             for ident in idents:
                 # internal text, get_list changes ident to unicode for sorted
@@ -234,15 +235,26 @@ class Collection(object):
             args = self.resource_args + [ident.decode("utf-8")]
             return self.resource(self.model, *args)

-    def get(self):
-        resources = self._get_resources()
+    def filter_data(self, resources, filter_params):
         data = []
         for res in resources:
-            data.append(res.data)
+            valid = True
+            for key, val in filter_params.items():
+                if not ( key in res.data and res.data[key] == val):
+                    valid = False
+                    break
+            if valid:
+                data.append(res.data)
+        return data
+
+    def get(self):
+        filter_params = parse_param()
+        resources = self._get_resources(filter_params)
+        data = self.filter_data(resources, filter_params)
         return kimchi.template.render(get_class_name(self), data)

     @cherrypy.expose
-    def index(self, *args):
+    def index(self, *args, **kwargs):
         method = validate_method(('GET', 'POST'))
         if method == 'GET':
             try:
diff --git a/src/kimchi/control/storagepools.py b/src/kimchi/control/storagepools.py
index 466b4b6..0df14c5 100644
--- a/src/kimchi/control/storagepools.py
+++ b/src/kimchi/control/storagepools.py
@@ -61,9 +61,9 @@ class StoragePools(Collection):

         return resp

-    def _get_resources(self):
+    def _get_resources(self, filter_params):
         try:
-            res_list = super(StoragePools, self)._get_resources()
+            res_list = super(StoragePools, self)._get_resources(filter_params)
             # Append reserved pools
             isos = getattr(self, ISO_POOL_NAME)
             isos.lookup()
diff --git a/src/kimchi/control/utils.py b/src/kimchi/control/utils.py
index c3c5f8e..4b3c4b0 100644
--- a/src/kimchi/control/utils.py
+++ b/src/kimchi/control/utils.py
@@ -81,6 +81,8 @@ def parse_request():
         raise cherrypy.HTTPError(415, "This API only supports"
                                       " 'application/json'")

+def parse_param():
+    return cherrypy.request.params

 def internal_redirect(url):
     raise cherrypy.InternalRedirect(url.encode("utf-8"))


-- 
Thanks and best regards!

Sheldon Feng(冯少合)<shaohef@linux.vnet.ibm.com>
IBM Linux Technology Center


_______________________________________________
Kimchi-devel mailing list
Kimchi-devel@ovirt.org
http://lists.ovirt.org/mailman/listinfo/kimchi-devel



-- 
Thanks and best regards!

Sheldon Feng(冯少合)<shaohef@linux.vnet.ibm.com>
IBM Linux Technology Center