From 2b9dfcdb10a6f02e397c4f88a84c012fcddf2a87 Mon Sep 17 00:00:00 2001 From: Lingxian Kong Date: Mon, 28 Dec 2015 17:33:02 +0800 Subject: [PATCH] Support workflow UUID when creating cron trigger Add 'workflow_id' parameter for cron trigger creation, if 'workflow_id' is specified, 'workflow_name' param will be ignored. Partially implements: blueprint use-workflow-id-in-rest-api Change-Id: I0c6020cf27f88646fa82611b9be0a2c125221a2b --- mistral/api/controllers/v2/cron_trigger.py | 7 +++++-- mistral/db/v2/sqlalchemy/api.py | 16 +++++++++------- mistral/services/triggers.py | 8 +++++--- mistral/tests/unit/api/v2/test_cron_triggers.py | 11 ++--------- .../tests/unit/services/test_trigger_service.py | 15 +++++++++++++++ 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/mistral/api/controllers/v2/cron_trigger.py b/mistral/api/controllers/v2/cron_trigger.py index cb22e8a4..5b866891 100644 --- a/mistral/api/controllers/v2/cron_trigger.py +++ b/mistral/api/controllers/v2/cron_trigger.py @@ -33,6 +33,7 @@ class CronTrigger(resource.Resource): id = wtypes.text name = wtypes.text workflow_name = wtypes.text + workflow_id = wtypes.text workflow_input = types.jsontype workflow_params = types.jsontype @@ -51,6 +52,7 @@ class CronTrigger(resource.Resource): return cls(id='123e4567-e89b-12d3-a456-426655440000', name='my_trigger', workflow_name='my_wf', + workflow_id='123e4567-e89b-12d3-a456-426655441111', workflow_input={}, workflow_params={}, scope='private', @@ -93,12 +95,13 @@ class CronTriggersController(rest.RestController): db_model = triggers.create_cron_trigger( values['name'], - values['workflow_name'], + values.get('workflow_name'), values.get('workflow_input'), values.get('workflow_params'), values.get('pattern'), values.get('first_execution_time'), - values.get('remaining_executions') + values.get('remaining_executions'), + workflow_id=values.get('workflow_id') ) return CronTrigger.from_dict(db_model.to_dict()) diff --git a/mistral/db/v2/sqlalchemy/api.py b/mistral/db/v2/sqlalchemy/api.py index 54cdc342..d22a4057 100644 --- a/mistral/db/v2/sqlalchemy/api.py +++ b/mistral/db/v2/sqlalchemy/api.py @@ -373,11 +373,7 @@ def delete_workflow_definition(identifier, session=None): msg = "Attempt to delete a system workflow: %s" % identifier raise exc.DataAccessException(msg) - # TODO(lane): We use workflow name here instead of supporting UUID, as - # cron-trigger is created using workflow name currently. Of course, - # cron-trigger creation still needs to be fixed in terms of non-unique - # workflow name in the system. - cron_triggers = _get_associated_cron_triggers(wf_def.name) + cron_triggers = _get_associated_cron_triggers(identifier) if cron_triggers: raise exc.DBException( @@ -389,11 +385,17 @@ def delete_workflow_definition(identifier, session=None): session.delete(wf_def) -def _get_associated_cron_triggers(wf_name): +def _get_associated_cron_triggers(wf_identifier): + criterion = ( + {'workflow_id': wf_identifier} + if uuidutils.is_uuid_like(wf_identifier) + else {'workflow_name': wf_identifier} + ) + cron_triggers = b.model_query( models.CronTrigger, [models.CronTrigger.name] - ).filter_by(workflow_name=wf_name).all() + ).filter_by(**criterion).all() return [t[0] for t in cron_triggers] diff --git a/mistral/services/triggers.py b/mistral/services/triggers.py index f96c3a41..8f2ee017 100644 --- a/mistral/services/triggers.py +++ b/mistral/services/triggers.py @@ -60,7 +60,7 @@ def validate_cron_trigger_input(pattern, first_time, count): def create_cron_trigger(name, workflow_name, workflow_input, workflow_params=None, pattern=None, first_time=None, - count=None, start_time=None): + count=None, start_time=None, workflow_id=None): if not start_time: start_time = datetime.datetime.now() @@ -84,7 +84,9 @@ def create_cron_trigger(name, workflow_name, workflow_input, next_time = get_next_execution_time(pattern, start_time) with db_api.transaction(): - wf_def = db_api.get_workflow_definition(workflow_name) + wf_def = db_api.get_workflow_definition( + workflow_id if workflow_id else workflow_name + ) eng_utils.validate_input( wf_def, @@ -98,7 +100,7 @@ def create_cron_trigger(name, workflow_name, workflow_input, 'first_execution_time': first_time, 'next_execution_time': next_time, 'remaining_executions': count, - 'workflow_name': workflow_name, + 'workflow_name': wf_def.name, 'workflow_id': wf_def.id, 'workflow_input': workflow_input or {}, 'workflow_params': workflow_params or {}, diff --git a/mistral/tests/unit/api/v2/test_cron_triggers.py b/mistral/tests/unit/api/v2/test_cron_triggers.py index 51c54fd6..4cf3cd86 100644 --- a/mistral/tests/unit/api/v2/test_cron_triggers.py +++ b/mistral/tests/unit/api/v2/test_cron_triggers.py @@ -34,13 +34,14 @@ WF = models.WorkflowDefinition( } } ) -WF.update({'id': '1-2-3-4', 'name': 'my_wf'}) +WF.update({'id': '123e4567-e89b-12d3-a456-426655440000', 'name': 'my_wf'}) TRIGGER = { 'id': '123', 'name': 'my_cron_trigger', 'pattern': '* * * * *', 'workflow_name': WF.name, + 'workflow_id': '123e4567-e89b-12d3-a456-426655440000', 'workflow_input': '{}', 'workflow_params': '{}', 'scope': 'private', @@ -57,17 +58,9 @@ trigger_values['workflow_params'] = json.loads( TRIGGER_DB = models.CronTrigger() TRIGGER_DB.update(trigger_values) - -UPDATED_TRIGGER_DB = copy.copy(TRIGGER_DB) -UPDATED_TRIGGER_DB['pattern'] = '*/1 * * * *' - -UPDATED_TRIGGER = copy.deepcopy(TRIGGER) -UPDATED_TRIGGER['pattern'] = '*/1 * * * *' - MOCK_WF = mock.MagicMock(return_value=WF) MOCK_TRIGGER = mock.MagicMock(return_value=TRIGGER_DB) MOCK_TRIGGERS = mock.MagicMock(return_value=[TRIGGER_DB]) -MOCK_UPDATED_TRIGGER = mock.MagicMock(return_value=UPDATED_TRIGGER_DB) MOCK_DELETE = mock.MagicMock(return_value=None) MOCK_EMPTY = mock.MagicMock(return_value=[]) MOCK_NOT_FOUND = mock.MagicMock(side_effect=exc.NotFoundException()) diff --git a/mistral/tests/unit/services/test_trigger_service.py b/mistral/tests/unit/services/test_trigger_service.py index 46ea6747..f0313b02 100644 --- a/mistral/tests/unit/services/test_trigger_service.py +++ b/mistral/tests/unit/services/test_trigger_service.py @@ -90,6 +90,21 @@ class TriggerServiceV2Test(base.DbTestCase): self.assertEqual(datetime.datetime(2010, 8, 25, 0, 10), next_time) + def test_trigger_create_with_wf_id(self): + trigger = t_s.create_cron_trigger( + 'test', + None, + {}, + {}, + '*/5 * * * *', + None, + None, + datetime.datetime(2010, 8, 25), + workflow_id=self.wf.id + ) + + self.assertEqual(self.wf.name, trigger.workflow_name) + def test_trigger_create_the_same_first_time_or_count(self): t_s.create_cron_trigger( 'test',