Пример #1
0
    def start(self, wf_def, wf_ex_id, input_dict, desc='', params=None):
        """Start workflow.

        :param wf_def: Workflow definition.
        :param wf_ex_id: Workflow execution id.
        :param input_dict: Workflow input.
        :param desc: Workflow execution description.
        :param params: Workflow type specific parameters.

        :raises
        """

        assert not self.wf_ex

        # New workflow execution.
        self.wf_spec = spec_parser.get_workflow_spec_by_definition_id(
            wf_def.id, wf_def.updated_at)

        wf_trace.info(
            self.wf_ex, 'Starting workflow [name=%s, input=%s]' %
            (wf_def.name, utils.cut(input_dict)))

        self.validate_input(input_dict)

        self._create_execution(wf_def, wf_ex_id,
                               self.prepare_input(input_dict), desc, params)

        self.set_state(states.RUNNING)

        wf_ctrl = wf_base.get_controller(self.wf_ex, self.wf_spec)

        dispatcher.dispatch_workflow_commands(self.wf_ex,
                                              wf_ctrl.continue_workflow())
Пример #2
0
    def run_action(self, rpc_ctx, action_ex_id, action_cls_str,
                   action_cls_attrs, params, safe_rerun, execution_context,
                   timeout):
        """Receives calls over RPC to run action on executor.

        :param timeout: a period of time in seconds after which execution of
            action will be interrupted
        :param execution_context: A dict of values providing information about
            the current execution.
        :param rpc_ctx: RPC request context dictionary.
        :param action_ex_id: Action execution id.
        :param action_cls_str: Action class name.
        :param action_cls_attrs: Action class attributes.
        :param params: Action input parameters.
        :param safe_rerun: Tells if given action can be safely rerun.
        :return: Action result.
        """

        LOG.debug(
            "Received RPC request 'run_action'[action_ex_id=%s, "
            "action_cls_str=%s, action_cls_attrs=%s, params=%s, "
            "timeout=%s]",
            action_ex_id,
            action_cls_str,
            action_cls_attrs,
            utils.cut(params),
            timeout
        )

        redelivered = rpc_ctx.redelivered or False

        try:
            self._aer.add_action_ex_id(action_ex_id)

            res = self.executor.run_action(
                action_ex_id,
                action_cls_str,
                action_cls_attrs,
                params,
                safe_rerun,
                execution_context,
                redelivered,
                timeout=timeout
            )

            LOG.debug(
                "Sending action result to engine"
                " [action_ex_id=%s, action_cls=%s]",
                action_ex_id,
                action_cls_str
            )

            return res
        finally:
            self._aer.remove_action_ex_id(action_ex_id)
Пример #3
0
    def post(self, env):
        """Create a new environment.

        :param env: Required. Environment structure to create
        """
        acl.enforce('environments:create', context.ctx())

        LOG.debug("Create environment [env=%s]", cut(env))

        self._validate_environment(
            json.loads(wsme_pecan.pecan.request.body.decode()),
            ['name', 'description', 'variables'])

        db_model = rest_utils.rest_retry_on_db_error(
            db_api.create_environment)(env.to_dict())

        return resources.Environment.from_db_model(db_model)
Пример #4
0
    def notify(self, rpc_ctx, ex_id, data, event, timestamp, publishers):
        """Receives calls over RPC to notify on notification server.

        :param rpc_ctx: RPC request context dictionary.
        :param ex_id: Workflow, task, or action execution id.
        :param data: Dictionary to include in the notification message.
        :param event: Event being notified on.
        :param timestamp: Datetime when this event occurred.
        :param publishers: The list of publishers to send the notification.
        """

        LOG.info(
            "Received RPC request 'notify'[ex_id=%s, event=%s, "
            "timestamp=%s, data=%s, publishers=%s]", ex_id, event, timestamp,
            data, utils.cut(publishers))

        self.notifier.notify(ex_id, data, event, timestamp, publishers)
Пример #5
0
    def start_action(self, rpc_ctx, action_name, action_input, description,
                     params):
        """Receives calls over RPC to start actions on engine.

        :param rpc_ctx: RPC request context.
        :param action_name: name of the Action.
        :param action_input: input dictionary for Action.
        :param description: description of new Action execution.
        :param params: extra parameters to run Action.
        :return: Action execution.
        """
        LOG.info(
            "Received RPC request 'start_action'[name=%s, input=%s, "
            "description=%s, params=%s]", action_name, utils.cut(action_input),
            description, params)

        return self.engine.start_action(action_name, action_input, description,
                                        **params)
