Getting rid of "policies" keyword

* Removed "policies" keyword
* Removed obsolete stubs for trigger specs
* Other minor renamings and refactorings
* Fixed "join" tests: all partial join tests were not thread-safe

Change-Id: I31b00d5d221b3a4bf03d1ab47622692c2b0f3013
This commit is contained in:
Renat Akhmerov 2015-04-17 14:43:20 +06:00
parent f9357309c2
commit b79f1f277b
17 changed files with 228 additions and 312 deletions

View File

@ -32,14 +32,13 @@ workflows:
task1:
description: This is a test task
action: action1 name=<% $.name %>
policies:
wait-before: 2
wait-after: 5
retry:
count: 10
delay: 30
break-on: <% $.my_val = 10 %>
concurrency: 3
wait-before: 2
wait-after: 5
retry:
count: 10
delay: 30
break-on: <% $.my_val = 10 %>
concurrency: 3
task2:
requires: [task1]
@ -50,11 +49,10 @@ workflows:
type: direct
task-defaults:
policies:
retry:
count: 10
delay: 30
break-on: <% $.my_val = 10 %>
retry:
count: 10
delay: 30
break-on: <% $.my_val = 10 %>
on-error:
- fail: <% $.my_val = 0 %>
on-success:

View File

@ -255,16 +255,19 @@ class JoinEngineTest(base.EngineTestCase):
self.assertEqual(4, len(tasks))
task4 = self._assert_single_item(tasks, name='task4')
task1 = self._assert_single_item(tasks, name='task1')
task2 = self._assert_single_item(tasks, name='task2')
task3 = self._assert_single_item(tasks, name='task3')
task4 = self._assert_single_item(tasks, name='task4')
self.assertEqual(states.SUCCESS, task1.state)
self.assertEqual(states.SUCCESS, task2.state)
self.assertEqual(states.ERROR, task3.state)
self.assertEqual(states.SUCCESS, task4.state)
# task3 may still be in RUNNING state and we need to make sure
# it gets into ERROR state.
self._await(lambda: self.is_task_error(task3.id))
self.assertDictEqual({'result4': '1,2'}, task4.published)
self.assertDictEqual({'result': '1,2'}, wf_ex.output)
@ -332,18 +335,15 @@ class JoinEngineTest(base.EngineTestCase):
self.assertEqual(5, len(tasks))
task1 = self._assert_single_item(tasks, name='task1')
task2 = self._assert_single_item(tasks, name='task2')
task3 = self._assert_single_item(tasks, name='task3')
task4 = self._assert_single_item(tasks, name='task4')
task5 = self._assert_single_item(tasks, name='task5')
self.assertEqual(states.SUCCESS, task1.state)
self.assertEqual(states.SUCCESS, task2.state)
self.assertEqual(states.SUCCESS, task3.state)
self.assertEqual(states.SUCCESS, task4.state)
self.assertEqual(states.SUCCESS, task5.state)
success_count = sum([1 for t in tasks if t.state == states.SUCCESS])
# At least task4 and two others must be successfully completed.
self.assertTrue(success_count >= 3)
result5 = task5.published['result5']
self.assertIsNotNone(result5)
@ -406,16 +406,15 @@ class JoinEngineTest(base.EngineTestCase):
self.assertEqual(4, len(tasks))
task1 = self._assert_single_item(tasks, name='task1')
task2 = self._assert_single_item(tasks, name='task2')
task3 = self._assert_single_item(tasks, name='task3')
task4 = self._assert_single_item(tasks, name='task4')
self.assertEqual(states.SUCCESS, task1.state)
self.assertEqual(states.SUCCESS, task2.state)
self.assertEqual(states.SUCCESS, task3.state)
self.assertEqual(states.SUCCESS, task4.state)
success_count = sum([1 for t in tasks if t.state == states.SUCCESS])
# At least task4 and one of others must be successfully completed.
self.assertTrue(success_count >= 2)
result4 = task4.published['result4']
self.assertIsNotNone(result4)

View File

