
From: Royce Lv <lvroyce@linux.vnet.ibm.com>
Add support for passing params for GET method, This include add param to get_list method, and filter the result with given params. we will call it like: GET /collection?filter_field=value With current implementation with a wrapper, we can easily support any collection query with param.
Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- src/kimchi/control/base.py | 28 ++++++++++++++++++++-------- src/kimchi/control/storagepools.py | 4 ++-- src/kimchi/control/storagevolumes.py | 2 +- src/kimchi/control/utils.py | 2 ++ 4 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/src/kimchi/control/base.py b/src/kimchi/control/base.py index 185c8d8..a477abb 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,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) For the methods doesn't support filter params, it will break if add a
On 01/14/2014 11:47 PM, lvroyce0210@gmail.com wrote: param in url.
res_list = [] for ident in idents: # internal text, get_list changes ident to unicode for sorted @@ -234,19 +234,31 @@ 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 key in res.data and res.data[key] != val: + valid = False + break + if valid:
if all(key in res.data and res.data[key] == val for key, val in filter_params.iteritems()): data.append(res.data)
+ data.append(res.data) + return data
or return [res.data for res in resources if all(key in res.data and res.data[key] == val for key, val in filter_params.iteritems())] :)
+ + def get(self, filter_params): + resources = self._get_resources(filter_params) + data = self.filter_data(resources, filter_params) I guess there're two kinds of filter parameters in your mind: one takes effect during model's get_list method while the other works based the return value from model. So please make those two params explicit and ensure one param only can take effect in one place. 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 = parse_param() + 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 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 It's not a good function name for me, because you didn't do any parsing in it. get_query_params or just use cherrypy.request.params?
def internal_redirect(url): raise cherrypy.InternalRedirect(url.encode("utf-8"))