Beispiel #1
0
    def _get_target(self, input_dict):
        ctx_view = data_flow.ContextView(
            input_dict, self.ctx,
            data_flow.get_workflow_environment_dict(self.wf_ex),
            self.wf_ex.context, self.wf_ex.input)

        return expr.evaluate_recursively(self.task_spec.get_target(), ctx_view)
Beispiel #2
0
    def _find_next_tasks(self, task_ex, ctx=None):
        t_state = task_ex.state
        t_name = task_ex.name

        ctx_view = data_flow.ContextView(
            data_flow.get_current_task_dict(task_ex), ctx
            or data_flow.evaluate_task_outbound_context(task_ex),
            data_flow.get_workflow_environment_dict(self.wf_ex),
            self.wf_ex.context, self.wf_ex.input)

        # [(task_name, params, 'on-success'|'on-error'|'on-complete'), ...]
        result = []

        def process_clause(clause, event_name):
            task_tuples = self._find_next_tasks_for_clause(clause, ctx_view)

            for t in task_tuples:
                result.append((t[0], t[1], event_name))

        if t_state == states.SUCCESS:
            process_clause(self.wf_spec.get_on_success_clause(t_name),
                           'on-success')
        elif t_state == states.ERROR:
            process_clause(self.wf_spec.get_on_error_clause(t_name),
                           'on-error')

        if states.is_completed(t_state) and not states.is_cancelled(t_state):
            process_clause(self.wf_spec.get_on_complete_clause(t_name),
                           'on-complete')

        return result
Beispiel #3
0
    def _evaluate_expression(self, expression, ctx=None):
        ctx_view = data_flow.ContextView(
            data_flow.get_current_task_dict(self.task_ex),
            data_flow.get_workflow_environment_dict(self.wf_ex), ctx
            or self.ctx, self.wf_ex.context, self.wf_ex.input)

        return expr.evaluate_recursively(expression, ctx_view)
Beispiel #4
0
    def _find_next_tasks(self, task_ex, ctx):
        t_n = task_ex.name
        t_s = task_ex.state

        ctx_view = data_flow.ContextView(
            data_flow.get_current_task_dict(task_ex), ctx,
            data_flow.get_workflow_environment_dict(self.wf_ex),
            self.wf_ex.context, self.wf_ex.input)

        # [(task_name, params, 'on-success'|'on-error'|'on-complete'), ...]
        result = []

        if t_s == states.ERROR:
            for name, cond, params in self.wf_spec.get_on_error_clause(t_n):
                if not cond or expr.evaluate(cond, ctx_view):
                    params = expr.evaluate_recursively(params, ctx_view)
                    result.append((name, params, 'on-error'))

        if t_s == states.SUCCESS:
            for name, cond, params in self.wf_spec.get_on_success_clause(t_n):
                if not cond or expr.evaluate(cond, ctx_view):
                    params = expr.evaluate_recursively(params, ctx_view)
                    result.append((name, params, 'on-success'))

        if states.is_completed(t_s) and not states.is_cancelled(t_s):
            for name, cond, params in self.wf_spec.get_on_complete_clause(t_n):
                if not cond or expr.evaluate(cond, ctx_view):
                    params = expr.evaluate_recursively(params, ctx_view)
                    result.append((name, params, 'on-complete'))

        return result
Beispiel #5
0
    def _prepare_input(self, input_dict):
        if self._prepared_input is not None:
            return self._prepared_input

        base_input_dict = input_dict

        for action_def in self.adhoc_action_defs:
            action_spec = spec_parser.get_action_spec(action_def.spec)

            for k, v in action_spec.get_input().items():
                if (k not in base_input_dict
                        or base_input_dict[k] is utils.NotDefined):
                    base_input_dict[k] = v

            base_input_expr = action_spec.get_base_input()

            if base_input_expr:
                wf_ex = (self.task_ex.workflow_execution
                         if self.task_ex else None)

                ctx_view = data_flow.ContextView(
                    base_input_dict, self.task_ctx,
                    data_flow.get_workflow_environment_dict(wf_ex),
                    self.wf_ctx)

                base_input_dict = expr.evaluate_recursively(
                    base_input_expr, ctx_view)
            else:
                base_input_dict = {}

        self._prepared_input = super(AdHocAction,
                                     self)._prepare_input(base_input_dict)

        return self._prepared_input
