Merge "Add action context to all action executions"
This commit is contained in:
commit
7f1c1d0808
@ -122,22 +122,9 @@ class Action(object):
|
||||
"""
|
||||
return True
|
||||
|
||||
def _create_action_execution(self, input_dict, runtime_ctx, desc=''):
|
||||
# Assign the action execution ID here to minimize database calls.
|
||||
# Otherwise, the input property of the action execution DB object needs
|
||||
# to be updated with the action execution ID after the action execution
|
||||
# DB object is created.
|
||||
action_ex_id = utils.generate_unicode_uuid()
|
||||
|
||||
# TODO(rakhmerov): Bad place, we probably need to push action context
|
||||
# to all actions. It's related to
|
||||
# https://blueprints.launchpad.net/mistral/+spec/mistral-custom-actions-api
|
||||
if a_m.has_action_context(
|
||||
self.action_def.action_class,
|
||||
self.action_def.attributes or {}) and self.task_ex:
|
||||
input_dict.update(
|
||||
a_m.get_action_context(self.task_ex, action_ex_id)
|
||||
)
|
||||
def _create_action_execution(self, input_dict, runtime_ctx,
|
||||
desc='', action_ex_id=None):
|
||||
action_ex_id = action_ex_id or utils.generate_unicode_uuid()
|
||||
|
||||
values = {
|
||||
'id': action_ex_id,
|
||||
@ -212,10 +199,19 @@ class PythonAction(Action):
|
||||
def schedule(self, input_dict, target, index=0, desc=''):
|
||||
assert not self.action_ex
|
||||
|
||||
# Assign the action execution ID here to minimize database calls.
|
||||
# Otherwise, the input property of the action execution DB object needs
|
||||
# to be updated with the action execution ID after the action execution
|
||||
# DB object is created.
|
||||
action_ex_id = utils.generate_unicode_uuid()
|
||||
|
||||
self._insert_action_context(action_ex_id, input_dict)
|
||||
|
||||
self._create_action_execution(
|
||||
self._prepare_input(input_dict),
|
||||
self._prepare_runtime_context(index),
|
||||
desc=desc
|
||||
desc=desc,
|
||||
action_ex_id=action_ex_id
|
||||
)
|
||||
|
||||
scheduler.schedule_call(
|
||||
@ -233,8 +229,21 @@ class PythonAction(Action):
|
||||
input_dict = self._prepare_input(input_dict)
|
||||
runtime_ctx = self._prepare_runtime_context(index)
|
||||
|
||||
# Assign the action execution ID here to minimize database calls.
|
||||
# Otherwise, the input property of the action execution DB object needs
|
||||
# to be updated with the action execution ID after the action execution
|
||||
# DB object is created.
|
||||
action_ex_id = utils.generate_unicode_uuid()
|
||||
|
||||
self._insert_action_context(action_ex_id, input_dict, save=save)
|
||||
|
||||
if save:
|
||||
self._create_action_execution(input_dict, runtime_ctx, desc=desc)
|
||||
self._create_action_execution(
|
||||
input_dict,
|
||||
runtime_ctx,
|
||||
desc=desc,
|
||||
action_ex_id=action_ex_id
|
||||
)
|
||||
|
||||
result = rpc.get_executor_client().run_action(
|
||||
self.action_ex.id if self.action_ex else None,
|
||||
@ -286,6 +295,24 @@ class PythonAction(Action):
|
||||
"""
|
||||
return {'index': index}
|
||||
|
||||
def _insert_action_context(self, action_ex_id, input_dict, save=True):
|
||||
"""Template method to prepare action context.
|
||||
|
||||
It inserts the action context in the input if required
|
||||
runtime context.
|
||||
"""
|
||||
# we need to push action context to all actions. It's related to
|
||||
# https://blueprints.launchpad.net/mistral/+spec/mistral-custom-actions-api
|
||||
has_action_context = a_m.has_action_context(
|
||||
self.action_def.action_class,
|
||||
self.action_def.attributes or {}
|
||||
)
|
||||
|
||||
if has_action_context:
|
||||
input_dict.update(
|
||||
a_m.get_action_context(self.task_ex, action_ex_id, save=save)
|
||||
)
|
||||
|
||||
|
||||
class AdHocAction(PythonAction):
|
||||
"""Ad-hoc action."""
|
||||
|
@ -147,16 +147,41 @@ def get_action_class(action_full_name):
|
||||
)
|
||||
|
||||
|
||||
def get_action_context(task_ex, action_ex_id):
|
||||
def get_action_context(task_ex, action_ex_id, save=True):
|
||||
if task_ex:
|
||||
return {
|
||||
_ACTION_CTX_PARAM: {
|
||||
'workflow_name': task_ex.workflow_name,
|
||||
'workflow_execution_id': task_ex.workflow_execution_id,
|
||||
'task_id': task_ex.id,
|
||||
'task_name': task_ex.name,
|
||||
'task_tags': task_ex.tags,
|
||||
'action_execution_id': action_ex_id,
|
||||
'callback_url': '/v2/action_executions/%s' % action_ex_id
|
||||
}
|
||||
}
|
||||
elif save:
|
||||
return {
|
||||
_ACTION_CTX_PARAM: {
|
||||
'workflow_name': None,
|
||||
'workflow_execution_id': None,
|
||||
'task_id': None,
|
||||
'task_name': None,
|
||||
'task_tags': None,
|
||||
'action_execution_id': action_ex_id,
|
||||
'callback_url': '/v2/action_executions/%s' % action_ex_id
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
_ACTION_CTX_PARAM: {
|
||||
'workflow_name': task_ex.workflow_name,
|
||||
'workflow_execution_id': task_ex.workflow_execution_id,
|
||||
'task_id': task_ex.id,
|
||||
'task_name': task_ex.name,
|
||||
'task_tags': task_ex.tags,
|
||||
'action_execution_id': action_ex_id,
|
||||
'callback_url': '/v2/action_executions/%s' % action_ex_id
|
||||
'workflow_name': None,
|
||||
'workflow_execution_id': None,
|
||||
'task_id': None,
|
||||
'task_name': None,
|
||||
'task_tags': None,
|
||||
'action_execution_id': None,
|
||||
'callback_url': None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,3 +91,101 @@ class ActionContextTest(base.EngineTestCase):
|
||||
proxies=None,
|
||||
verify=None
|
||||
)
|
||||
|
||||
@mock.patch.object(
|
||||
requests, 'request',
|
||||
mock.MagicMock(return_value=test_base.FakeHTTPResponse('', 200, 'OK')))
|
||||
def test_single_async_saved_action_context(self):
|
||||
action_ex = self.engine.start_action(
|
||||
'std.mistral_http',
|
||||
{'url': 'https://wiki.openstack.org/wiki/mistral'},
|
||||
save_result=True
|
||||
)
|
||||
|
||||
action_context = {
|
||||
'action_execution_id': action_ex.id,
|
||||
'callback_url': '/v2/action_executions/%s' % action_ex.id,
|
||||
'task_id': None,
|
||||
'task_name': None,
|
||||
'task_tags': None,
|
||||
'workflow_name': None,
|
||||
'workflow_execution_id': None
|
||||
}
|
||||
|
||||
self.assertIn('action_context', action_ex.input)
|
||||
self.assertEqual(action_context, action_ex.input['action_context'])
|
||||
|
||||
@mock.patch.object(
|
||||
requests, 'request',
|
||||
mock.MagicMock(return_value=test_base.FakeHTTPResponse('', 200, 'OK')))
|
||||
def test_single_async_action_context(self):
|
||||
action_ex = self.engine.start_action(
|
||||
'std.mistral_http',
|
||||
{'url': 'https://wiki.openstack.org/wiki/mistral'},
|
||||
save_result=False
|
||||
)
|
||||
|
||||
action_context = {
|
||||
'action_execution_id': action_ex.id,
|
||||
'callback_url': '/v2/action_executions/%s' % action_ex.id,
|
||||
'task_id': None,
|
||||
'task_name': None,
|
||||
'task_tags': None,
|
||||
'workflow_name': None,
|
||||
'workflow_execution_id': None
|
||||
}
|
||||
|
||||
self.assertIn('action_context', action_ex.input)
|
||||
self.assertEqual(action_context, action_ex.input['action_context'])
|
||||
|
||||
@mock.patch.object(
|
||||
requests, 'request',
|
||||
mock.MagicMock(return_value=test_base.FakeHTTPResponse('', 200, 'OK')))
|
||||
@mock.patch.object(
|
||||
std_actions.MistralHTTPAction, 'is_sync',
|
||||
mock.MagicMock(return_value=True))
|
||||
def test_single_sync_saved_action_context(self):
|
||||
action_ex = self.engine.start_action(
|
||||
'std.mistral_http',
|
||||
{'url': 'https://wiki.openstack.org/wiki/mistral'},
|
||||
save_result=True
|
||||
)
|
||||
|
||||
action_context = {
|
||||
'action_execution_id': action_ex.id,
|
||||
'callback_url': '/v2/action_executions/%s' % action_ex.id,
|
||||
'task_id': None,
|
||||
'task_name': None,
|
||||
'task_tags': None,
|
||||
'workflow_name': None,
|
||||
'workflow_execution_id': None
|
||||
}
|
||||
|
||||
self.assertIn('action_context', action_ex.input)
|
||||
self.assertEqual(action_context, action_ex.input['action_context'])
|
||||
|
||||
@mock.patch.object(
|
||||
requests, 'request',
|
||||
mock.MagicMock(return_value=test_base.FakeHTTPResponse('', 200, 'OK')))
|
||||
@mock.patch.object(
|
||||
std_actions.MistralHTTPAction, 'is_sync',
|
||||
mock.MagicMock(return_value=True))
|
||||
def test_single_sync_action_context(self):
|
||||
action_ex = self.engine.start_action(
|
||||
'std.mistral_http',
|
||||
{'url': 'https://wiki.openstack.org/wiki/mistral'},
|
||||
save_result=False
|
||||
)
|
||||
|
||||
action_context = {
|
||||
'action_execution_id': None,
|
||||
'callback_url': None,
|
||||
'task_id': None,
|
||||
'task_name': None,
|
||||
'task_tags': None,
|
||||
'workflow_name': None,
|
||||
'workflow_execution_id': None
|
||||
}
|
||||
|
||||
self.assertIn('action_context', action_ex.input)
|
||||
self.assertEqual(action_context, action_ex.input['action_context'])
|
||||
|
Loading…
Reference in New Issue
Block a user