Support filtering for execution query
Change-Id: Iab965386f57948d4c333dfadde589c76ea639764 Implements: blueprint qinling-execution-filter
This commit is contained in:
parent
a7496f4e16
commit
601410e119
43
example/functions/python/openstack/create_thumbnail.py
Normal file
43
example/functions/python/openstack/create_thumbnail.py
Normal file
@ -0,0 +1,43 @@
|
||||
from PIL import Image
|
||||
import swiftclient
|
||||
|
||||
|
||||
def main(context, container, object):
|
||||
conn = swiftclient.Connection(
|
||||
session=context['os_session'],
|
||||
os_options={'region_name': 'RegionOne'},
|
||||
)
|
||||
|
||||
# obj_header = conn.head_object(container, object)
|
||||
new_container = '%s_thumb' % container
|
||||
|
||||
# Download original photo
|
||||
image_path = '/%s' % object
|
||||
_, obj_contents = conn.get_object(container, object)
|
||||
with open(image_path, 'w') as local:
|
||||
local.write(obj_contents)
|
||||
|
||||
print('Downloaded object % from container %s' % (object, container))
|
||||
|
||||
# Resize
|
||||
SIZE = (75, 75)
|
||||
thumb_path = '/%s_thumb' % object
|
||||
im = Image.open(image_path)
|
||||
im.convert('RGB')
|
||||
im.thumbnail(SIZE, Image.ANTIALIAS)
|
||||
im.save(thumb_path, 'JPEG', quality=80)
|
||||
|
||||
print('Resized.')
|
||||
|
||||
# Upload thumb photo
|
||||
with open(thumb_path, 'r') as new_local:
|
||||
conn.put_object(
|
||||
new_container,
|
||||
object,
|
||||
contents=new_local,
|
||||
content_type='text/plain'
|
||||
)
|
||||
|
||||
print('Uploaded object %s to container %s' % (object, new_container))
|
||||
|
||||
return True
|
@ -15,6 +15,7 @@
|
||||
from oslo_log import log as logging
|
||||
import pecan
|
||||
from pecan import rest
|
||||
from wsme import types as wtypes
|
||||
import wsmeext.pecan as wsme_pecan
|
||||
|
||||
from qinling.api.controllers.v1 import resources
|
||||
@ -61,12 +62,13 @@ class ExecutionsController(rest.RestController):
|
||||
return resources.Execution.from_dict(db_model.to_dict())
|
||||
|
||||
@rest_utils.wrap_wsme_controller_exception
|
||||
@wsme_pecan.wsexpose(resources.Executions)
|
||||
def get_all(self):
|
||||
LOG.info("Get all %ss.", self.type)
|
||||
@wsme_pecan.wsexpose(resources.Executions, wtypes.text)
|
||||
def get_all(self, function_id=None):
|
||||
filters = rest_utils.get_filters(function_id=function_id)
|
||||
LOG.info("Get all %ss. filters=%s", self.type, filters)
|
||||
|
||||
executions = [resources.Execution.from_dict(db_model.to_dict())
|
||||
for db_model in db_api.get_executions()]
|
||||
for db_model in db_api.get_executions(**filters)]
|
||||
|
||||
return resources.Executions(executions=executions)
|
||||
|
||||
|
@ -130,8 +130,8 @@ def get_execution(id):
|
||||
return IMPL.get_execution(id)
|
||||
|
||||
|
||||
def get_executions():
|
||||
return IMPL.get_executions()
|
||||
def get_executions(**filters):
|
||||
return IMPL.get_executions(**filters)
|
||||
|
||||
|
||||
def delete_execution(id):
|
||||
|
@ -70,6 +70,24 @@ class TestExecutionController(base.APITest):
|
||||
)
|
||||
self._assertDictContainsSubset(actual, body)
|
||||
|
||||
@mock.patch('qinling.rpc.EngineClient.create_execution')
|
||||
def test_get_all_filter(self, mock_create_execution):
|
||||
body = {
|
||||
'function_id': self.func_id,
|
||||
}
|
||||
resp = self.app.post_json('/v1/executions', body)
|
||||
exec_id = resp.json.get('id')
|
||||
|
||||
self.assertEqual(201, resp.status_int)
|
||||
|
||||
resp = self.app.get('/v1/executions?function_id=%s' % self.func_id)
|
||||
|
||||
self.assertEqual(200, resp.status_int)
|
||||
actual = self._assert_single_item(
|
||||
resp.json['executions'], id=exec_id
|
||||
)
|
||||
self._assertDictContainsSubset(actual, body)
|
||||
|
||||
@mock.patch('qinling.rpc.EngineClient.create_execution')
|
||||
def test_delete(self, mock_create_execution):
|
||||
body = {
|
||||
|
@ -70,3 +70,86 @@ def wrap_pecan_controller_exception(func):
|
||||
)
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
def get_filters(**params):
|
||||
"""Create filters from REST request parameters.
|
||||
|
||||
:param req_params: REST request parameters.
|
||||
:return: filters dictionary.
|
||||
"""
|
||||
filters = {}
|
||||
|
||||
for column, data in params.items():
|
||||
if data is not None:
|
||||
if isinstance(data, six.string_types):
|
||||
f_type, value = _extract_filter_type_and_value(data)
|
||||
|
||||
create_or_update_filter(column, value, f_type, filters)
|
||||
else:
|
||||
create_or_update_filter(column, data, _filter=filters)
|
||||
|
||||
return filters
|
||||
|
||||
|
||||
def create_or_update_filter(column, value, filter_type='eq', _filter=None):
|
||||
"""Create or Update filter.
|
||||
|
||||
:param column: Column name by which user want to filter.
|
||||
:param value: Column value.
|
||||
:param filter_type: filter type. Filter type can be
|
||||
'eq', 'neq', 'gt', 'gte', 'lte', 'in',
|
||||
'lt', 'nin'. Default is 'eq'.
|
||||
:param _filter: Optional. If provided same filter dictionary will
|
||||
be updated.
|
||||
:return: filter dictionary.
|
||||
|
||||
"""
|
||||
if _filter is None:
|
||||
_filter = {}
|
||||
|
||||
_filter[column] = {filter_type: value}
|
||||
|
||||
return _filter
|
||||
|
||||
|
||||
def _extract_filter_type_and_value(data):
|
||||
"""Extract filter type and its value from the data.
|
||||
|
||||
:param data: REST parameter value from which filter type and
|
||||
value can be get. It should be in format of
|
||||
'filter_type:value'.
|
||||
:return: filter type and value.
|
||||
"""
|
||||
if data.startswith("in:"):
|
||||
value = list(six.text_type(data[3:]).split(","))
|
||||
filter_type = 'in'
|
||||
elif data.startswith("nin:"):
|
||||
value = list(six.text_type(data[4:]).split(","))
|
||||
filter_type = 'nin'
|
||||
elif data.startswith("neq:"):
|
||||
value = six.text_type(data[4:])
|
||||
filter_type = 'neq'
|
||||
elif data.startswith("gt:"):
|
||||
value = six.text_type(data[3:])
|
||||
filter_type = 'gt'
|
||||
elif data.startswith("gte:"):
|
||||
value = six.text_type(data[4:])
|
||||
filter_type = 'gte'
|
||||
elif data.startswith("lt:"):
|
||||
value = six.text_type(data[3:])
|
||||
filter_type = 'lt'
|
||||
elif data.startswith("lte:"):
|
||||
value = six.text_type(data[4:])
|
||||
filter_type = 'lte'
|
||||
elif data.startswith("eq:"):
|
||||
value = six.text_type(data[3:])
|
||||
filter_type = 'eq'
|
||||
elif data.startswith("has:"):
|
||||
value = six.text_type(data[4:])
|
||||
filter_type = 'has'
|
||||
else:
|
||||
value = data
|
||||
filter_type = 'eq'
|
||||
|
||||
return filter_type, value
|
||||
|
Loading…
x
Reference in New Issue
Block a user