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)
예제 #2
0
    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
        )
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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)
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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
예제 #9
0
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
예제 #10
0
    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
예제 #11
0
    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())
예제 #12
0
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 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())
예제 #14
0
    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)
예제 #15
0
    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
예제 #16
0
    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
예제 #17
0
    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)
예제 #18
0
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)
예제 #19
0
    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 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)
예제 #22
0
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
    )
예제 #23
0
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
예제 #24
0
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