Update AdHoc Actions to support context data references

AdHoc actions can be defined using YAQL and Jinja2 expressions in the
same way as Tasks, but they could not access the associated context
data because the context was not available when the expression is
evaluated.  This patchset passes the task and workflow context into
the AdHocAction object so that the inputs can be evaluated using the
available context, and the context data will be available for
reference.

Added a test to verify that the env() works in AdHoc Actions.

Change-Id: Ib95604d3d494a443e852bc7f5eee24f398b1648c
Closes-Bug: 1690158
This commit is contained in:
Bob Haddleton 2017-05-15 10:40:59 -05:00
parent b6de4720db
commit a121aacbbc
4 changed files with 53 additions and 3 deletions

View File

@ -31,6 +31,7 @@ from mistral.services import action_manager as a_m
from mistral.services import security
from mistral import utils
from mistral.utils import wf_trace
from mistral.workflow import data_flow
from mistral.workflow import states
from mistral.workflow import utils as wf_utils
@ -338,7 +339,8 @@ class PythonAction(Action):
class AdHocAction(PythonAction):
"""Ad-hoc action."""
def __init__(self, action_def, action_ex=None, task_ex=None):
def __init__(self, action_def, action_ex=None, task_ex=None, task_ctx=None,
wf_ctx=None):
self.action_spec = spec_parser.get_action_spec(action_def.spec)
base_action_def = db_api.get_action_definition(
@ -355,6 +357,8 @@ class AdHocAction(PythonAction):
)
self.adhoc_action_def = action_def
self.task_ctx = task_ctx or {}
self.wf_ctx = wf_ctx or {}
def validate_input(self, input_dict):
expected_input = self.action_spec.get_input()
@ -382,9 +386,14 @@ class AdHocAction(PythonAction):
base_input_expr = action_spec.get_base_input()
if base_input_expr:
ctx_view = data_flow.ContextView(
base_input_dict,
self.task_ctx,
self.wf_ctx
)
base_input_dict = expr.evaluate_recursively(
base_input_expr,
base_input_dict
ctx_view
)
else:
base_input_dict = {}

View File

@ -404,7 +404,9 @@ class RegularTask(Task):
)
if action_def.spec:
return actions.AdHocAction(action_def, task_ex=self.task_ex)
return actions.AdHocAction(action_def, task_ex=self.task_ex,
task_ctx=self.ctx,
wf_ctx=self.wf_ex.context)
return actions.PythonAction(action_def, task_ex=self.task_ex)

View File

@ -41,6 +41,11 @@ actions:
- s2
output: "<% $ %> and <% $ %>"
test_env:
base: std.echo
base-input:
output: '{{ env().foo }}'
workflows:
wf1:
type: direct
@ -81,6 +86,20 @@ workflows:
tasks:
concat:
action: concat_twice
wf4:
type: direct
input:
- str1
output:
workflow_result: '{{ _.printenv_result }}'
tasks:
printenv:
action: test_env
publish:
printenv_result: '{{ task().result }}'
"""
@ -135,3 +154,18 @@ class AdhocActionsTest(base.EngineTestCase):
self.assertIn("Invalid input", wf_ex.state_info)
self.assertEqual(states.ERROR, wf_ex.state)
def test_run_adhoc_action_with_env(self):
wf_ex = self.engine.start_workflow(
'my_wb.wf4', {'str1': 'a'}, env={'foo': 'bar'})
self.await_workflow_success(wf_ex.id)
with db_api.transaction():
wf_ex = db_api.get_workflow_execution(wf_ex.id)
self.assertDictEqual(
{
'workflow_result': 'bar'
},
wf_ex.output
)

View File

@ -0,0 +1,5 @@
---
fixes:
- Added support for referencing task and workflow context data, including
environment variables via env(), when using YAQL/Jinja2 expressions inside AdHoc Actions.
YAQL/Jinja2 expressions can reference env() and other context data in the base-input section.