Merge "Fix API inconsistencies with GET /v2/workflows"

This commit is contained in:
Jenkins 2016-06-21 10:17:54 +00:00 committed by Gerrit Code Review
commit 2e8b36d825
11 changed files with 623 additions and 242 deletions

View File

@ -182,9 +182,9 @@ class ActionsController(rest.RestController, hooks.HookController):
db_api.delete_action_definition(name)
@wsme_pecan.wsexpose(Actions, types.uuid, int, types.uniquelist,
types.list)
types.list, types.uniquelist, types.jsontype)
def get_all(self, marker=None, limit=None, sort_keys='name',
sort_dirs='asc'):
sort_dirs='asc', fields='', **filters):
"""Return all actions.
:param marker: Optional. Pagination marker for large data sets.
@ -196,35 +196,30 @@ class ActionsController(rest.RestController, hooks.HookController):
:param sort_dirs: Optional. Directions to sort corresponding to
sort_keys, "asc" or "desc" can be choosed.
Default: asc.
:param fields: Optional. A specified list of fields of the resource to
be returned. 'id' will be included automatically in
fields if it's provided, since it will be used when
constructing 'next' link.
:param filters: Optional. A list of filters to apply to the result.
Where project_id is the same as the requester or
project_id is different but the scope is public.
"""
acl.enforce('actions:list', context.ctx())
LOG.info("Fetch actions. marker=%s, limit=%s, sort_keys=%s, "
"sort_dirs=%s", marker, limit, sort_keys, sort_dirs)
"sort_dirs=%s, filters=%s", marker, limit, sort_keys,
sort_dirs, filters)
rest_utils.validate_query_params(limit, sort_keys, sort_dirs)
marker_obj = None
if marker:
marker_obj = db_api.get_action_definition_by_id(marker)
db_action_defs = db_api.get_action_definitions(
return rest_utils.get_all(
Actions,
Action,
db_api.get_action_definitions,
db_api.get_action_definition_by_id,
resource_function=None,
marker=marker,
limit=limit,
marker=marker_obj,
sort_keys=sort_keys,
sort_dirs=sort_dirs
)
actions_list = [Action.from_dict(db_model.to_dict())
for db_model in db_action_defs]
return Actions.convert_with_links(
actions_list,
limit,
pecan.request.host_url,
sort_keys=','.join(sort_keys),
sort_dirs=','.join(sort_dirs)
sort_dirs=sort_dirs,
fields=fields,
**filters
)

View File

@ -79,11 +79,16 @@ class ActionExecution(resource.Resource):
)
class ActionExecutions(resource.Resource):
class ActionExecutions(resource.ResourceList):
"""A collection of action_executions."""
action_executions = [ActionExecution]
def __init__(self, **kwargs):
self._type = 'action_executions'
super(ActionExecutions, self).__init__(**kwargs)
@classmethod
def sample(cls):
return cls(action_executions=[ActionExecution.sample()])
@ -115,18 +120,48 @@ def _get_action_execution_resource(action_ex):
return res
def _get_action_executions(task_execution_id=None):
kwargs = {'type': 'action_execution'}
def _get_action_executions(task_execution_id=None, marker=None, limit=None,
sort_keys='created_at', sort_dirs='asc',
fields='', **filters):
"""Return all action executions.
Where project_id is the same as the requestor or
project_id is different but the scope is public.
:param marker: Optional. Pagination marker for large data sets.
:param limit: Optional. Maximum number of resources to return in a
single result. Default value is None for backward
compatibility.
:param sort_keys: Optional. Columns to sort results by.
Default: created_at, which is backward compatible.
:param sort_dirs: Optional. Directions to sort corresponding to
sort_keys, "asc" or "desc" can be chosen.
Default: desc. The length of sort_dirs can be equal
or less than that of sort_keys.
:param fields: Optional. A specified list of fields of the resource to
be returned. 'id' will be included automatically in
fields if it's provided, since it will be used when
constructing 'next' link.
:param filters: Optional. A list of filters to apply to the result.
"""
filters['type'] = 'action_execution'
if task_execution_id:
kwargs['task_execution_id'] = task_execution_id
filters['task_execution_id'] = task_execution_id
action_execs = [
_get_action_execution_resource(a_ex)
for a_ex in db_api.get_action_executions(**kwargs)
]
return ActionExecutions(action_executions=action_execs)
return rest_utils.get_all(
ActionExecutions,
ActionExecution,
db_api.get_action_executions,
db_api.get_action_execution,
resource_function=_get_action_execution_resource,
marker=marker,
limit=limit,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
fields=fields,
**filters
)
class ActionExecutionsController(rest.RestController):
@ -194,13 +229,45 @@ class ActionExecutionsController(rest.RestController):
return ActionExecution.from_dict(values)
@wsme_pecan.wsexpose(ActionExecutions)
def get_all(self):
"""Return all action_executions within the execution."""
acl.enforce('action_executions:list', context.ctx())
LOG.info("Fetch action_executions")
@wsme_pecan.wsexpose(ActionExecutions, types.uuid, int, types.uniquelist,
types.list, types.uniquelist, types.jsontype)
def get_all(self, marker=None, limit=None, sort_keys='created_at',
sort_dirs='asc', fields='', **filters):
"""Return all tasks within the execution.
return _get_action_executions()
Where project_id is the same as the requestor or
project_id is different but the scope is public.
:param marker: Optional. Pagination marker for large data sets.
:param limit: Optional. Maximum number of resources to return in a
single result. Default value is None for backward
compatibility.
:param sort_keys: Optional. Columns to sort results by.
Default: created_at, which is backward compatible.
:param sort_dirs: Optional. Directions to sort corresponding to
sort_keys, "asc" or "desc" can be chosen.
Default: desc. The length of sort_dirs can be equal
or less than that of sort_keys.
:param fields: Optional. A specified list of fields of the resource to
be returned. 'id' will be included automatically in
fields if it's provided, since it will be used when
constructing 'next' link.
:param filters: Optional. A list of filters to apply to the result.
"""
acl.enforce('action_executions:list', context.ctx())
LOG.info("Fetch action_executions. marker=%s, limit=%s, "
"sort_keys=%s, sort_dirs=%s, filters=%s",
marker, limit, sort_keys, sort_dirs, filters)
return _get_action_executions(
marker=marker,
limit=limit,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
fields=fields,
**filters
)
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
@ -228,13 +295,46 @@ class ActionExecutionsController(rest.RestController):
class TasksActionExecutionController(rest.RestController):
@wsme_pecan.wsexpose(ActionExecutions, wtypes.text)
def get_all(self, task_execution_id):
"""Return all action executions within the task execution."""
acl.enforce('action_executions:list', context.ctx())
LOG.info("Fetch action executions")
@wsme_pecan.wsexpose(ActionExecutions, types.uuid, types.uuid, int,
types.uniquelist, types.list, types.uniquelist,
types.jsontype)
def get_all(self, task_execution_id, marker=None, limit=None,
sort_keys='created_at', sort_dirs='asc', fields='', **filters):
"""Return all tasks within the execution.
return _get_action_executions(task_execution_id=task_execution_id)
Where project_id is the same as the requestor or
project_id is different but the scope is public.
:param marker: Optional. Pagination marker for large data sets.
:param limit: Optional. Maximum number of resources to return in a
single result. Default value is None for backward
compatibility.
:param sort_keys: Optional. Columns to sort results by.
Default: created_at, which is backward compatible.
:param sort_dirs: Optional. Directions to sort corresponding to
sort_keys, "asc" or "desc" can be chosen.
Default: desc. The length of sort_dirs can be equal
or less than that of sort_keys.
:param fields: Optional. A specified list of fields of the resource to
be returned. 'id' will be included automatically in
fields if it's provided, since it will be used when
constructing 'next' link.
:param filters: Optional. A list of filters to apply to the result.
"""
acl.enforce('action_executions:list', context.ctx())
LOG.info("Fetch action_executions. marker=%s, limit=%s, "
"sort_keys=%s, sort_dirs=%s, filters=%s",
marker, limit, sort_keys, sort_dirs, filters)
return _get_action_executions(
task_execution_id=task_execution_id,
marker=marker,
limit=limit,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
fields=fields,
**filters
)
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(ActionExecution, wtypes.text, wtypes.text)

