def test_update_actions(self): db_actions = action_service.create_actions(ACTION_LIST) self.assertEqual(2, len(db_actions)) action1_db = self._assert_single_item(db_actions, name='action1') action1_spec = spec_parser.get_action_spec(action1_db.spec) self.assertEqual('action1', action1_spec.get_name()) self.assertEqual('std.echo', action1_spec.get_base()) self.assertDictEqual({'output': 'Hi'}, action1_spec.get_base_input()) self.assertDictEqual({}, action1_spec.get_input()) db_actions = action_service.update_actions(UPDATED_ACTION_LIST) # Action 1. action1_db = self._assert_single_item(db_actions, name='action1') action1_spec = spec_parser.get_action_spec(action1_db.spec) self.assertEqual('action1', action1_spec.get_name()) self.assertListEqual([], action1_spec.get_tags()) self.assertEqual('std.echo', action1_spec.get_base()) self.assertDictEqual({'output': 'Hi'}, action1_spec.get_base_input()) self.assertIn('param1', action1_spec.get_input()) self.assertIs(action1_spec.get_input().get('param1'), utils.NotDefined)
def test_update_actions(self): db_actions = action_service.create_actions(ACTION_LIST) self.assertEqual(2, len(db_actions)) action1_db = self._assert_single_item(db_actions, name='action1') action1_spec = spec_parser.get_action_spec(action1_db.spec) self.assertEqual('action1', action1_spec.get_name()) self.assertEqual('std.echo', action1_spec.get_base()) self.assertDictEqual({'output': 'Hi'}, action1_spec.get_base_input()) self.assertDictEqual({}, action1_spec.get_input()) db_actions = action_service.update_actions(UPDATED_ACTION_LIST) # Action 1. action1_db = self._assert_single_item(db_actions, name='action1') action1_spec = spec_parser.get_action_spec(action1_db.spec) self.assertEqual('action1', action1_spec.get_name()) self.assertListEqual([], action1_spec.get_tags()) self.assertEqual('std.echo', action1_spec.get_base()) self.assertDictEqual({'output': 'Hi'}, action1_spec.get_base_input()) self.assertIn('param1', action1_spec.get_input()) self.assertIs( action1_spec.get_input().get('param1'), utils.NotDefined )
def _get_adhoc_action_input(action_def, input_dict, wf_name=None, wf_spec=None): action_spec = spec_parser.get_action_spec(action_def.spec) base_name = action_spec.get_base() action_def = resolve_action_definition( base_name, wf_name if wf_name else None, wf_spec.get_name() if wf_spec else None ) _inject_action_ctx_for_validating(action_def, input_dict) e_utils.validate_input(action_def, input_dict, action_spec) base_input = action_spec.get_base_input() if base_input: input_dict = expr.evaluate_recursively( base_input, input_dict ) else: input_dict = {} return input_dict
def _get_action_input(wf_spec, task_ex, task_spec, ctx): input_dict = expr.evaluate_recursively(task_spec.get_input(), ctx) action_spec_name = task_spec.get_action_name() action_def = e_utils.resolve_action_definition(task_ex.workflow_name, wf_spec.get_name(), action_spec_name) input_dict = utils.merge_dicts(input_dict, _get_action_defaults(task_ex, task_spec), overwrite=False) if action_def.spec: # Ad-hoc action. action_spec = spec_parser.get_action_spec(action_def.spec) base_name = action_spec.get_base() action_def = e_utils.resolve_action_definition(task_ex.workflow_name, wf_spec.get_name(), base_name) e_utils.validate_input(action_def, action_spec, input_dict) base_input = action_spec.get_base_input() if base_input: input_dict = expr.evaluate_recursively(base_input, input_dict) else: input_dict = {} return input_dict
def _schedule_run_action(task_ex, task_spec, action_input, index): wf_ex = task_ex.workflow_execution wf_spec = spec_parser.get_workflow_spec(wf_ex.spec) action_spec_name = task_spec.get_action_name() # TODO(rakhmerov): Refactor ad-hoc actions and isolate them. action_def = e_utils.resolve_action_definition(wf_ex.workflow_name, wf_spec.get_name(), action_spec_name) if action_def.spec: # Ad-hoc action. action_spec = spec_parser.get_action_spec(action_def.spec) base_name = action_spec.get_base() action_def = e_utils.resolve_action_definition(task_ex.workflow_name, wf_spec.get_name(), base_name) action_ex = _create_action_execution(task_ex, action_def, action_input, index) target = expr.evaluate_recursively( task_spec.get_target(), utils.merge_dicts(copy.deepcopy(action_input), copy.copy(task_ex.in_context))) scheduler.schedule_call(None, 'mistral.engine.task_handler.run_action', 0, action_ex_id=action_ex.id, target=target)
def transform_result(result, task_ex=None, action_ex=None): """Transforms task result accounting for ad-hoc actions. In case if the given result is an action result and action is an ad-hoc action the method transforms the result according to ad-hoc action configuration. :param task_ex: Task DB model. :param result: Result of task action/workflow. """ if result.is_error(): return result action_spec_name = None if task_ex: action_spec_name = spec_parser.get_task_spec(task_ex.spec).get_action_name() elif action_ex: if action_ex.spec: action_spec_name = spec_parser.get_action_spec(action_ex.spec) else: action_spec_name = action_ex.name if action_spec_name: wf_ex = task_ex.workflow_execution if task_ex else None wf_spec_name = spec_parser.get_workflow_spec(wf_ex.spec).get_name() if task_ex else None return transform_action_result( action_spec_name, result, wf_ex.workflow_name if wf_ex else None, wf_spec_name if wf_ex else None ) return result
def resolve_definition(action_name, task_ex=None, wf_spec=None): if task_ex and wf_spec: wf_ex = task_ex.workflow_execution action_def = resolve_action_definition( action_name, wf_ex.workflow_name, wf_spec.get_name() ) else: action_def = resolve_action_definition(action_name) if action_def.spec: # Ad-hoc action. action_spec = spec_parser.get_action_spec(action_def.spec) base_name = action_spec.get_base() action_def = resolve_action_definition( base_name, task_ex.workflow_name if task_ex else None, wf_spec.get_name() if wf_spec else None ) return action_def
def __init__(self, action_def, action_ex=None, task_ex=None): self.action_spec = spec_parser.get_action_spec(action_def.spec) base_action_def = db_api.get_action_definition( self.action_spec.get_base()) super(AdHocAction, self).__init__(base_action_def, action_ex, task_ex) self.adhoc_action_def = action_def
def test_create_actions(self): db_actions = action_service.create_actions(ACTION_LIST) self.assertEqual(2, len(db_actions)) # Action 1. action1_db = self._assert_single_item(db_actions, name='action1') action1_spec = spec_parser.get_action_spec(action1_db.spec) self.assertEqual('action1', action1_spec.get_name()) self.assertListEqual(['test', 'v2'], action1_spec.get_tags()) self.assertEqual('std.echo', action1_spec.get_base()) self.assertDictEqual({'output': 'Hi'}, action1_spec.get_base_input()) # Action 2. action2_db = self._assert_single_item(db_actions, name='action2') action2_spec = spec_parser.get_action_spec(action2_db.spec) self.assertEqual('action2', action2_spec.get_name()) self.assertEqual('std.echo', action1_spec.get_base()) self.assertDictEqual({'output': 'Hey'}, action2_spec.get_base_input())
def transform_action_result(action_spec_name, result, wf_name=None, wf_spec_name=None): action_def = resolve_action_definition(action_spec_name, wf_name, wf_spec_name) if not action_def.spec: return result transformer = spec_parser.get_action_spec(action_def.spec).get_output() if transformer is None: return result return wf_utils.Result(data=expr.evaluate_recursively(transformer, result.data), error=result.error)
def _prepare_input(self, input_dict): base_input_dict = input_dict for action_def in self.adhoc_action_defs: action_spec = spec_parser.get_action_spec(action_def.spec) base_input_expr = action_spec.get_base_input() if base_input_expr: base_input_dict = expr.evaluate_recursively( base_input_expr, base_input_dict) else: base_input_dict = {} return super(AdHocAction, self)._prepare_input(base_input_dict)
def __init__(self, action_def, action_ex=None, task_ex=None): self.action_spec = spec_parser.get_action_spec(action_def.spec) base_action_def = db_api.get_action_definition( self.action_spec.get_base() ) super(AdHocAction, self).__init__( base_action_def, action_ex, task_ex ) self.adhoc_action_def = action_def
def _prepare_output(self, result): # In case of error, we don't transform a result. if not result.is_error(): adhoc_action_spec = spec_parser.get_action_spec( self.adhoc_action_def.spec) transformer = adhoc_action_spec.get_output() if transformer is not None: result = wf_utils.Result(data=expr.evaluate_recursively( transformer, result.data), error=result.error) return _get_action_output(result) if result else None
def _prepare_input(self, input_dict): base_input_dict = input_dict for action_def in self.adhoc_action_defs: action_spec = spec_parser.get_action_spec(action_def.spec) base_input_expr = action_spec.get_base_input() if base_input_expr: base_input_dict = expr.evaluate_recursively( base_input_expr, base_input_dict ) else: base_input_dict = {} return super(AdHocAction, self)._prepare_input(base_input_dict)
def transform_action_result(wf_name, wf_spec_name, action_spec_name, result): action_def = resolve_action_definition(wf_name, wf_spec_name, action_spec_name) if not action_def.spec: return result transformer = spec_parser.get_action_spec(action_def.spec).get_output() if transformer is None: return result return wf_utils.Result(data=expr.evaluate_recursively( transformer, result.data), error=result.error)
def _prepare_output(self, result): # In case of error, we don't transform a result. if not result.is_error(): adhoc_action_spec = spec_parser.get_action_spec( self.adhoc_action_def.spec ) transformer = adhoc_action_spec.get_output() if transformer is not None: result = wf_utils.Result( data=expr.evaluate_recursively(transformer, result.data), error=result.error ) return _get_action_output(result) if result else None
def test_create_workbook(self): wb_db = wb_service.create_workbook_v2(WORKBOOK) self.assertIsNotNone(wb_db) self.assertEqual('my_wb', wb_db.name) self.assertEqual(WORKBOOK, wb_db.definition) self.assertIsNotNone(wb_db.spec) self.assertListEqual(['test'], wb_db.tags) db_actions = db_api.get_action_definitions(name='my_wb.concat') self.assertEqual(1, len(db_actions)) # Action. action_db = self._assert_single_item(db_actions, name='my_wb.concat') self.assertFalse(action_db.is_system) action_spec = spec_parser.get_action_spec(action_db.spec) self.assertEqual('concat', action_spec.get_name()) self.assertEqual('std.echo', action_spec.get_base()) self.assertEqual(ACTION_DEFINITION, action_db.definition) db_wfs = db_api.get_workflow_definitions() self.assertEqual(2, len(db_wfs)) # Workflow 1. wf1_db = self._assert_single_item(db_wfs, name='my_wb.wf1') wf1_spec = spec_parser.get_workflow_spec(wf1_db.spec) self.assertEqual('wf1', wf1_spec.get_name()) self.assertEqual('reverse', wf1_spec.get_type()) self.assertListEqual(['wf_test'], wf1_spec.get_tags()) self.assertListEqual(['wf_test'], wf1_db.tags) self.assertEqual(WORKBOOK_WF1_DEFINITION, wf1_db.definition) # Workflow 2. wf2_db = self._assert_single_item(db_wfs, name='my_wb.wf2') wf2_spec = spec_parser.get_workflow_spec(wf2_db.spec) self.assertEqual('wf2', wf2_spec.get_name()) self.assertEqual('direct', wf2_spec.get_type()) self.assertEqual(WORKBOOK_WF2_DEFINITION, wf2_db.definition)
def _schedule_run_action(task_ex, task_spec, action_input, index): wf_ex = task_ex.workflow_execution wf_spec = spec_parser.get_workflow_spec(wf_ex.spec) action_spec_name = task_spec.get_action_name() # TODO(rakhmerov): Refactor ad-hoc actions and isolate them. action_def = e_utils.resolve_action_definition( wf_ex.workflow_name, wf_spec.get_name(), action_spec_name ) if action_def.spec: # Ad-hoc action. action_spec = spec_parser.get_action_spec(action_def.spec) base_name = action_spec.get_base() action_def = e_utils.resolve_action_definition( task_ex.workflow_name, wf_spec.get_name(), base_name ) action_ex = _create_action_execution( task_ex, action_def, action_input, index ) target = expr.evaluate_recursively( task_spec.get_target(), utils.merge_dicts( copy.deepcopy(action_input), copy.copy(task_ex.in_context) ) ) scheduler.schedule_call( None, 'mistral.engine.task_handler.run_action', 0, action_ex_id=action_ex.id, target=target )
def _get_action_input(wf_spec, task_ex, task_spec, ctx): input_dict = expr.evaluate_recursively(task_spec.get_input(), ctx) action_spec_name = task_spec.get_action_name() action_def = e_utils.resolve_action_definition( task_ex.workflow_name, wf_spec.get_name(), action_spec_name ) input_dict = utils.merge_dicts( input_dict, _get_action_defaults(task_ex, task_spec), overwrite=False ) if action_def.spec: # Ad-hoc action. action_spec = spec_parser.get_action_spec(action_def.spec) base_name = action_spec.get_base() action_def = e_utils.resolve_action_definition( task_ex.workflow_name, wf_spec.get_name(), base_name ) e_utils.validate_input(action_def, action_spec, input_dict) base_input = action_spec.get_base_input() if base_input: input_dict = expr.evaluate_recursively( base_input, input_dict ) else: input_dict = {} return input_dict
def transform_result(result, task_ex=None, action_ex=None): """Transforms task result accounting for ad-hoc actions. In case if the given result is an action result and action is an ad-hoc action the method transforms the result according to ad-hoc action configuration. :param task_ex: Task DB model. :param result: Result of task action/workflow. """ if result.is_error(): return result action_spec_name = None if task_ex: action_spec_name = spec_parser.get_task_spec( task_ex.spec).get_action_name() elif action_ex: if action_ex.spec: action_spec_name = spec_parser.get_action_spec(action_ex.spec) else: action_spec_name = action_ex.name if action_spec_name: wf_ex = task_ex.workflow_execution if task_ex else None wf_spec_name = (spec_parser.get_workflow_spec( wf_ex.spec).get_name() if task_ex else None) return transform_action_result( action_spec_name, result, wf_ex.workflow_name if wf_ex else None, wf_spec_name if wf_ex else None, ) return result