@ -42,14 +42,13 @@ workflows:
tasks:
task1:
action: std.echo output="Hi!"
policies:
wait-before: 2
wait-after: 5
timeout: 7
retry:
count: 5
delay: 10
break-on: <% $.my_val = 10 %>
wait-before: 2
wait-after: 5
timeout: 7
retry:
count: 5
delay: 10
break-on: <% $.my_val = 10 %>
"""
@ -64,19 +63,17 @@ workflows:
type: direct
task-defaults:
policies:
wait-before: 2
retry:
count: 2
delay: 1
wait-before: 2
retry:
count: 2
delay: 1
tasks:
task1:
action: std.echo output="Hi!"
policies:
wait-before: 3
wait-after: 5
timeout: 7
wait-before: 3
wait-after: 5
timeout: 7
"""
@ -94,8 +91,7 @@ workflows:
tasks:
task1:
action: std.echo output="Hi!"
policies:
wait-before: 1
wait-before: 1
"""
@ -115,8 +111,7 @@ workflows:
tasks:
task1:
action: std.echo output="Hi!"
policies:
wait-before: <% $.wait_before %>
wait-before: <% $.wait_before %>
"""
@ -133,8 +128,7 @@ workflows:
tasks:
task1:
action: std.echo output="Hi!"
policies:
wait-after: 2
wait-after: 2
"""
@ -151,10 +145,9 @@ workflows:
tasks:
task1:
action: std.http url="http://some_non-existing_host"
policies:
retry:
count: 3
delay: 1
retry:
count: 3
delay: 1
"""
@ -171,15 +164,13 @@ workflows:
tasks:
task1:
action: std.async_noop
policies:
timeout: 2
timeout: 2
on-error:
- task2
task2:
action: std.echo output="Hi!"
policies:
timeout: 3
timeout: 3
"""
@ -194,9 +185,8 @@ workflows:
tasks:
task1:
action: std.echo output="Hi!"
policies:
wait-after: 4
timeout: 3
wait-after: 4
timeout: 3
"""
@ -211,8 +201,7 @@ workflows:
tasks:
task1:
action: std.echo output="Hi!"
policies:
pause-before: True
pause-before: True
on-success:
- task2
task2:
@ -231,8 +220,7 @@ workflows:
tasks:
task1:
action: std.echo output="Hi!"
policies:
concurrency: 4
concurrency: 4
"""
@ -512,8 +500,7 @@ class PoliciesTest(base.EngineTestCase):
tasks:
task1:
action: std.echo output="Hi!"
policies:
wait-before: <% $.wait_before %>
wait-before: <% $.wait_before %>
"""
wb_service.create_workbook_v2(wb)
@ -535,8 +522,7 @@ class PoliciesTest(base.EngineTestCase):
task1:
action: std.noop
policies:
wait-before: 1
wait-before: 1
task2:
action: std.noop

View File

@ -85,10 +85,9 @@ wf:
type: reverse
task-defaults:
policies:
retry:
count: 2
delay: 1
retry:
count: 2
delay: 1
tasks:
task1:
@ -108,8 +107,7 @@ wf:
type: reverse
task-defaults:
policies:
timeout: 1
timeout: 1
tasks:
task1:
@ -128,9 +126,8 @@ wf:
type: reverse
task-defaults:
policies:
wait-before: 1
wait-after: 1
wait-before: 1
wait-after: 1
tasks:
task1:
@ -146,7 +143,6 @@ class TaskDefaultsReverseWorkflowEngineTest(base.EngineTestCase):
self.addCleanup(thread_group.stop)
@testtools.skip("Fix 'retry' policy.")
def test_task_defaults_retry_policy(self):
wf_service.create_workflows(REVERSE_WF_RETRY)
@ -190,7 +186,6 @@ class TaskDefaultsReverseWorkflowEngineTest(base.EngineTestCase):
self._assert_single_item(tasks, name='task1', state=states.ERROR)
@testtools.skip("Fix 'wait' policies.")
def test_task_defaults_wait_policies(self):
wf_service.create_workflows(REVERSE_WF_WAIT)

View File

@ -65,8 +65,7 @@ workflows:
tasks:
task1:
action: std.echo output="Hi!"
policies:
wait-after: 1
wait-after: 1
task2:
action: std.echo output="Task 2"

View File