View File

@ -64,11 +64,16 @@ class CronTrigger(resource.Resource):
updated_at='1970-01-01T00:00:00.000000')
class CronTriggers(resource.Resource):
class CronTriggers(resource.ResourceList):
"""A collection of cron triggers."""
cron_triggers = [CronTrigger]
def __init__(self, **kwargs):
self._type = 'cron_triggers'
super(CronTriggers, self).__init__(**kwargs)
@classmethod
def sample(cls):
return cls(cron_triggers=[CronTrigger.sample()])
@ -119,16 +124,44 @@ class CronTriggersController(rest.RestController):
db_api.delete_cron_trigger(name)
@wsme_pecan.wsexpose(CronTriggers)
def get_all(self):
"""Return all cron triggers."""
@wsme_pecan.wsexpose(CronTriggers, types.uuid, int, types.uniquelist,
types.list, types.uniquelist, types.jsontype)
def get_all(self, marker=None, limit=None, sort_keys='created_at',
sort_dirs='asc', fields='', **filters):
"""Return all cron triggers.
:param marker: Optional. Pagination marker for large data sets.
:param limit: Optional. Maximum number of resources to return in a
single result. Default value is None for backward
compatibility.
:param sort_keys: Optional. Columns to sort results by.
Default: created_at, which is backward compatible.
:param sort_dirs: Optional. Directions to sort corresponding to
sort_keys, "asc" or "desc" can be chosen.
Default: desc. The length of sort_dirs can be equal
or less than that of sort_keys.
:param fields: Optional. A specified list of fields of the resource to
be returned. 'id' will be included automatically in
fields if it's provided, since it will be used when
constructing 'next' link.
:param filters: Optional. A list of filters to apply to the result.
"""
acl.enforce('cron_triggers:list', context.ctx())
LOG.info("Fetch cron triggers.")
LOG.info("Fetch cron triggers. marker=%s, limit=%s, sort_keys=%s, "
"sort_dirs=%s, filters=%s", marker, limit, sort_keys,
sort_dirs, filters)
_list = [
CronTrigger.from_dict(db_model.to_dict())
for db_model in db_api.get_cron_triggers()
]
return CronTriggers(cron_triggers=_list)
return rest_utils.get_all(
CronTriggers,
CronTrigger,
db_api.get_cron_triggers,
db_api.get_cron_trigger,
resource_function=None,
marker=marker,
limit=limit,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
fields=fields,
**filters
)

