diff --git a/mistral/api/controllers/v2/execution.py b/mistral/api/controllers/v2/execution.py index e775e72fb..d3a45cd40 100644 --- a/mistral/api/controllers/v2/execution.py +++ b/mistral/api/controllers/v2/execution.py @@ -47,6 +47,14 @@ STATE_TYPES = wtypes.Enum( ) +def _get_execution_resource(ex): + # We need to refer to this lazy-load field explicitly in + # order to make sure that it is correctly loaded. + hasattr(ex, 'output') + + return resources.Execution.from_dict(ex.to_dict()) + + # TODO(rakhmerov): Make sure to make all needed renaming on public API. @@ -218,12 +226,13 @@ class ExecutionsController(rest.RestController): types.uniquelist, types.list, types.uniquelist, wtypes.text, types.uuid, wtypes.text, types.jsontype, types.uuid, STATE_TYPES, wtypes.text, types.jsontype, - types.jsontype, wtypes.text, wtypes.text) + types.jsontype, wtypes.text, wtypes.text, bool) def get_all(self, marker=None, limit=None, sort_keys='created_at', sort_dirs='asc', fields='', workflow_name=None, workflow_id=None, description=None, params=None, task_execution_id=None, state=None, state_info=None, - input=None, output=None, created_at=None, updated_at=None): + input=None, output=None, created_at=None, updated_at=None, + include_output=None): """Return all Executions. :param marker: Optional. Pagination marker for large data sets. @@ -258,6 +267,8 @@ class ExecutionsController(rest.RestController): time and date. :param updated_at: Optional. Keep only resources with specific latest update time and date. + :param include_output: Optional. Include the output for all executions + in the list """ acl.enforce('executions:list', context.ctx()) @@ -281,11 +292,17 @@ class ExecutionsController(rest.RestController): filters ) + if include_output: + resource_function = _get_execution_resource + else: + resource_function = None + return rest_utils.get_all( resources.Executions, resources.Execution, db_api.get_workflow_executions, db_api.get_workflow_execution, + resource_function=resource_function, marker=marker, limit=limit, sort_keys=sort_keys, diff --git a/mistral/tests/unit/api/v2/test_executions.py b/mistral/tests/unit/api/v2/test_executions.py index 9dc6f3827..6016e65c6 100644 --- a/mistral/tests/unit/api/v2/test_executions.py +++ b/mistral/tests/unit/api/v2/test_executions.py @@ -25,6 +25,7 @@ import oslo_messaging import uuid from webtest import app as webtest_app +from mistral.api.controllers.v2 import execution from mistral.db.v2 import api as db_api from mistral.db.v2.sqlalchemy import api as sql_db_api from mistral.db.v2.sqlalchemy import models @@ -32,6 +33,7 @@ from mistral.engine.rpc_backend import rpc from mistral import exceptions as exc from mistral.tests.unit.api import base from mistral import utils +from mistral.utils import rest_utils from mistral.workflow import states # This line is needed for correct initialization of messaging config. @@ -604,3 +606,27 @@ class TestExecutionsController(base.APITest): SUB_WF_EX_JSON_WITH_DESC, resp.json['executions'][0] ) + + @mock.patch.object(db_api, 'get_workflow_executions', MOCK_WF_EXECUTIONS) + @mock.patch.object(rest_utils, 'get_all') + def test_get_all_executions_with_output(self, mock_get_all): + resp = self.app.get('/v2/executions?include_output=true') + + self.assertEqual(200, resp.status_int) + + args, kwargs = mock_get_all.call_args + resource_function = kwargs['resource_function'] + + self.assertEqual(execution._get_execution_resource, resource_function) + + @mock.patch.object(db_api, 'get_workflow_executions', MOCK_WF_EXECUTIONS) + @mock.patch.object(rest_utils, 'get_all') + def test_get_all_executions_without_output(self, mock_get_all): + resp = self.app.get('/v2/executions') + + self.assertEqual(200, resp.status_int) + + args, kwargs = mock_get_all.call_args + resource_function = kwargs['resource_function'] + + self.assertEqual(None, resource_function)