Beispiel #6
0
    def _evaluate_expression(self, expression, ctx=None):
        ctx_view = data_flow.ContextView(
            data_flow.get_current_task_dict(self.task_ex),
            data_flow.get_workflow_environment_dict(self.wf_ex),
            ctx or self.ctx,
            self.wf_ex.context,
            self.wf_ex.input
        )

        return expr.evaluate_recursively(expression, ctx_view)
Beispiel #7
0
    def get_expression_context(self, ctx=None):
        assert self.task_ex

        return data_flow.ContextView(
            data_flow.get_current_task_dict(self.task_ex),
            data_flow.get_workflow_environment_dict(self.wf_ex),
            ctx or {},
            self.task_ex.in_context,
            self.wf_ex.context,
            self.wf_ex.input,
        )
Beispiel #8
0
    def schedule(self,
                 input_dict,
                 target,
                 index=0,
                 desc='',
                 safe_rerun=False,
                 timeout=None):
        assert not self.action_ex

        self.action_desc.check_parameters(input_dict)

        wf_ex = self.task_ex.workflow_execution if self.task_ex else None

        wf_ctx = data_flow.ContextView(
            self.task_ctx, data_flow.get_workflow_environment_dict(wf_ex),
            wf_ex.context if wf_ex else {})

        try:
            action = self.action_desc.instantiate(input_dict, wf_ctx)
        except Exception:
            raise exc.InvalidActionException(
                'Failed to instantiate an action'
                ' [action_desc=%s, input_dict=%s]' %
                (self.action_desc, input_dict))

        # Assign the action execution ID here to minimize database calls.
        # Otherwise, the input property of the action execution DB object needs
        # to be updated with the action execution ID after the action execution
        # DB object is created.
        action_ex_id = utils.generate_unicode_uuid()

        self._create_action_execution(input_dict,
                                      self._prepare_runtime_context(
                                          index, safe_rerun),
                                      desc=desc,
                                      action_ex_id=action_ex_id,
                                      is_sync=action.is_sync())

        def _run_action():
            executor = exe.get_executor(cfg.CONF.executor.type)

            return executor.run_action(
                action,
                self.action_ex.id if self.action_ex is not None else None,
                safe_rerun,
                self._prepare_execution_context(),
                target=target,
                timeout=timeout)

        # Register an asynchronous command to run the action
        # on an executor outside of the main DB transaction.
        post_tx_queue.register_operation(_run_action)
Beispiel #9
0
    def all_errors_handled(self):
        for t_ex in lookup_utils.find_error_task_executions(self.wf_ex.id):
            ctx_view = data_flow.ContextView(
                data_flow.evaluate_task_outbound_context(t_ex),
                data_flow.get_workflow_environment_dict(self.wf_ex),
                self.wf_ex.context, self.wf_ex.input)

            tasks_on_error = self._find_next_tasks_for_clause(
                self.wf_spec.get_on_error_clause(t_ex.name), ctx_view)

            if not tasks_on_error:
                return False

        return True
Beispiel #10
0
    def after_task_complete(self, task_ex, task_spec):
        """Called right after task completes.

        :param task_ex: Completed task DB model.
        :param task_spec: Completed task specification.
        """
        wf_ex = task_ex.workflow_execution

        ctx_view = data_flow.ContextView(
            task_ex.in_context, data_flow.get_workflow_environment_dict(wf_ex),
            wf_ex.context, wf_ex.input)

        data_flow.evaluate_object_fields(self, ctx_view)

        self._validate()