View File

@ -61,33 +61,66 @@ class Environment(resource.Resource):
updated_at='1970-01-01T00:00:00.000000')
class Environments(resource.Resource):
class Environments(resource.ResourceList):
"""A collection of Environment resources."""
environments = [Environment]
def __init__(self, **kwargs):
self._type = 'environments'
super(Environments, self).__init__(**kwargs)
@classmethod
def sample(cls):
return cls(environments=[Environment.sample()])
class EnvironmentController(rest.RestController):
@wsme_pecan.wsexpose(Environments)
def get_all(self):
@wsme_pecan.wsexpose(Environments, types.uuid, int, types.uniquelist,
types.list, types.uniquelist, types.jsontype)
def get_all(self, marker=None, limit=None, sort_keys='created_at',
sort_dirs='asc', fields='', **filters):
"""Return all environments.
Where project_id is the same as the requestor or
project_id is different but the scope is public.
:param marker: Optional. Pagination marker for large data sets.
:param limit: Optional. Maximum number of resources to return in a
single result. Default value is None for backward
compatibility.
:param sort_keys: Optional. Columns to sort results by.
Default: created_at, which is backward compatible.
:param sort_dirs: Optional. Directions to sort corresponding to
sort_keys, "asc" or "desc" can be chosen.
Default: desc. The length of sort_dirs can be equal
or less than that of sort_keys.
:param fields: Optional. A specified list of fields of the resource to
be returned. 'id' will be included automatically in
fields if it's provided, since it will be used when
constructing 'next' link.
:param filters: Optional. A list of filters to apply to the result.
"""
acl.enforce('environments:list', context.ctx())
LOG.info("Fetch environments.")
LOG.info("Fetch environments. marker=%s, limit=%s, sort_keys=%s, "
"sort_dirs=%s, filters=%s", marker, limit, sort_keys,
sort_dirs, filters)
environments = [
Environment.from_dict(db_model.to_dict())
for db_model in db_api.get_environments()
]
return Environments(environments=environments)
return rest_utils.get_all(
Environments,
Environment,
db_api.get_environments,
db_api.get_environment,
resource_function=None,
marker=marker,
limit=limit,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
fields=fields,
**filters
)
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(Environment, wtypes.text)

View File

