[Kimchi-devel] [PATCHv8 1/8] Support params for GET method

lvroyce0210 at gmail.com lvroyce0210 at gmail.com
Sun Jan 19 15:28:43 UTC 2014


From: Royce Lv <lvroyce at linux.vnet.ibm.com>

GET filter parameter will take effect in two places:
  1. process of query resources
  2. final resource infomation filtering
If you are adding some collection of get param,
pls explicity add its param to API.json and wrap its model
to accept filter param.
Then we can call it like:
    GET /collection?filter_field=value

Signed-off-by: Royce Lv <lvroyce at linux.vnet.ibm.com>
---
 src/kimchi/control/base.py           | 24 ++++++++++++++++--------
 src/kimchi/control/storagepools.py   |  4 ++--
 src/kimchi/control/storagevolumes.py |  2 +-
 src/kimchi/control/utils.py          |  7 +++++++
 4 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/src/kimchi/control/base.py b/src/kimchi/control/base.py
index 185c8d8..ce3101d 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, get_query_params, 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,10 @@ class Collection(object):
 
         return res.get()
 
-    def _get_resources(self):
+    def _get_resources(self, filter_params):
         try:
             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,19 +234,27 @@ 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)
+            if all(key not in res.data or res.data[key] == val \
+                   for key, val in filter_params.iteritems()):
+                data.append(res.data)
+        return data
+
+    def get(self, filter_params):
+        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:
-                return self.get()
+                filter_params = get_query_params()
+                validate_params(filter_params, self, 'get_list')
+                return self.get(filter_params)
             except InvalidOperation, param:
                 error = "Invalid operation: '%s'" % param
                 raise cherrypy.HTTPError(400, error)
diff --git a/src/kimchi/control/storagepools.py b/src/kimchi/control/storagepools.py
index 782f5a6..e3236a7 100644
--- a/src/kimchi/control/storagepools.py
+++ b/src/kimchi/control/storagepools.py
@@ -63,9 +63,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/storagevolumes.py b/src/kimchi/control/storagevolumes.py
index d541807..cd15bcc 100644
--- a/src/kimchi/control/storagevolumes.py
+++ b/src/kimchi/control/storagevolumes.py
@@ -70,7 +70,7 @@ class IsoVolumes(Collection):
         super(IsoVolumes, self).__init__(model)
         self.pool = pool
 
-    def get(self):
+    def get(self, filter_params):
         res_list = []
         try:
             get_list = getattr(self.model, model_fn(self, 'get_list'))
diff --git a/src/kimchi/control/utils.py b/src/kimchi/control/utils.py
index 814ba20..28733e2 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 get_query_params():
+    return cherrypy.request.params
 
 def internal_redirect(url):
     raise cherrypy.InternalRedirect(url.encode("utf-8"))
@@ -98,6 +100,11 @@ def validate_params(params, instance, action):
     validator = Draft3Validator(api_schema, format_checker=FormatChecker())
     request = {operation: params}
 
+    if (params and action in ['get_list'] and
+        operation not in validator.schema['properties']):
+        # get_list method does not allow parameter by default
+        raise InvalidParameter("%s does not support param %s" % (operation, params))
+
     try:
         validator.validate(request)
     except ValidationError:
-- 
1.8.1.2




More information about the Kimchi-devel mailing list