Beispiel #11
0
    def before_task_start(self, task_ex, task_spec):
        """Called right before task start.

        :param task_ex: DB model for task that is about to start.
        :param task_spec: Task specification.
        """
        wf_ex = task_ex.workflow_execution

        ctx_view = data_flow.ContextView(
            task_ex.in_context, data_flow.get_workflow_environment_dict(wf_ex),
            wf_ex.context, wf_ex.input)

        data_flow.evaluate_object_fields(self, ctx_view)

        self._validate()
Beispiel #12
0
    def _get_target(self, input_dict):
        if not self.task_spec.get_target():
            return None

        ctx_view = data_flow.ContextView(
            input_dict,
            self.ctx,
            data_flow.get_workflow_environment_dict(self.wf_ex),
            self.wf_ex.context,
            self.wf_ex.input
        )

        return expr.evaluate_recursively(
            self.task_spec.get_target(),
            ctx_view
        )
Beispiel #13
0
def get_published_global(task_ex, wf_ex=None):
    if task_ex.state not in [states.SUCCESS, states.ERROR]:
        return

    if wf_ex is None:
        wf_ex = task_ex.workflow_execution

    expr_ctx = ContextView(get_current_task_dict(task_ex), task_ex.in_context,
                           get_workflow_environment_dict(wf_ex), wf_ex.context,
                           wf_ex.input)

    task_spec = spec_parser.get_task_spec(task_ex.spec)
    publish_spec = task_spec.get_publish(task_ex.state)

    if not publish_spec:
        return
    global_vars = publish_spec.get_global()
    return expr.evaluate_recursively(global_vars, expr_ctx)
Beispiel #14
0
    def _prepare_input(self, input_dict):
        if self._prepared_input is not None:
            return self._prepared_input

        base_input_dict = input_dict

        for action_def in self.adhoc_action_defs:
            action_spec = spec_parser.get_action_spec(action_def.spec)

            for k, v in action_spec.get_input().items():
                if (k not in base_input_dict or
                        base_input_dict[k] is utils.NotDefined):
                    base_input_dict[k] = v

            base_input_expr = action_spec.get_base_input()

            if base_input_expr:
                wf_ex = (
                    self.task_ex.workflow_execution if self.task_ex else None
                )

                ctx_view = data_flow.ContextView(
                    base_input_dict,
                    self.task_ctx,
                    data_flow.get_workflow_environment_dict(wf_ex),
                    self.wf_ctx
                )

                base_input_dict = expr.evaluate_recursively(
                    base_input_expr,
                    ctx_view
                )
            else:
                base_input_dict = {}

        self._prepared_input = super(AdHocAction, self)._prepare_input(
            base_input_dict
        )

        return self._prepared_input
Beispiel #15
0
    def _find_next_tasks(self, task_ex, ctx=None):
        t_state = task_ex.state
        t_name = task_ex.name

        ctx_view = data_flow.ContextView(
            data_flow.get_current_task_dict(task_ex),
            ctx or data_flow.evaluate_task_outbound_context(task_ex),
            data_flow.get_workflow_environment_dict(self.wf_ex),
            self.wf_ex.context,
            self.wf_ex.input
        )

        # [(task_name, params, 'on-success'|'on-error'|'on-complete'), ...]
        result = []

        def process_clause(clause, event_name):
            task_tuples = self._find_next_tasks_for_clause(clause, ctx_view)

            for t in task_tuples:
                result.append((t[0], t[1], event_name))

        if t_state == states.SUCCESS:
            process_clause(
                self.wf_spec.get_on_success_clause(t_name),
                'on-success'
            )
        elif t_state == states.ERROR:
            process_clause(
                self.wf_spec.get_on_error_clause(t_name),
                'on-error'
            )

        if states.is_completed(t_state) and not states.is_cancelled(t_state):
            process_clause(
                self.wf_spec.get_on_complete_clause(t_name),
                'on-complete'
            )

        return result