Пример #6
0
    def put(self, env):
        """Update an environment.

        :param env: Required. Environment structure to update
        """
        acl.enforce('environments:update', context.ctx())

        if not env.name:
            raise exceptions.InputException(
                'Name of the environment is not provided.')

        LOG.debug("Update environment [name=%s, env=%s]", env.name, cut(env))

        definition = json.loads(wsme_pecan.pecan.request.body.decode())
        definition.pop('name')

        self._validate_environment(definition,
                                   ['description', 'variables', 'scope'])

        db_model = rest_utils.rest_retry_on_db_error(
            db_api.update_environment)(env.name, env.to_dict())

        return resources.Environment.from_db_model(db_model)
Пример #7
0
    def start_workflow(self, rpc_ctx, wf_identifier, wf_namespace, wf_ex_id,
                       wf_input, description, params):
        """Receives calls over RPC to start workflows on engine.

        :param rpc_ctx: RPC request context.
        :param wf_identifier: Workflow definition identifier.
        :param wf_namespace: Workflow namespace.
        :param wf_input: Workflow input.
        :param wf_ex_id: Workflow execution id. If passed, it will be set
            in the new execution object.
        :param description: Workflow execution description.
        :param params: Additional workflow type specific parameters.
        :return: Workflow execution.
        """

        LOG.info(
            "Received RPC request 'start_workflow'[workflow_identifier=%s, "
            "workflow_input=%s, description=%s, params=%s]", wf_identifier,
            utils.cut(wf_input), description, params)

        return self.engine.start_workflow(wf_identifier, wf_namespace,
                                          wf_ex_id, wf_input, description,
                                          **params)
Пример #8
0
 def cut_repr(self):
     return 'Result [data=%s, error=%s, cancel=%s]' % (
         utils.cut(self.data), utils.cut(self.error), str(self.cancel)
     )
Пример #9
0
        return d


for cls in utils.iter_subclasses(Execution):
    event.listen(
        # Catch and trim Execution.state_info to always fit allocated size.
        # Note that the limit is 65500 which is less than 65535 (2^16 -1).
        # The reason is that utils.cut() is not exactly accurate in case if
        # the value is not a string, but, for example, a dictionary. If we
        # limit it exactly to 65535 then once in a while it may go slightly
        # beyond the allowed maximum size. It may depend on the order of
        # keys in a string representation and other things that are hidden
        # inside utils.cut_dict() method.
        cls.state_info,
        'set',
        lambda t, v, o, i: utils.cut(v, 65500),
        retval=True)

# Many-to-one for 'ActionExecution' and 'TaskExecution'.

ActionExecution.task_execution_id = sa.Column(sa.String(36),
                                              sa.ForeignKey(
                                                  TaskExecution.id,
                                                  ondelete='CASCADE'),
                                              nullable=True)

TaskExecution.action_executions = relationship(
    ActionExecution,
    backref=backref('task_execution', remote_side=[TaskExecution.id]),
    cascade='all, delete-orphan',
    foreign_keys=ActionExecution.task_execution_id,
Пример #10
0
        def _result_msg():
            if state == states.ERROR:
                return "error = %s" % utils.cut(result.error)

            return "result = %s" % utils.cut(result.data)
Пример #11
0
 def test_cut_dict_for_state_info(self):
     d = {}
     for i in range(2000):
         d[i] = {'value': 'This is a string that exceeds 35 characters'}
     s = utils.cut(d, 65500)
     self.assertThat(len(s), ttm.Not(ttm.GreaterThan(65500)))
Пример #12
0
 def test_cut_dict_with_large_dict_of_dict(self):
     d = {}
     for i in range(65535):
         d[i] = {'value': str(i)}
     s = utils.cut(d, 65535)
     self.assertThat(len(s), ttm.Not(ttm.GreaterThan(65535)))
Пример #13
0
 def test_cut_dict_with_large_dict_of_str(self):
     d = {}
     for i in range(65535):
         d[str(i)] = str(i)
     s = utils.cut(d, 65535)
     self.assertThat(len(s), ttm.Not(ttm.GreaterThan(65535)))
Пример #14
0
 def test_cut_list_with_large_dict_of_int(self):
     d = [i for i in range(65535)]
     s = utils.cut(d, 65535)
     self.assertThat(len(s), ttm.Not(ttm.GreaterThan(65535)))
Пример #15
0
 def cut_repr(self):
     return 'Result [data=%s, error=%s, cancel=%s]' % (utils.cut(
         self.data), utils.cut(self.error), str(self.cancel))
Пример #16
0
 def cut_repr(self):
     _data = utils.mask_data(self.data)
     _error = utils.mask_data(self.error)
     _cancel = utils.mask_data(self.cancel)
     return 'Result [data=%s, error=%s, cancel=%s]' % (
         utils.cut(_data), utils.cut(_error), str(_cancel))