Add executions yaql filter
This allows for filtering or executions Implements: blueprint mistral-workflow-executions-yaql-function Change-Id: I8d41c662d8659375750b52f7510e9a35f8b42f93
This commit is contained in:
parent
9b356b6486
commit
ad733d3112
|
@ -1394,6 +1394,68 @@ Execution info is available by **execution()**. It contains
|
||||||
information about execution itself such as **id**, **wf_spec**,
|
information about execution itself such as **id**, **wf_spec**,
|
||||||
**input** and **start_params**.
|
**input** and **start_params**.
|
||||||
|
|
||||||
|
Executions function
|
||||||
|
'''''''''''''''''''
|
||||||
|
|
||||||
|
Signature:
|
||||||
|
**executions(id=null, root_execution_id=null, state=null,
|
||||||
|
from_time=null, to_time=null)**
|
||||||
|
|
||||||
|
Description:
|
||||||
|
|
||||||
|
This function allows users to filter all executions by execution id,
|
||||||
|
root_execution_id ,state and/or created_at time.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
#. **id** - If provided will return a list of executions with that id.
|
||||||
|
Otherwise it will return all executions that match the other
|
||||||
|
parameters. *Optional.*
|
||||||
|
#. **root_execution_id** - Similar to id above, if provided will return
|
||||||
|
a list of executions with that root_execution_id. Otherwise it will
|
||||||
|
return all executions that match the other parameters. *Optional.*
|
||||||
|
False by default.
|
||||||
|
#. **state** - If provided, the executions will be filtered by their
|
||||||
|
current state. If state isn't provided, all executions that match the
|
||||||
|
other parameters will be returned . *Optional.*
|
||||||
|
#. **from_time** - If provided, the executions will be filtered by their
|
||||||
|
created_at time being greater or equal to the from_time parameter.
|
||||||
|
If from_time isn't provided, all executions that match the
|
||||||
|
other parameters will be returned. from_time parameter can be provided
|
||||||
|
in the format *YYYY-MM-DD hh:mm:ss*
|
||||||
|
*Optional.*
|
||||||
|
#. **to_time** - If provided, the executions will be filtered by their
|
||||||
|
created_at time being less than to the from_time parameter (less than but
|
||||||
|
not less than equal as the from_time parameter does)
|
||||||
|
If to_time isn't provided, all executions that match the
|
||||||
|
other parameters will be returned. to_time parameter can be provided
|
||||||
|
in the format *YYYY-MM-DD hh:mm:ss*
|
||||||
|
*Optional.*
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
Workflow definition:
|
||||||
|
|
||||||
|
.. code-block:: mistral
|
||||||
|
|
||||||
|
---
|
||||||
|
version: "v2.0"
|
||||||
|
wf:
|
||||||
|
tasks:
|
||||||
|
task:
|
||||||
|
action: std.noop
|
||||||
|
publish:
|
||||||
|
all_executions_yaql: <% executions() %>
|
||||||
|
all_child_executions_of_this_execution: "{{ executions(root_execution_id=execution().id) }}"
|
||||||
|
|
||||||
|
all_executions_in_error_yaql: <% executions(null, null, ERROR) %>
|
||||||
|
all_executions_in_error_jinja: "{{ executions(None, None, 'ERROR') }}"
|
||||||
|
all_executions_in_error_yaql_with_kw: <% executions(state => ERROR) %>
|
||||||
|
all_executions_in_error_jinja_with_kw: "{{ executions(state='ERROR') }}"
|
||||||
|
|
||||||
|
all_executions_filtered_date_jinja: "{{ executions(to_time="2016-12-01 15:01:00") }}"
|
||||||
|
|
||||||
|
|
||||||
Environment
|
Environment
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,10 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import datetime
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
from mistral.db.v2.sqlalchemy import api as db_api
|
||||||
from mistral import exceptions as exc
|
from mistral import exceptions as exc
|
||||||
from mistral.expressions import jinja_expression as expr
|
from mistral.expressions import jinja_expression as expr
|
||||||
from mistral.tests.unit import base
|
from mistral.tests.unit import base
|
||||||
|
@ -36,6 +38,38 @@ SERVERS = {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WF_EXECS = [
|
||||||
|
{
|
||||||
|
'spec': {},
|
||||||
|
'id': "one",
|
||||||
|
'start_params': {'task': 'my_task1'},
|
||||||
|
'state': 'IDLE',
|
||||||
|
'state_info': "Running...",
|
||||||
|
'created_at': datetime.datetime(2016, 12, 1, 15, 0, 0),
|
||||||
|
'updated_at': None,
|
||||||
|
'context': None,
|
||||||
|
'task_id': None,
|
||||||
|
'trust_id': None,
|
||||||
|
'description': None,
|
||||||
|
'output': None
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'spec': {},
|
||||||
|
'id': "two",
|
||||||
|
'root_execution_id': "one",
|
||||||
|
'start_params': {'task': 'my_task1'},
|
||||||
|
'state': 'RUNNING',
|
||||||
|
'state_info': "Running...",
|
||||||
|
'created_at': datetime.datetime(2016, 12, 1, 15, 1, 0),
|
||||||
|
'updated_at': None,
|
||||||
|
'context': {'image_id': '123123'},
|
||||||
|
'task_id': None,
|
||||||
|
'trust_id': None,
|
||||||
|
'description': None,
|
||||||
|
'output': None
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class JinjaEvaluatorTest(base.BaseTest):
|
class JinjaEvaluatorTest(base.BaseTest):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -314,6 +348,127 @@ class JinjaEvaluatorTest(base.BaseTest):
|
||||||
'updated_at': wf_ex.updated_at.isoformat(' ')
|
'updated_at': wf_ex.updated_at.isoformat(' ')
|
||||||
}, result)
|
}, result)
|
||||||
|
|
||||||
|
def test_executions(self):
|
||||||
|
with db_api.transaction():
|
||||||
|
created0 = db_api.create_workflow_execution(WF_EXECS[0])
|
||||||
|
created1 = db_api.create_workflow_execution(WF_EXECS[1])
|
||||||
|
|
||||||
|
ctx = {
|
||||||
|
'__execution': {
|
||||||
|
'id': 'some'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = self._evaluator.evaluate('_|executions()', ctx)
|
||||||
|
|
||||||
|
self.assertEqual([created0, created1], result)
|
||||||
|
db_api.rollback_tx()
|
||||||
|
|
||||||
|
def test_executions_id_filter(self):
|
||||||
|
with db_api.transaction():
|
||||||
|
created0 = db_api.create_workflow_execution(WF_EXECS[0])
|
||||||
|
created1 = db_api.create_workflow_execution(WF_EXECS[1])
|
||||||
|
|
||||||
|
ctx = {
|
||||||
|
'__execution': {
|
||||||
|
'id': 'some'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = self._evaluator.evaluate('_|executions("one")', ctx)
|
||||||
|
|
||||||
|
self.assertEqual([created0], result)
|
||||||
|
|
||||||
|
result = self._evaluator.evaluate(
|
||||||
|
'executions(root_execution_id="one") ', ctx
|
||||||
|
)
|
||||||
|
self.assertEqual([created1], result)
|
||||||
|
db_api.rollback_tx()
|
||||||
|
|
||||||
|
def test_executions_state_filter(self):
|
||||||
|
with db_api.transaction():
|
||||||
|
db_api.create_workflow_execution(WF_EXECS[0])
|
||||||
|
created1 = db_api.create_workflow_execution(WF_EXECS[1])
|
||||||
|
|
||||||
|
ctx = {
|
||||||
|
'__execution': {
|
||||||
|
'id': 'some'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = self._evaluator.evaluate(
|
||||||
|
'_|executions(state="RUNNING")', ctx
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual([created1], result)
|
||||||
|
|
||||||
|
result = self._evaluator.evaluate(
|
||||||
|
'_|executions(id="one", state="RUNNING")', ctx
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual([], result)
|
||||||
|
db_api.rollback_tx()
|
||||||
|
|
||||||
|
def test_executions_from_time_filter(self):
|
||||||
|
with db_api.transaction():
|
||||||
|
created0 = db_api.create_workflow_execution(WF_EXECS[0])
|
||||||
|
created1 = db_api.create_workflow_execution(WF_EXECS[1])
|
||||||
|
|
||||||
|
ctx = {
|
||||||
|
'__execution': {
|
||||||
|
'id': 'some'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = self._evaluator.evaluate(
|
||||||
|
'_|executions(from_time="2000-01-01")', ctx
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual([created0, created1], result)
|
||||||
|
|
||||||
|
result = self._evaluator.evaluate(
|
||||||
|
'_|executions(from_time="2016-12-01 15:01:00")', ctx
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual([created1], result)
|
||||||
|
|
||||||
|
result = self._evaluator.evaluate(
|
||||||
|
'_|executions(id="one", from_time="2016-12-01 15:01:00")', ctx
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual([], result)
|
||||||
|
db_api.rollback_tx()
|
||||||
|
|
||||||
|
def test_executions_to_time_filter(self):
|
||||||
|
with db_api.transaction():
|
||||||
|
created0 = db_api.create_workflow_execution(WF_EXECS[0])
|
||||||
|
created1 = db_api.create_workflow_execution(WF_EXECS[1])
|
||||||
|
|
||||||
|
ctx = {
|
||||||
|
'__execution': {
|
||||||
|
'id': 'some'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = self._evaluator.evaluate(
|
||||||
|
'_|executions(to_time="2020-01-01")', ctx
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual([created0, created1], result)
|
||||||
|
|
||||||
|
result = self._evaluator.evaluate(
|
||||||
|
'_|executions(to_time="2016-12-01 15:01:00")', ctx
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual([created0], result)
|
||||||
|
|
||||||
|
result = self._evaluator.evaluate(
|
||||||
|
'_|executions(id="two", to_time="2016-12-01 15:01:00")', ctx
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual([], result)
|
||||||
|
db_api.rollback_tx()
|
||||||
|
|
||||||
@mock.patch('mistral.db.v2.api.get_workflow_execution')
|
@mock.patch('mistral.db.v2.api.get_workflow_execution')
|
||||||
def test_function_execution(self, workflow_execution):
|
def test_function_execution(self, workflow_execution):
|
||||||
wf_ex = mock.MagicMock(return_value={})
|
wf_ex = mock.MagicMock(return_value={})
|
||||||
|
|
|
@ -104,6 +104,58 @@ def env_(context):
|
||||||
return context['__env']
|
return context['__env']
|
||||||
|
|
||||||
|
|
||||||
|
def executions_(context,
|
||||||
|
id=None,
|
||||||
|
root_execution_id=None,
|
||||||
|
state=None,
|
||||||
|
from_time=None,
|
||||||
|
to_time=None
|
||||||
|
):
|
||||||
|
|
||||||
|
filter = {}
|
||||||
|
if id is not None:
|
||||||
|
filter = utils.filter_utils.create_or_update_filter(
|
||||||
|
'id',
|
||||||
|
id,
|
||||||
|
"eq",
|
||||||
|
filter
|
||||||
|
)
|
||||||
|
if root_execution_id is not None:
|
||||||
|
filter = utils.filter_utils.create_or_update_filter(
|
||||||
|
'root_execution_id',
|
||||||
|
root_execution_id,
|
||||||
|
"eq",
|
||||||
|
filter
|
||||||
|
)
|
||||||
|
|
||||||
|
if state is not None:
|
||||||
|
filter = utils.filter_utils.create_or_update_filter(
|
||||||
|
'state',
|
||||||
|
state,
|
||||||
|
"eq",
|
||||||
|
filter
|
||||||
|
)
|
||||||
|
|
||||||
|
if from_time is not None:
|
||||||
|
filter = utils.filter_utils.create_or_update_filter(
|
||||||
|
'created_at',
|
||||||
|
from_time,
|
||||||
|
"gte",
|
||||||
|
filter
|
||||||
|
)
|
||||||
|
|
||||||
|
if to_time is not None:
|
||||||
|
filter = utils.filter_utils.create_or_update_filter(
|
||||||
|
'created_at',
|
||||||
|
to_time,
|
||||||
|
"lt",
|
||||||
|
filter
|
||||||
|
)
|
||||||
|
|
||||||
|
wf_executions = db_api.get_workflow_executions(**filter)
|
||||||
|
return wf_executions
|
||||||
|
|
||||||
|
|
||||||
def execution_(context):
|
def execution_(context):
|
||||||
wf_ex = db_api.get_workflow_execution(context['__execution']['id'])
|
wf_ex = db_api.get_workflow_execution(context['__execution']['id'])
|
||||||
|
|
||||||
|
@ -251,7 +303,6 @@ def _get_tasks_from_db(workflow_execution_id=None, recursive=False, state=None,
|
||||||
|
|
||||||
def tasks_(context, workflow_execution_id=None, recursive=False, state=None,
|
def tasks_(context, workflow_execution_id=None, recursive=False, state=None,
|
||||||
flat=False):
|
flat=False):
|
||||||
|
|
||||||
task_execs = _get_tasks_from_db(
|
task_execs = _get_tasks_from_db(
|
||||||
workflow_execution_id,
|
workflow_execution_id,
|
||||||
recursive,
|
recursive,
|
||||||
|
|
|
@ -84,6 +84,7 @@ mistral.expression.functions =
|
||||||
|
|
||||||
env = mistral.utils.expression_utils:env_
|
env = mistral.utils.expression_utils:env_
|
||||||
execution = mistral.utils.expression_utils:execution_
|
execution = mistral.utils.expression_utils:execution_
|
||||||
|
executions = mistral.utils.expression_utils:executions_
|
||||||
global = mistral.utils.expression_utils:global_
|
global = mistral.utils.expression_utils:global_
|
||||||
json_parse = mistral.utils.expression_utils:json_parse_
|
json_parse = mistral.utils.expression_utils:json_parse_
|
||||||
json_dump = mistral.utils.expression_utils:json_dump_
|
json_dump = mistral.utils.expression_utils:json_dump_
|
||||||
|
|
Loading…
Reference in New Issue