@ -15,7 +15,6 @@
# limitations under the License.
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
@ -255,9 +254,9 @@ class ExecutionsController(rest.RestController):
return db_api.delete_workflow_execution(id)
@wsme_pecan.wsexpose(Executions, types.uuid, int, types.uniquelist,
types.list)
types.list, types.uniquelist, types.jsontype)
def get_all(self, marker=None, limit=None, sort_keys='created_at',
sort_dirs='asc'):
sort_dirs='asc', fields='', **filters):
"""Return all Executions.
:param marker: Optional. Pagination marker for large data sets.
@ -270,36 +269,30 @@ class ExecutionsController(rest.RestController):
sort_keys, "asc" or "desc" can be chosen.
Default: desc. The length of sort_dirs can be equal
or less than that of sort_keys.
:param fields: Optional. A specified list of fields of the resource to
be returned. 'id' will be included automatically in
fields if it's provided, since it will be used when
constructing 'next' link.
:param filters: Optional. A list of filters to apply to the result.
"""
acl.enforce('executions:list', context.ctx())
LOG.info(
"Fetch executions. marker=%s, limit=%s, sort_keys=%s, "
"sort_dirs=%s", marker, limit, sort_keys, sort_dirs
"sort_dirs=%s, filters=%s", marker, limit, sort_keys, sort_dirs,
filters
)
rest_utils.validate_query_params(limit, sort_keys, sort_dirs)
marker_obj = None
if marker:
marker_obj = db_api.get_workflow_execution(marker)
db_workflow_exs = db_api.get_workflow_executions(
return rest_utils.get_all(
Executions,
Execution,
db_api.get_workflow_executions,
db_api.get_workflow_execution,
resource_function=None,
marker=marker,
limit=limit,
marker=marker_obj,
sort_keys=sort_keys,
sort_dirs=sort_dirs
)
wf_executions = [
Execution.from_dict(db_model.to_dict())
for db_model in db_workflow_exs
]
return Executions.convert_with_links(
wf_executions,
limit,
pecan.request.host_url,
sort_keys=','.join(sort_keys),
sort_dirs=','.join(sort_dirs)
sort_dirs=sort_dirs,
fields=fields,
**filters
)

View File

@ -85,11 +85,16 @@ class Task(resource.Resource):
)
class Tasks(resource.Resource):
class Tasks(resource.ResourceList):
"""A collection of tasks."""
tasks = [Task]
def __init__(self, **kwargs):
self._type = 'tasks'
super(Tasks, self).__init__(**kwargs)
@classmethod
def sample(cls):
return cls(tasks=[Task.sample()])
@ -102,16 +107,46 @@ def _get_task_resource_with_result(task_ex):
return task
def _get_task_resources_with_results(wf_ex_id=None):
filters = {}
def _get_task_resources_with_results(wf_ex_id=None, marker=None, limit=None,
sort_keys='created_at', sort_dirs='asc',
fields='', **filters):
"""Return all tasks within the execution.
Where project_id is the same as the requestor or
project_id is different but the scope is public.
:param marker: Optional. Pagination marker for large data sets.
:param limit: Optional. Maximum number of resources to return in a
single result. Default value is None for backward
compatibility.
:param sort_keys: Optional. Columns to sort results by.
Default: created_at, which is backward compatible.
:param sort_dirs: Optional. Directions to sort corresponding to
sort_keys, "asc" or "desc" can be chosen.
Default: desc. The length of sort_dirs can be equal
or less than that of sort_keys.
:param fields: Optional. A specified list of fields of the resource to
be returned. 'id' will be included automatically in
fields if it's provided, since it will be used when
constructing 'next' link.
:param filters: Optional. A list of filters to apply to the result.
"""
if wf_ex_id:
filters['workflow_execution_id'] = wf_ex_id
task_exs = db_api.get_task_executions(**filters)
tasks = [_get_task_resource_with_result(t_e) for t_e in task_exs]
return Tasks(tasks=tasks)
return rest_utils.get_all(
Tasks,
Task,
db_api.get_task_executions,
db_api.get_task_execution,
resource_function=_get_task_resource_with_result,
marker=marker,
limit=limit,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
fields=fields,
**filters
)
class TasksController(rest.RestController):
@ -128,13 +163,45 @@ class TasksController(rest.RestController):
return _get_task_resource_with_result(task_ex)
@wsme_pecan.wsexpose(Tasks)
def get_all(self):
"""Return all tasks within the execution."""
acl.enforce('tasks:list', context.ctx())
LOG.info("Fetch tasks")
@wsme_pecan.wsexpose(Tasks, types.uuid, int, types.uniquelist,
types.list, types.uniquelist, types.jsontype)
def get_all(self, marker=None, limit=None, sort_keys='created_at',
sort_dirs='asc', fields='', **filters):
"""Return all tasks.
return _get_task_resources_with_results()
Where project_id is the same as the requestor or
project_id is different but the scope is public.
:param marker: Optional. Pagination marker for large data sets.
:param limit: Optional. Maximum number of resources to return in a
single result. Default value is None for backward
compatibility.
:param sort_keys: Optional. Columns to sort results by.
Default: created_at, which is backward compatible.
:param sort_dirs: Optional. Directions to sort corresponding to
sort_keys, "asc" or "desc" can be chosen.
Default: desc. The length of sort_dirs can be equal
or less than that of sort_keys.
:param fields: Optional. A specified list of fields of the resource to
be returned. 'id' will be included automatically in
fields if it's provided, since it will be used when
constructing 'next' link.
:param filters: Optional. A list of filters to apply to the result.
"""
acl.enforce('tasks:list', context.ctx())
LOG.info("Fetch tasks. marker=%s, limit=%s, sort_keys=%s, "
"sort_dirs=%s, filters=%s", marker, limit, sort_keys,
sort_dirs, filters)
return _get_task_resources_with_results(
marker=marker,
limit=limit,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
fields=fields,
**filters
)
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(Task, wtypes.text, body=Task)
@ -190,10 +257,44 @@ class TasksController(rest.RestController):
class ExecutionTasksController(rest.RestController):
@wsme_pecan.wsexpose(Tasks, wtypes.text)
def get_all(self, workflow_execution_id):
"""Return all tasks within the workflow execution."""
acl.enforce('tasks:list', context.ctx())
LOG.info("Fetch tasks.")
return _get_task_resources_with_results(workflow_execution_id)
@wsme_pecan.wsexpose(Tasks, types.uuid, types.uuid, int, types.uniquelist,
types.list, types.uniquelist)
def get_all(self, workflow_execution_id, marker=None, limit=None,
sort_keys='created_at', sort_dirs='asc', fields='', **filters):
"""Return all tasks within the execution.
Where project_id is the same as the requestor or
project_id is different but the scope is public.
:param marker: Optional. Pagination marker for large data sets.
:param limit: Optional. Maximum number of resources to return in a
single result. Default value is None for backward
compatibility.
:param sort_keys: Optional. Columns to sort results by.
Default: created_at, which is backward compatible.
:param sort_dirs: Optional. Directions to sort corresponding to
sort_keys, "asc" or "desc" can be chosen.
Default: desc. The length of sort_dirs can be equal
or less than that of sort_keys.
:param fields: Optional. A specified list of fields of the resource to
be returned. 'id' will be included automatically in
fields if it's provided, since it will be used when
constructing 'next' link.
:param filters: Optional. A list of filters to apply to the result.
"""
acl.enforce('tasks:list', context.ctx())
LOG.info("Fetch tasks. workflow_execution_id=%s, marker=%s, limit=%s, "
"sort_keys=%s, sort_dirs=%s, filters=%s",
workflow_execution_id, marker, limit, sort_keys, sort_dirs,
filters)
return _get_task_resources_with_results(
wf_ex_id=workflow_execution_id,
marker=marker,
limit=limit,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
fields=fields,
**filters
)

