diff --git a/mistral/engine/action_handler.py b/mistral/engine/action_handler.py index fcb1c388..4eb4fb1d 100644 --- a/mistral/engine/action_handler.py +++ b/mistral/engine/action_handler.py @@ -141,7 +141,7 @@ def _get_adhoc_action_input(action_def, input_dict, def run_action(action_def, action_input, action_ex_id=None, target=None, async=True): - return rpc.get_executor_client().run_action( + action_result = rpc.get_executor_client().run_action( action_ex_id, action_def.action_class, action_def.attributes or {}, @@ -150,16 +150,28 @@ def run_action(action_def, action_input, async ) + if action_result: + return _get_action_output(action_result) + + +def _get_action_output(result): + """Returns action output. + + :param result: ActionResult instance or ActionResult dict + :return: dict containing result. + """ + if isinstance(result, dict): + result = wf_utils.Result(result.get('data'), result.get('error')) + + return ({'result': result.data} + if result.is_success() else {'result': result.error}) + def store_action_result(action_ex, result): prev_state = action_ex.state - if result.is_success(): - action_ex.state = states.SUCCESS - action_ex.output = {'result': result.data} - else: - action_ex.state = states.ERROR - action_ex.output = {'result': result.error} + action_ex.state = states.SUCCESS if result.is_success() else states.ERROR + action_ex.output = _get_action_output(result) action_ex.accepted = True diff --git a/mistral/engine/default_engine.py b/mistral/engine/default_engine.py index c4949f23..3a9d6ba3 100644 --- a/mistral/engine/default_engine.py +++ b/mistral/engine/default_engine.py @@ -120,7 +120,7 @@ class DefaultEngine(base.Engine): return action_ex.get_clone() else: - result = action_handler.run_action( + output = action_handler.run_action( action_def, resolved_action_input, target=params.get('target'), @@ -131,7 +131,7 @@ class DefaultEngine(base.Engine): name=action_name, description=description, input=action_input, - output={'result': result} + output=output ) def on_task_state_change(self, task_ex_id, state): diff --git a/mistral/engine/default_executor.py b/mistral/engine/default_executor.py index b3623d9b..7f080c61 100644 --- a/mistral/engine/default_executor.py +++ b/mistral/engine/default_executor.py @@ -55,13 +55,13 @@ class DefaultExecutor(base.Executor): result = action.run() - if action.is_sync() and action_ex_id: - # Note: it's made for backwards compatibility with already - # existing Mistral actions which don't return result as - # instance of workflow.utils.Result. - if not isinstance(result, wf_utils.Result): - result = wf_utils.Result(data=result) + # Note: it's made for backwards compatibility with already + # existing Mistral actions which don't return result as + # instance of workflow.utils.Result. + if not isinstance(result, wf_utils.Result): + result = wf_utils.Result(data=result) + if action.is_sync() and action_ex_id: self._engine_client.on_action_complete(action_ex_id, result) return result diff --git a/mistral/tests/functional/api/v2/test_mistral_basic_v2.py b/mistral/tests/functional/api/v2/test_mistral_basic_v2.py index 22b76ce5..ad84292f 100644 --- a/mistral/tests/functional/api/v2/test_mistral_basic_v2.py +++ b/mistral/tests/functional/api/v2/test_mistral_basic_v2.py @@ -767,7 +767,22 @@ class ActionExecutionTestsV2(base.TestCase): self.assertEqual(201, resp.status) body = json.loads(body) output = json.loads(body['output']) - self.assertIsInstance(output['result'], dict) + self.assertTrue(output['result']['status'] in range(200, 307)) + + @test.attr(type='sanity') + def test_run_action_std_http_error(self): + resp, body = self.client.post_json( + 'action_executions', + { + 'name': 'std.http', + 'input': '{"url": "http://www.google.ru/not-found-test"}' + } + ) + + self.assertEqual(201, resp.status) + body = json.loads(body) + output = json.loads(body['output']) + self.assertEqual(404, output['result']['status']) @test.attr(type='sanity') def test_create_action_execution(self): diff --git a/mistral/tests/unit/engine/test_run_action.py b/mistral/tests/unit/engine/test_run_action.py index b40f1190..89c4637e 100644 --- a/mistral/tests/unit/engine/test_run_action.py +++ b/mistral/tests/unit/engine/test_run_action.py @@ -123,6 +123,7 @@ class RunActionEngineTest(base.EngineTestCase): 'scope': 'public' }) def_mock.return_value = action_def + run_mock.return_value = {'result': 'Hello'} class_ret = mock.MagicMock() class_mock.return_value = class_ret