@ -13,7 +13,6 @@
# limitations under the License.
from mistral.db.v2 import api as db_api
from mistral.services import scheduler
from mistral.services import workflows as wf_service
from mistral.tests.unit.engine import base
from mistral.workflow import states
@ -36,15 +35,10 @@ class WorkflowStopTest(base.EngineTestCase):
task2:
action: std.echo output="foo"
policies:
wait-before: 3
wait-before: 3
"""
wf_service.create_workflows(WORKFLOW)
# Note(dzimine): scheduler.setup is nessessary for wait- policies.
thread_group = scheduler.setup()
self.addCleanup(thread_group.stop)
self.exec_id = self.engine.start_workflow('wf', {}).id
def test_stop_failed(self):

View File

@ -156,52 +156,49 @@ class TaskSpecValidation(v2_base.WorkflowSpecValidationTestCase):
def test_policies(self):
tests = [
({'policies': {'retry': {'count': 3, 'delay': 1}}}, False),
({'policies': {'retry': {'count': '<% 3 %>', 'delay': 1}}},
False),
({'policies': {'retry': {'count': '<% * %>', 'delay': 1}}},
True),
({'policies': {'retry': {'count': 3, 'delay': '<% 1 %>'}}},
False),
({'policies': {'retry': {'count': 3, 'delay': '<% * %>'}}},
True),
({'policies': {'retry': {'count': -3, 'delay': 1}}}, True),
({'policies': {'retry': {'count': 3, 'delay': -1}}}, True),
({'policies': {'retry': {'count': '3', 'delay': 1}}}, True),
({'policies': {'retry': {'count': 3, 'delay': '1'}}}, True),
({'policies': {'retry': None}}, True),
({'policies': {'wait-before': 1}}, False),
({'policies': {'wait-before': '<% 1 %>'}}, False),
({'policies': {'wait-before': '<% * %>'}}, True),
({'policies': {'wait-before': -1}}, True),
({'policies': {'wait-before': 1.0}}, True),
({'policies': {'wait-before': '1'}}, True),
({'policies': {'wait-after': 1}}, False),
({'policies': {'wait-after': '<% 1 %>'}}, False),
({'policies': {'wait-after': '<% * %>'}}, True),
({'policies': {'wait-after': -1}}, True),
({'policies': {'wait-after': 1.0}}, True),
({'policies': {'wait-after': '1'}}, True),
({'policies': {'timeout': 300}}, False),
({'policies': {'timeout': '<% 300 %>'}}, False),
({'policies': {'timeout': '<% * %>'}}, True),
({'policies': {'timeout': -300}}, True),
({'policies': {'timeout': 300.0}}, True),
({'policies': {'timeout': '300'}}, True),
({'policies': {'pause-before': False}}, False),
({'policies': {'pause-before': '<% False %>'}}, False),
({'policies': {'pause-before': '<% * %>'}}, True),
({'policies': {'pause-before': 'False'}}, True),
({'policies': {'concurrency': 10}}, False),
({'policies': {'concurrency': '<% 10 %>'}}, False),
({'policies': {'concurrency': '<% * %>'}}, True),
({'policies': {'concurrency': -10}}, True),
({'policies': {'concurrency': 10.0}}, True),
({'policies': {'concurrency': '10'}}, True)
({'retry': {'count': 3, 'delay': 1}}, False),
({'retry': {'count': '<% 3 %>', 'delay': 1}}, False),
({'retry': {'count': '<% * %>', 'delay': 1}}, True),
({'retry': {'count': 3, 'delay': '<% 1 %>'}}, False),
({'retry': {'count': 3, 'delay': '<% * %>'}}, True),
({'retry': {'count': -3, 'delay': 1}}, True),
({'retry': {'count': 3, 'delay': -1}}, True),
({'retry': {'count': '3', 'delay': 1}}, True),
({'retry': {'count': 3, 'delay': '1'}}, True),
({'retry': None}, True),
({'wait-before': 1}, False),
({'wait-before': '<% 1 %>'}, False),
({'wait-before': '<% * %>'}, True),
({'wait-before': -1}, True),
({'wait-before': 1.0}, True),
({'wait-before': '1'}, True),
({'wait-after': 1}, False),
({'wait-after': '<% 1 %>'}, False),
({'wait-after': '<% * %>'}, True),
({'wait-after': -1}, True),
({'wait-after': 1.0}, True),
({'wait-after': '1'}, True),
({'timeout': 300}, False),
({'timeout': '<% 300 %>'}, False),
({'timeout': '<% * %>'}, True),
({'timeout': -300}, True),
({'timeout': 300.0}, True),
({'timeout': '300'}, True),
({'pause-before': False}, False),
({'pause-before': '<% False %>'}, False),
({'pause-before': '<% * %>'}, True),
({'pause-before': 'False'}, True),
({'concurrency': 10}, False),
({'concurrency': '<% 10 %>'}, False),
({'concurrency': '<% * %>'}, True),
({'concurrency': -10}, True),
({'concurrency': 10.0}, True),
({'concurrency': '10'}, True)
]
for policy, expect_error in tests:
overlay = {'test': {'tasks': {'get': policy}}}
self._parse_dsl_spec(add_tasks=True,
changes=overlay,
expect_error=expect_error)

View File

@ -33,7 +33,6 @@ class WorkbookSpecValidation(base.WorkbookSpecValidationTestCase):
# Workbook.
act_specs = wb_spec.get_actions()
wf_specs = wb_spec.get_workflows()
tr_specs = wb_spec.get_triggers()
self.assertEqual('2.0', wb_spec.get_version())
self.assertEqual('my_workbook', wb_spec.get_name())
@ -41,7 +40,6 @@ class WorkbookSpecValidation(base.WorkbookSpecValidationTestCase):
self.assertListEqual(['test', 'v2'], wb_spec.get_tags())
self.assertIsNotNone(act_specs)
self.assertIsNotNone(wf_specs)
self.assertIsNone(tr_specs)
# Actions.
action_spec = act_specs.get('action1')
@ -385,20 +383,3 @@ class WorkbookSpecValidation(base.WorkbookSpecValidationTestCase):
for workflows, expect_error in tests:
self._parse_dsl_spec(changes=workflows,
expect_error=expect_error)
def test_triggers(self):
tests = [
({'triggers': []}, True),
({'triggers': {}}, True),
({'triggers': None}, True),
({'triggers': {'version': None}}, True),
({'triggers': {'version': ''}}, True),
({'triggers': {'version': '1.0'}}, True),
({'triggers': {'version': '2.0'}}, False),
({'triggers': {'version': 2.0}}, False),
({'triggers': {'version': 2}}, False)
]
for triggers, expect_error in tests:
self._parse_dsl_spec(changes=triggers,
expect_error=expect_error)

View File

@ -63,9 +63,9 @@ class WorkflowSpecValidation(base.WorkflowSpecValidationTestCase):
def test_direct_workflow_invalid_task(self):
overlay = {'test': {'type': 'direct', 'tasks': {}}}
require = {'requires': ['echo', 'get']}
requires = {'requires': ['echo', 'get']}
utils.merge_dicts(overlay['test']['tasks'], {'email': require})
utils.merge_dicts(overlay['test']['tasks'], {'email': requires})
self._parse_dsl_spec(add_tasks=True,
changes=overlay,
@ -218,48 +218,44 @@ class WorkflowSpecValidation(base.WorkflowSpecValidationTestCase):
({'on-complete': []}, True),
({'on-complete': ['email', 'email']}, True),
({'on-complete': ['email', 12345]}, True),
({'policies': {'retry': {'count': 3, 'delay': 1}}}, False),
({'policies': {'retry': {'count': '<% 3 %>', 'delay': 1}}},
False),
({'policies': {'retry': {'count': '<% * %>', 'delay': 1}}},
True),
({'policies': {'retry': {'count': 3, 'delay': '<% 1 %>'}}},
False),
({'policies': {'retry': {'count': 3, 'delay': '<% * %>'}}},
True),
({'policies': {'retry': {'count': -3, 'delay': 1}}}, True),
({'policies': {'retry': {'count': 3, 'delay': -1}}}, True),
({'policies': {'retry': {'count': '3', 'delay': 1}}}, True),
({'policies': {'retry': {'count': 3, 'delay': '1'}}}, True),
({'policies': {'retry': None}}, True),
({'policies': {'wait-before': 1}}, False),
({'policies': {'wait-before': '<% 1 %>'}}, False),
({'policies': {'wait-before': '<% * %>'}}, True),
({'policies': {'wait-before': -1}}, True),
({'policies': {'wait-before': 1.0}}, True),
({'policies': {'wait-before': '1'}}, True),
({'policies': {'wait-after': 1}}, False),
({'policies': {'wait-after': '<% 1 %>'}}, False),
({'policies': {'wait-after': '<% * %>'}}, True),
({'policies': {'wait-after': -1}}, True),
({'policies': {'wait-after': 1.0}}, True),
({'policies': {'wait-after': '1'}}, True),
({'policies': {'timeout': 300}}, False),
({'policies': {'timeout': '<% 300 %>'}}, False),
({'policies': {'timeout': '<% * %>'}}, True),
({'policies': {'timeout': -300}}, True),
({'policies': {'timeout': 300.0}}, True),
({'policies': {'timeout': '300'}}, True),
({'policies': {'pause-before': False}}, False),
({'policies': {'pause-before': '<% False %>'}}, False),
({'policies': {'pause-before': '<% * %>'}}, True),
({'policies': {'pause-before': 'False'}}, True),
({'policies': {'concurrency': 10}}, False),
({'policies': {'concurrency': '<% 10 %>'}}, False),
({'policies': {'concurrency': '<% * %>'}}, True),
({'policies': {'concurrency': -10}}, True),
({'policies': {'concurrency': 10.0}}, True),
({'policies': {'concurrency': '10'}}, True)
({'retry': {'count': 3, 'delay': 1}}, False),
({'retry': {'count': '<% 3 %>', 'delay': 1}}, False),
({'retry': {'count': '<% * %>', 'delay': 1}}, True),
({'retry': {'count': 3, 'delay': '<% 1 %>'}}, False),
({'retry': {'count': 3, 'delay': '<% * %>'}}, True),
({'retry': {'count': -3, 'delay': 1}}, True),
({'retry': {'count': 3, 'delay': -1}}, True),
({'retry': {'count': '3', 'delay': 1}}, True),
({'retry': {'count': 3, 'delay': '1'}}, True),
({'retry': None}, True),
({'wait-before': 1}, False),
({'wait-before': '<% 1 %>'}, False),
({'wait-before': '<% * %>'}, True),
({'wait-before': -1}, True),
({'wait-before': 1.0}, True),
({'wait-before': '1'}, True),
({'wait-after': 1}, False),
({'wait-after': '<% 1 %>'}, False),
({'wait-after': '<% * %>'}, True),
({'wait-after': -1}, True),
({'wait-after': 1.0}, True),
({'wait-after': '1'}, True),
({'timeout': 300}, False),
({'timeout': '<% 300 %>'}, False),
({'timeout': '<% * %>'}, True),
({'timeout': -300}, True),
({'timeout': 300.0}, True),
({'timeout': '300'}, True),
({'pause-before': False}, False),
({'pause-before': '<% False %>'}, False),
({'pause-before': '<% * %>'}, True),
({'pause-before': 'False'}, True),
({'concurrency': 10}, False),
({'concurrency': '<% 10 %>'}, False),
({'concurrency': '<% * %>'}, True),
({'concurrency': -10}, True),
({'concurrency': 10.0}, True),
({'concurrency': '10'}, True)
]
for default, expect_error in tests:

View File

@ -108,6 +108,20 @@ class BaseSpec(object):
return spec_cls(prop_val) if prop_val else None
def _group_spec(self, spec_cls, *prop_names):
if not prop_names:
return None
data = {}
for prop_name in prop_names:
prop_val = self._data.get(prop_name)
if prop_val:
data[prop_name] = prop_val
return spec_cls(data)
def _inject_version(self, prop_names):
for prop_name in prop_names:
prop_data = self._data.get(prop_name)

View File

@ -105,15 +105,11 @@ def get_workflow_list_spec(spec_dict):
def get_workflow_spec_from_yaml(text):
spec_dict = parse_yaml(text)
return get_workflow_spec(spec_dict)
return get_workflow_spec(parse_yaml(text))
def get_workflow_list_spec_from_yaml(text):
spec_dict = parse_yaml(text)
return get_workflow_list_spec(spec_dict)
return get_workflow_list_spec(parse_yaml(text))
def get_task_spec(spec_dict):

View File

@ -96,6 +96,21 @@ STRING_OR_YAQL_CONDITION = {
]
}
YAQL_OR_POSITIVE_INTEGER = {
"oneOf": [
YAQL,
POSITIVE_INTEGER
]
}
YAQL_OR_BOOLEAN = {
"oneOf": [
YAQL,
{"type": "boolean"}
]
}
UNIQUE_STRING_OR_YAQL_CONDITION_LIST = {
"type": "array",
"items": STRING_OR_YAQL_CONDITION,

View File

@ -18,65 +18,45 @@ from mistral.workbook.v2 import base
from mistral.workbook.v2 import retry_policy
class TaskPoliciesSpec(base.BaseSpec):
# See http://json-schema.org
_retry_policy_schema = retry_policy.RetrySpec.get_schema(
includes=None)
RETRY_SCHEMA = retry_policy.RetrySpec.get_schema(includes=None)
WAIT_BEFORE_SCHEMA = types.YAQL_OR_POSITIVE_INTEGER
WAIT_AFTER_SCHEMA = types.YAQL_OR_POSITIVE_INTEGER
TIMEOUT_SCHEMA = types.YAQL_OR_POSITIVE_INTEGER
PAUSE_BEFORE_SCHEMA = types.YAQL_OR_BOOLEAN
CONCURRENCY_SCHEMA = types.YAQL_OR_POSITIVE_INTEGER
class PoliciesSpec(base.BaseSpec):
# See http://json-schema.org
_schema = {
"type": "object",
"properties": {
"retry": _retry_policy_schema,
"wait-before": {
"oneOf": [
types.YAQL,
types.POSITIVE_INTEGER
]
},
"wait-after": {
"oneOf": [
types.YAQL,
types.POSITIVE_INTEGER
]
},
"timeout": {
"oneOf": [
types.YAQL,
types.POSITIVE_INTEGER
]
},
"pause-before": {
"oneOf": [
types.YAQL,
{"type": "boolean"}
]
},
"concurrency": {
"oneOf": [
types.YAQL,
types.POSITIVE_INTEGER
]
},
"retry": RETRY_SCHEMA,
"wait-before": WAIT_BEFORE_SCHEMA,
"wait-after": WAIT_AFTER_SCHEMA,
"timeout": TIMEOUT_SCHEMA,
"pause-before": PAUSE_BEFORE_SCHEMA,
"concurrency": CONCURRENCY_SCHEMA,
},
"additionalProperties": False
}
@classmethod
def get_schema(cls, includes=['definitions']):
return super(TaskPoliciesSpec, cls).get_schema(includes)
return super(PoliciesSpec, cls).get_schema(includes)
def __init__(self, data):
super(TaskPoliciesSpec, self).__init__(data)
super(PoliciesSpec, self).__init__(data)
self._retry = self._spec_property('retry', retry_policy.RetrySpec)
self._wait_before = data.get("wait-before", 0)
self._wait_after = data.get("wait-after", 0)
self._timeout = data.get("timeout", 0)
self._pause_before = data.get("pause-before", False)
self._concurrency = data.get("concurrency", 0)
self._wait_before = data.get('wait-before', 0)
self._wait_after = data.get('wait-after', 0)
self._timeout = data.get('timeout', 0)
self._pause_before = data.get('pause-before', False)
self._concurrency = data.get('concurrency', 0)
def validate(self):
super(TaskPoliciesSpec, self).validate()
super(PoliciesSpec, self).validate()
# Validate YAQL expressions.
self.validate_yaql_expr(self._data.get('wait-before', 0))

View File

@ -15,18 +15,23 @@
from mistral.workbook import types
from mistral.workbook.v2 import base
from mistral.workbook.v2 import task_policies
from mistral.workbook.v2 import policies
class TaskDefaultsSpec(base.BaseSpec):
# See http://json-schema.org
_task_policies_schema = task_policies.TaskPoliciesSpec.get_schema(
_task_policies_schema = policies.PoliciesSpec.get_schema(
includes=None)
_schema = {
"type": "object",
"properties": {
"policies": _task_policies_schema,
"retry": policies.RETRY_SCHEMA,
"wait-before": policies.WAIT_BEFORE_SCHEMA,
"wait-after": policies.WAIT_AFTER_SCHEMA,
"timeout": policies.TIMEOUT_SCHEMA,
"pause-before": policies.PAUSE_BEFORE_SCHEMA,
"concurrency": policies.CONCURRENCY_SCHEMA,
"on-complete": types.UNIQUE_STRING_OR_YAQL_CONDITION_LIST,
"on-success": types.UNIQUE_STRING_OR_YAQL_CONDITION_LIST,
"on-error": types.UNIQUE_STRING_OR_YAQL_CONDITION_LIST
@ -41,9 +46,14 @@ class TaskDefaultsSpec(base.BaseSpec):
def __init__(self, data):
super(TaskDefaultsSpec, self).__init__(data)
self._policies = self._spec_property(
'policies',
task_policies.TaskPoliciesSpec
self._policies = self._group_spec(
policies.PoliciesSpec,
'retry',
'wait-before',
'wait-after',
'timeout',
'pause-before',
'concurrency'
)
self._on_complete = self._as_list_of_tuples("on-complete")
self._on_success = self._as_list_of_tuples("on-success")

View File

@ -23,7 +23,7 @@ from mistral import expressions as expr
from mistral import utils
from mistral.workbook import types
from mistral.workbook.v2 import base
from mistral.workbook.v2 import task_policies
from mistral.workbook.v2 import policies
WITH_ITEMS_PTRN = re.compile(
@ -35,9 +35,6 @@ class TaskSpec(base.BaseSpec):
# See http://json-schema.org
_type = None
_task_policies_schema = task_policies.TaskPoliciesSpec.get_schema(
includes=None)
_schema = {
"type": "object",
"properties": {
@ -52,14 +49,14 @@ class TaskSpec(base.BaseSpec):
]
},
"publish": types.NONEMPTY_DICT,
"policies": _task_policies_schema,
"retry": policies.RETRY_SCHEMA,
"wait-before": policies.WAIT_BEFORE_SCHEMA,
"wait-after": policies.WAIT_AFTER_SCHEMA,
"timeout": policies.TIMEOUT_SCHEMA,
"pause-before": policies.PAUSE_BEFORE_SCHEMA,
"concurrency": policies.CONCURRENCY_SCHEMA,
"target": types.NONEMPTY_STRING,
"keep-result": {
"oneOf": [
types.YAQL,
{"type": "boolean"}
]
}
"keep-result": types.YAQL_OR_BOOLEAN
},
"additionalProperties": False
}
@ -74,9 +71,14 @@ class TaskSpec(base.BaseSpec):
self._input = data.get('input', {})
self._with_items = self._transform_with_items()
self._publish = data.get('publish', {})
self._policies = self._spec_property(
'policies',
task_policies.TaskPoliciesSpec
self._policies = self._group_spec(
policies.PoliciesSpec,
'retry',
'wait-before',
'wait-after',
'timeout',
'pause-before',
'concurrency'
)
self._target = data.get('target')
self._keep_result = data.get('keep-result', True)

View File

@ -1,30 +0,0 @@
# Copyright 2014 - Mirantis, Inc.
# Copyright 2015 - StackStorm, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from mistral.workbook.v2 import base
# TODO(rakhmerov): In progress.
class TriggerSpec(base.BaseSpec):
def __init__(self, data):
super(TriggerSpec, self).__init__(data)
# TODO(rakhmerov): Implement.
class TriggerSpecList(base.BaseSpecList):
item_class = TriggerSpec

View File

@ -15,7 +15,6 @@
from mistral.workbook.v2 import actions as act
from mistral.workbook.v2 import base
from mistral.workbook.v2 import triggers as tr
from mistral.workbook.v2 import workflows as wf
@ -26,8 +25,6 @@ class WorkbookSpec(base.BaseSpec):
_workflow_schema = wf.WorkflowSpec.get_schema(includes=None)
_trigger_schema = tr.TriggerSpec.get_schema(includes=None)
_schema = {
"type": "object",
"properties": {
@ -47,14 +44,6 @@ class WorkbookSpec(base.BaseSpec):
"version": {"enum": ["2.0", 2.0]},
"^(?!version)\w+$": _workflow_schema
}
},
"triggers": {
"type": "object",
"minProperties": 1,
"patternProperties": {
"version": {"enum": ["2.0", 2.0]},
"^(?!version)\w+$": _trigger_schema
}
}
},
"additionalProperties": False
@ -69,9 +58,7 @@ class WorkbookSpec(base.BaseSpec):
self._description = data.get('description')
self._tags = data.get('tags', [])
self._actions = self._spec_property('actions', act.ActionSpecList)
self._workflows = self._spec_property(
'workflows', wf.WorkflowSpecList)
self._triggers = self._spec_property('triggers', tr.TriggerSpecList)
self._workflows = self._spec_property('workflows', wf.WorkflowSpecList)
def get_name(self):
return self._name
@ -87,6 +74,3 @@ class WorkbookSpec(base.BaseSpec):
def get_workflows(self):
return self._workflows
def get_triggers(self):
return self._triggers