View File

@ -22,6 +22,7 @@ import wsmeext.pecan as wsme_pecan
from mistral.api import access_control as acl
from mistral.api.controllers import resource
from mistral.api.controllers.v2 import types
from mistral.api.controllers.v2 import validation
from mistral.api.hooks import content_type as ct_hook
from mistral import context
@ -62,11 +63,16 @@ class Workbook(resource.Resource):
updated_at='1970-01-01T00:00:00.000000')
class Workbooks(resource.Resource):
class Workbooks(resource.ResourceList):
"""A collection of Workbooks."""
workbooks = [Workbook]
def __init__(self, **kwargs):
self._type = 'workbooks'
super(Workbooks, self).__init__(**kwargs)
@classmethod
def sample(cls):
return cls(workbooks=[Workbook.sample()])
@ -123,17 +129,45 @@ class WorkbooksController(rest.RestController, hooks.HookController):
db_api.delete_workbook(name)
@wsme_pecan.wsexpose(Workbooks)
def get_all(self):
"""Return all workbooks.
@wsme_pecan.wsexpose(Workbooks, types.uuid, int, types.uniquelist,
types.list, types.uniquelist, types.jsontype)
def get_all(self, marker=None, limit=None, sort_keys='created_at',
sort_dirs='asc', fields='', **filters):
"""Return a list of workbooks.
:param marker: Optional. Pagination marker for large data sets.
:param limit: Optional. Maximum number of resources to return in a
single result. Default value is None for backward
compatibility.
:param sort_keys: Optional. Columns to sort results by.
Default: created_at.
:param sort_dirs: Optional. Directions to sort corresponding to
sort_keys, "asc" or "desc" can be choosed.
Default: asc.
:param fields: Optional. A specified list of fields of the resource to
be returned. 'id' will be included automatically in
fields if it's provided, since it will be used when
constructing 'next' link.
:param filters: Optional. A list of filters to apply to the result.
Where project_id is the same as the requestor or
project_id is different but the scope is public.
"""
acl.enforce('workbooks:list', context.ctx())
LOG.info("Fetch workbooks.")
LOG.info("Fetch workbooks. marker=%s, limit=%s, sort_keys=%s, "
"sort_dirs=%s, fields=%s, filters=%s", marker, limit,
sort_keys, sort_dirs, fields, filters)
workbooks_list = [Workbook.from_dict(db_model.to_dict())
for db_model in db_api.get_workbooks()]
return Workbooks(workbooks=workbooks_list)
return rest_utils.get_all(
Workbooks,
Workbook,
db_api.get_workbooks,
db_api.get_workbook,
resource_function=None,
marker=marker,
limit=limit,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
fields=fields,
**filters
)

View File

@ -236,9 +236,9 @@ class WorkflowsController(rest.RestController, hooks.HookController):
@rest_utils.wrap_wsme_controller_exception
@wsme_pecan.wsexpose(Workflows, types.uuid, int, types.uniquelist,
types.list, types.uniquelist)
types.list, types.uniquelist, types.jsontype)
def get_all(self, marker=None, limit=None, sort_keys='created_at',
sort_dirs='asc', fields=''):
sort_dirs='asc', fields='', **filters):
"""Return a list of workflows.
:param marker: Optional. Pagination marker for large data sets.
@ -254,46 +254,26 @@ class WorkflowsController(rest.RestController, hooks.HookController):
be returned. 'id' will be included automatically in
fields if it's provided, since it will be used when
constructing 'next' link.
:param filters: Optional. A list of filters to apply to the result.
Where project_id is the same as the requester or
project_id is different but the scope is public.
"""
acl.enforce('workflows:list', context.ctx())
LOG.info("Fetch workflows. marker=%s, limit=%s, sort_keys=%s, "
"sort_dirs=%s, fields=%s", marker, limit, sort_keys,
sort_dirs, fields)
"sort_dirs=%s, fields=%s, filters=%s", marker, limit,
sort_keys, sort_dirs, fields, filters)
if fields and 'id' not in fields:
fields.insert(0, 'id')
rest_utils.validate_query_params(limit, sort_keys, sort_dirs)
rest_utils.validate_fields(fields, Workflow.get_fields())
marker_obj = None
if marker:
marker_obj = db_api.get_workflow_definition_by_id(marker)
db_workflows = db_api.get_workflow_definitions(
return rest_utils.get_all(
Workflows,
Workflow,
db_api.get_workflow_definitions,
db_api.get_workflow_definition_by_id,
resource_function=None,
marker=marker,
limit=limit,
marker=marker_obj,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
fields=fields
)
workflows_list = []
for data in db_workflows:
workflow_dict = (dict(zip(fields, data)) if fields else
data.to_dict())
workflows_list.append(Workflow.from_dict(workflow_dict))
return Workflows.convert_with_links(
workflows_list,
limit,
pecan.request.host_url,
sort_keys=','.join(sort_keys),
sort_dirs=','.join(sort_dirs),
fields=','.join(fields) if fields else ''
fields=fields,
**filters
)

View File

@ -76,8 +76,16 @@ def load_workbook(name):
return IMPL.load_workbook(name)
def get_workbooks():
return IMPL.get_workbooks()
def get_workbooks(limit=None, marker=None, sort_keys=None,
sort_dirs=None, fields=None, **kwargs):
return IMPL.get_workbooks(
limit=limit,
marker=marker,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
fields=fields,
**kwargs
)
def create_workbook(values):
@ -328,8 +336,15 @@ def load_task_execution(name):
return IMPL.load_task_execution(name)
def get_task_executions(**kwargs):
return IMPL.get_task_executions(**kwargs)
def get_task_executions(limit=None, marker=None, sort_keys=['created_at'],
sort_dirs=None, **kwargs):
return IMPL.get_task_executions(
limit=limit,
marker=marker,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
**kwargs
)
def create_task_execution(values):
@ -428,8 +443,16 @@ def load_environment(name):
return IMPL.load_environment(name)
def get_environments():
return IMPL.get_environments()
def get_environments(limit=None, marker=None, sort_keys=['name'],
sort_dirs=None, **kwargs):
return IMPL.get_environments(
limit=limit,
marker=marker,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
**kwargs
)
def create_environment(values):

View File

@ -153,20 +153,56 @@ def _delete_all(model, session=None, **kwargs):
_secure_query(model).filter_by(**kwargs).delete(synchronize_session=False)
def _get_collection_sorted_by_name(model, **kwargs):
def _get_collection(model, limit=None, marker=None, sort_keys=None,
sort_dirs=None, fields=None, query=None, **kwargs):
columns = (
tuple([getattr(model, f) for f in fields if hasattr(model, f)])
if fields else ()
)
if query is None:
query = _secure_query(model, *columns).filter_by(**kwargs)
try:
return _paginate_query(
model,
limit,
marker,
sort_keys,
sort_dirs,
query
)
except Exception as e:
raise exc.DBQueryEntryException(
"Failed when querying database, error type: %s, "
"error message: %s" % (e.__class__.__name__, e.message)
)
def _get_collection_sorted_by_name(model, fields=None, sort_keys=['name'],
**kwargs):
# Note(lane): Sometimes tenant_A needs to get resources of tenant_B,
# especially in resource sharing scenario, the resource owner needs to
# check if the resource is used by a member.
query = (b.model_query(model) if 'project_id' in kwargs
else _secure_query(model))
columns = (
tuple([getattr(model, f) for f in fields if hasattr(model, f)])
if fields else ()
)
return query.filter_by(**kwargs).order_by(model.name).all()
query = (b.model_query(model, *columns) if 'project_id' in kwargs
else _secure_query(model, *columns))
return _get_collection(
model=model,
query=query,
sort_keys=sort_keys,
fields=fields,
**kwargs
)
def _get_collection_sorted_by_time(model, **kwargs):
query = _secure_query(model)
return query.filter_by(**kwargs).order_by(model.created_at).all()
def _get_collection_sorted_by_time(model, sort_keys=['created_at'], **kwargs):
return _get_collection(model, sort_keys=sort_keys, **kwargs)
def _get_db_object_by_name(model, name):
@ -259,19 +295,6 @@ def delete_workbooks(**kwargs):
# Workflow definitions.
WORKFLOW_COL_MAPPING = {
'id': models.WorkflowDefinition.id,
'name': models.WorkflowDefinition.name,
'input': models.WorkflowDefinition.spec,
'definition': models.WorkflowDefinition.definition,
'tags': models.WorkflowDefinition.tags,
'scope': models.WorkflowDefinition.scope,
'created_at': models.WorkflowDefinition.created_at,
'updated_at': models.WorkflowDefinition.updated_at
}
def get_workflow_definition(identifier):
"""Gets workflow definition by name or uuid.
@ -306,27 +329,16 @@ def load_workflow_definition(name):
return _get_workflow_definition(name)
def get_workflow_definitions(limit=None, marker=None, sort_keys=None,
sort_dirs=None, fields=None, **kwargs):
columns = (
tuple(WORKFLOW_COL_MAPPING.get(f) for f in fields) if fields else ()
)
def get_workflow_definitions(sort_keys=['created_at'], fields=None, **kwargs):
if fields and 'input' in fields:
fields.remove('input')
fields.append('spec')
query = _secure_query(models.WorkflowDefinition, *columns)
try:
return _paginate_query(
models.WorkflowDefinition,
limit,
marker,
sort_keys,
sort_dirs,
query
)
except Exception as e:
raise exc.DBQueryEntryError(
"Failed when querying database, error type: %s, "
"error message: %s" % (e.__class__.__name__, e.message)
return _get_collection(
model=models.WorkflowDefinition,
sort_keys=sort_keys,
fields=fields,
**kwargs
)
@ -471,23 +483,11 @@ def load_action_definition(name):
return _get_action_definition(name)
def get_action_definitions(limit=None, marker=None, sort_keys=['name'],
sort_dirs=None, **kwargs):
query = _secure_query(models.ActionDefinition).filter_by(**kwargs)
try:
return _paginate_query(
models.ActionDefinition,
limit,
marker,
sort_keys,
sort_dirs,
query
)
except Exception as e:
raise exc.DBQueryEntryError(
"Failed when querying database, error type: %s, "
"error message: %s" % (e.__class__.__name__, e.message)
def get_action_definitions(sort_keys=['name'], **kwargs):
return _get_collection(
model=models.ActionDefinition,
sort_keys=sort_keys,
**kwargs
)
@ -747,23 +747,11 @@ def ensure_workflow_execution_exists(id):
get_workflow_execution(id)
def get_workflow_executions(limit=None, marker=None, sort_keys=['created_at'],
sort_dirs=None, **kwargs):
query = _secure_query(models.WorkflowExecution).filter_by(**kwargs)
try:
return _paginate_query(
def get_workflow_executions(sort_keys=['created_at'], **kwargs):
return _get_collection(
models.WorkflowExecution,
limit,
marker,
sort_keys,
sort_dirs,
query
)
except Exception as e:
raise exc.DBQueryEntryError(
"Failed when quering database, error type: %s, "
"error message: %s" % (e.__class__.__name__, e.message)
sort_keys=sort_keys,
**kwargs
)
@ -1144,10 +1132,15 @@ def _get_cron_trigger(name):
return _get_db_object_by_name(models.CronTrigger, name)
def _get_cron_triggers(**kwargs):
def _get_cron_triggers(*columns, **kwargs):
query = b.model_query(models.CronTrigger)
return query.filter_by(**kwargs).all()
return _get_collection(
models.CronTrigger,
query=query,
*columns,
**kwargs
)
# Environments.

View File

@ -19,11 +19,15 @@ import json
import pecan
import six
from oslo_log import log as logging
from webob import Response
from wsme import exc as wsme_exc
from mistral import exceptions as exc
LOG = logging.getLogger(__name__)
def wrap_wsme_controller_exception(func):
"""Decorator for controllers method.
@ -102,3 +106,95 @@ def validate_fields(fields, object_fields):
raise wsme_exc.ClientSideError(
'Field(s) %s are invalid.' % ', '.join(invalid_fields)
)
def get_all(list_cls, cls, get_all_function, get_function,
resource_function=None, marker=None, limit=None,
sort_keys='created_at', sort_dirs='asc', fields='', **filters):
"""Return a list of cls.
:param list_cls: Collection class (e.g.: Actions, Workflows, ...).
:param cls: Class (e.g.: Action, Workflow, ...).
:param get_all_function: Request function to get all elements with
filtering (limit, marker, sort_keys, sort_dirs,
fields)
:param get_function: Function used to fetch the marker
:param resource_function: Optional, function used to fetch additional data
:param marker: Optional. Pagination marker for large data sets.
:param limit: Optional. Maximum number of resources to return in a
single result. Default value is None for backward
compatibility.
:param sort_keys: Optional. Columns to sort results by.
Default: created_at.
:param sort_dirs: Optional. Directions to sort corresponding to
sort_keys, "asc" or "desc" can be choosed.
Default: asc.
:param fields: Optional. A specified list of fields of the resource to
be returned. 'id' will be included automatically in
fields if it's provided, since it will be used when
constructing 'next' link.
:param filters: Optional. A specified dictionary of filters to match.
"""
if fields and 'id' not in fields:
fields.insert(0, 'id')
validate_query_params(limit, sort_keys, sort_dirs)
validate_fields(fields, cls.get_fields())
marker_obj = None
if marker:
marker_obj = get_function(marker)
list_to_return = []
if resource_function:
# do not filter fields yet, resource_function needs the ORM object
db_list = get_all_function(
limit=limit,
marker=marker_obj,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
**filters
)
for data in db_list:
obj = resource_function(data)
# filter fields using a loop instead of the ORM
if fields:
data = []
for f in fields:
if hasattr(obj, f):
data.append(getattr(obj, f))
dict_data = dict(zip(fields, data))
else:
dict_data = obj.to_dict()
list_to_return.append(cls.from_dict(dict_data))
else:
db_list = get_all_function(
limit=limit,
marker=marker_obj,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
fields=fields,
**filters
)
for data in db_list:
dict_data = (dict(zip(fields, data)) if fields else
data.to_dict())
list_to_return.append(cls.from_dict(dict_data))
return list_cls.convert_with_links(
list_to_return,
limit,
pecan.request.host_url,
sort_keys=','.join(sort_keys),
sort_dirs=','.join(sort_dirs),
fields=','.join(fields) if fields else '',
**filters
)