Пример #1
0
    def process_cron_triggers_v2(self, ctx):
        for t in triggers.get_next_cron_triggers():
            LOG.debug("Processing cron trigger: %s" % t)
            # Setup admin context before schedule triggers.
            ctx = security.create_context(t.trust_id, t.project_id)
            auth_ctx.set_ctx(ctx)

            LOG.debug("Cron trigger security context: %s" % ctx)

            try:
                rpc.get_engine_client().start_workflow(
                    t.workflow.name,
                    t.workflow_input,
                    description="workflow execution by cron trigger.",
                    **t.workflow_params
                )
            finally:
                if t.remaining_executions > 0:
                    t.remaining_executions -= 1
                if t.remaining_executions == 0:
                    db_api_v2.delete_cron_trigger(t.name)
                else:  # if remaining execution = None or > 0
                    next_time = triggers.get_next_execution_time(
                        t.pattern,
                        t.next_execution_time
                    )

                    db_api_v2.update_cron_trigger(
                        t.name,
                        {'next_execution_time': next_time,
                         'remaining_executions': t.remaining_executions}
                    )

                    auth_ctx.set_ctx(None)
Пример #2
0
    def process_cron_triggers_v2(self, ctx):
        for t in triggers.get_next_cron_triggers():
            LOG.debug("Processing cron trigger: %s" % t)

            # Setup admin context before schedule triggers.
            ctx = security.create_context(t.trust_id, t.project_id)

            auth_ctx.set_ctx(ctx)

            LOG.debug("Cron trigger security context: %s" % ctx)

            try:
                # Try to advance the cron trigger next_execution_time and
                # remaining_executions if relevant.
                modified = advance_cron_trigger(t)

                # If cron trigger was not already modified by another engine.
                if modified:
                    LOG.debug(
                        "Starting workflow '%s' by cron trigger '%s'",
                        t.workflow.name, t.name
                    )

                    rpc.get_engine_client().start_workflow(
                        t.workflow.name,
                        t.workflow_input,
                        description="Workflow execution created "
                                    "by cron trigger.",
                        **t.workflow_params
                    )
            except Exception:
                # Log and continue to next cron trigger.
                LOG.exception("Failed to process cron trigger %s" % str(t))
            finally:
                auth_ctx.set_ctx(None)
Пример #3
0
def run_workflow(wf_name, wf_input, wf_params):
    rpc.get_engine_client().start_workflow(
        wf_name,
        wf_input,
        "sub-workflow execution",
        **wf_params
    )
Пример #4
0
    def process_cron_triggers_v2(self, ctx):
        for t in triggers.get_next_cron_triggers():
            LOG.debug("Processing cron trigger: %s" % t)

            # Setup admin context before schedule triggers.
            ctx = security.create_context(t.trust_id, t.project_id)

            auth_ctx.set_ctx(ctx)

            LOG.debug("Cron trigger security context: %s" % ctx)

            try:
                # Try to advance the cron trigger next_execution_time and
                # remaining_executions if relevant.
                modified = advance_cron_trigger(t)

                # If cron trigger was not already modified by another engine.
                if modified:
                    LOG.debug(
                        "Starting workflow '%s' by cron trigger '%s'",
                        t.workflow.name, t.name
                    )

                    rpc.get_engine_client().start_workflow(
                        t.workflow.name,
                        t.workflow_input,
                        description="Workflow execution created "
                                    "by cron trigger.",
                        **t.workflow_params
                    )
            except Exception:
                # Log and continue to next cron trigger.
                LOG.exception("Failed to process cron trigger %s" % str(t))
            finally:
                auth_ctx.set_ctx(None)
Пример #5
0
    def process_cron_triggers_v2(self, ctx):
        for t in triggers.get_next_cron_triggers():
            LOG.debug("Processing cron trigger: %s" % t)

            # Setup admin context before schedule triggers.
            ctx = security.create_context(t.trust_id, t.project_id)

            auth_ctx.set_ctx(ctx)

            LOG.debug("Cron trigger security context: %s" % ctx)

            try:
                rpc.get_engine_client().start_workflow(
                    t.workflow.name,
                    t.workflow_input,
                    description="Workflow execution created by cron trigger.",
                    **t.workflow_params
                )
            finally:
                if t.remaining_executions is not None and t.remaining_executions > 0:
                    t.remaining_executions -= 1
                if t.remaining_executions == 0:
                    db_api_v2.delete_cron_trigger(t.name)
                else:  # if remaining execution = None or > 0
                    next_time = triggers.get_next_execution_time(t.pattern, t.next_execution_time)

                    db_api_v2.update_cron_trigger(
                        t.name, {"next_execution_time": next_time, "remaining_executions": t.remaining_executions}
                    )

                    auth_ctx.set_ctx(None)
Пример #6
0
def send_result_to_parent_workflow(wf_ex_id):
    wf_ex = db_api.get_workflow_execution(wf_ex_id)

    if wf_ex.state == states.SUCCESS:
        rpc.get_engine_client().on_action_complete(
            wf_ex.id, wf_utils.Result(data=wf_ex.output))
    elif wf_ex.state == states.ERROR:
        err_msg = 'Failed subworkflow [execution_id=%s]' % wf_ex.id

        rpc.get_engine_client().on_action_complete(
            wf_ex.id, wf_utils.Result(error=err_msg))
Пример #7
0
def fail_task_if_incomplete(task_ex_id, timeout):
    task_ex = db_api.get_task_execution(task_ex_id)

    if not states.is_completed(task_ex.state):
        msg = "Task timed out [id=%s, timeout(s)=%s]." % (task_ex_id, timeout)

        wf_trace.info(task_ex, msg)

        wf_trace.info(task_ex, "Task '%s' [%s -> ERROR]" % (task_ex.name, task_ex.state))

        rpc.get_engine_client().on_task_state_change(task_ex_id, states.ERROR)
Пример #8
0
def fail_task_if_incomplete(task_ex_id, timeout):
    task_ex = db_api.get_task_execution(task_ex_id)

    if not states.is_completed(task_ex.state):
        msg = "Task timed out [id=%s, timeout(s)=%s]." % (task_ex_id, timeout)

        wf_trace.info(task_ex, msg)

        wf_trace.info(
            task_ex, "Task '%s' [%s -> ERROR]" % (task_ex.name, task_ex.state))

        rpc.get_engine_client().on_task_state_change(task_ex_id, states.ERROR)
Пример #9
0
    def put(self, id, task):
        """Update the specified task execution.

        :param id: Task execution ID.
        :param task: Task execution object.
        """
        LOG.info("Update task execution [id=%s, task=%s]" % (id, task))

        task_ex = db_api.get_task_execution(id)
        task_spec = spec_parser.get_task_spec(task_ex.spec)
        task_name = task.name or None
        reset = task.reset
        env = task.env or None

        if task_name and task_name != task_ex.name:
            raise exc.WorkflowException('Task name does not match.')

        wf_ex = db_api.get_workflow_execution(task_ex.workflow_execution_id)
        wf_name = task.workflow_name or None

        if wf_name and wf_name != wf_ex.name:
            raise exc.WorkflowException('Workflow name does not match.')

        if task.state != states.RUNNING:
            raise exc.WorkflowException(
                'Invalid task state. Only updating task to rerun is supported.'
            )

        if task_ex.state != states.ERROR:
            raise exc.WorkflowException(
                'The current task execution must be in ERROR for rerun.'
                ' Only updating task to rerun is supported.'
            )

        if not task_spec.get_with_items() and not reset:
            raise exc.WorkflowException(
                'Only with-items task has the option to not reset.'
            )

        rpc.get_engine_client().rerun_workflow(
            wf_ex.id,
            task_ex.id,
            reset=reset,
            env=env
        )

        task_ex = db_api.get_task_execution(id)

        return _get_task_resource_with_result(task_ex)
Пример #10
0
def send_result_to_parent_workflow(wf_ex_id):
    wf_ex = db_api.get_workflow_execution(wf_ex_id)

    if wf_ex.state == states.SUCCESS:
        rpc.get_engine_client().on_action_complete(
            wf_ex.id,
            wf_utils.Result(data=wf_ex.output)
        )
    elif wf_ex.state == states.ERROR:
        err_msg = 'Failed subworkflow [execution_id=%s]' % wf_ex.id

        rpc.get_engine_client().on_action_complete(
            wf_ex.id,
            wf_utils.Result(error=err_msg)
        )
Пример #11
0
def launch_engine(transport):
    target = messaging.Target(
        topic=cfg.CONF.engine.topic,
        server=cfg.CONF.engine.host
    )

    engine_v2 = def_eng.DefaultEngine(rpc.get_engine_client())

    endpoints = [rpc.EngineServer(engine_v2)]

    # Setup scheduler in engine.
    db_api.setup_db()
    scheduler.setup()

    # Setup expiration policy
    expiration_policy.setup()

    server = messaging.get_rpc_server(
        transport,
        target,
        endpoints,
        executor='eventlet',
        serializer=ctx.RpcContextSerializer(ctx.JsonPayloadSerializer())
    )

    engine_v2.register_membership()

    server.start()
    server.wait()
Пример #12
0
def launch_engine(transport):
    target = messaging.Target(topic=cfg.CONF.engine.topic,
                              server=cfg.CONF.engine.host)

    engine_v2 = def_eng.DefaultEngine(rpc.get_engine_client())

    endpoints = [rpc.EngineServer(engine_v2)]

    # Setup scheduler in engine.
    db_api.setup_db()
    scheduler.setup()

    # Setup expiration policy
    expiration_policy.setup()

    server = messaging.get_rpc_server(transport,
                                      target,
                                      endpoints,
                                      executor='eventlet',
                                      serializer=ctx.RpcContextSerializer(
                                          ctx.JsonPayloadSerializer()))

    engine_v2.register_membership()

    try:
        server.start()
        while True:
            time.sleep(604800)
    except (KeyboardInterrupt, SystemExit):
        pass
    finally:
        print("Stopping engine service...")
        server.stop()
        server.wait()
Пример #13
0
def launch_executor(transport):
    target = messaging.Target(topic=cfg.CONF.executor.topic,
                              server=cfg.CONF.executor.host)

    executor_v2 = def_executor.DefaultExecutor(rpc.get_engine_client())

    endpoints = [rpc.ExecutorServer(executor_v2)]

    server = messaging.get_rpc_server(transport,
                                      target,
                                      endpoints,
                                      executor='eventlet',
                                      serializer=ctx.RpcContextSerializer(
                                          ctx.JsonPayloadSerializer()))

    executor_v2.register_membership()

    try:
        server.start()
        while True:
            time.sleep(604800)
    except (KeyboardInterrupt, SystemExit):
        pass
    finally:
        print("Stopping executor service...")
        server.stop()
        server.wait()
Пример #14
0
    def post(self, wf_ex):
        """Create a new Execution.

        :param wf_ex: Execution object with input content.
        """
        LOG.info('Create execution [execution=%s]' % wf_ex)

        engine = rpc.get_engine_client()
        exec_dict = wf_ex.to_dict()

        if not (exec_dict.get('workflow_id')
                or exec_dict.get('workflow_name')):
            raise exc.WorkflowException(
                "Workflow ID or workflow name must be provided. Workflow ID is"
                " recommended."
            )

        result = engine.start_workflow(
            exec_dict.get('workflow_id', exec_dict.get('workflow_name')),
            exec_dict.get('input'),
            exec_dict.get('description', ''),
            **exec_dict.get('params') or {}
        )

        return Execution.from_dict(result)
Пример #15
0
    def put(self, id, action_execution):
        """Update the specified action_execution."""
        LOG.info(
            "Update action_execution [id=%s, action_execution=%s]"
            % (id, action_execution)
        )

        # Client must provide a valid json. It shouldn't  necessarily be an
        # object but it should be json complaint so strings have to be escaped.
        output = None

        if action_execution.output:
            try:
                output = json.loads(action_execution.output)
            except (ValueError, TypeError) as e:
                raise exc.InvalidResultException(str(e))

        if action_execution.state == states.SUCCESS:
            result = wf_utils.Result(data=output)
        elif action_execution.state == states.ERROR:
            result = wf_utils.Result(error=output)
        else:
            raise exc.InvalidResultException(
                "Error. Expected on of %s, actual: %s" %
                ([states.SUCCESS, states.ERROR], action_execution.state)
            )

        values = rpc.get_engine_client().on_action_complete(id, result)

        return ActionExecution.from_dict(values)
Пример #16
0
    def put(self, id, action_ex):
        """Update the specified action_execution."""
        acl.enforce('action_executions:update', context.ctx())
        LOG.info(
            "Update action_execution [id=%s, action_execution=%s]"
            % (id, action_ex)
        )

        output = action_ex.output

        if action_ex.state == states.SUCCESS:
            result = wf_utils.Result(data=output)
        elif action_ex.state == states.ERROR:
            if not output:
                output = 'Unknown error'
            result = wf_utils.Result(error=output)
        else:
            raise exc.InvalidResultException(
                "Error. Expected on of %s, actual: %s" %
                ([states.SUCCESS, states.ERROR], action_ex.state)
            )

        values = rpc.get_engine_client().on_action_complete(id, result)

        return ActionExecution.from_dict(values)
Пример #17
0
def launch_executor(transport):
    profiler.setup('mistral-executor', cfg.CONF.executor.host)

    target = messaging.Target(
        topic=cfg.CONF.executor.topic,
        server=cfg.CONF.executor.host
    )

    executor_v2 = def_executor.DefaultExecutor(rpc.get_engine_client())

    endpoints = [rpc.ExecutorServer(executor_v2)]

    get_rpc_server = get_rpc_server_function()

    server = get_rpc_server(
        transport,
        target,
        endpoints,
        executor='eventlet',
        serializer=ctx.RpcContextSerializer(ctx.JsonPayloadSerializer())
    )

    executor_v2.register_membership()

    try:
        server.start()
        while True:
            time.sleep(604800)
    except (KeyboardInterrupt, SystemExit):
        pass
    finally:
        print("Stopping executor service...")
        server.stop()
        server.wait()
Пример #18
0
    def put(self, id, action_execution):
        """Update the specified action_execution."""
        LOG.info("Update action_execution [id=%s, action_execution=%s]" %
                 (id, action_execution))

        # Client must provide a valid json. It shouldn't  necessarily be an
        # object but it should be json complaint so strings have to be escaped.
        output = None

        if action_execution.output:
            try:
                output = json.loads(action_execution.output)
            except (ValueError, TypeError) as e:
                raise exc.InvalidResultException(str(e))

        if action_execution.state == states.SUCCESS:
            result = wf_utils.Result(data=output)
        elif action_execution.state == states.ERROR:
            result = wf_utils.Result(error=output)
        else:
            raise exc.InvalidResultException(
                "Error. Expected on of %s, actual: %s" %
                ([states.SUCCESS, states.ERROR], action_execution.state))

        values = rpc.get_engine_client().on_action_complete(id, result)

        return ActionExecution.from_dict(values)
Пример #19
0
    def post(self, action_execution):
        """Create new action_execution."""
        body = json.loads(pecan.request.body)

        LOG.info("Create action_execution [action_execution=%s]" % body)

        action_input = action_execution.input or None
        description = action_execution.description or None

        if action_input:
            try:
                action_input = json.loads(action_execution.input)

                if not isinstance(action_input, dict):
                    raise TypeError("Input should be dict type.")
            except (TypeError, ValueError) as e:
                raise exc.InputException(
                    "Input should be JSON-serialized dict string. Actual: %s, "
                    "error: %s" % (action_execution.input, e))

        name = action_execution.name
        params = body.get('params', {})

        if not name:
            raise exc.InputException(
                "Please provide at least action name to run action.")

        action_ex = rpc.get_engine_client().start_action(
            name, action_input, description=description, **params)

        return ActionExecution.from_dict(action_ex).to_dict()
Пример #20
0
    def put(self, id, execution):
        """Update the specified Execution.

        :param id: execution ID.
        :param execution: Execution objects
        """
        LOG.info("Update execution [id=%s, execution=%s]" %
                 (id, execution))
        db_api.ensure_workflow_execution_exists(id)

        new_state = execution.state
        new_description = execution.description
        msg = execution.state_info

        # Currently we can change only state or description.
        if (not (new_state or new_description) or
                (new_state and new_description)):
            raise exc.DataAccessException(
                "Only state or description of execution can be changed. "
                "But they can not be changed at the same time."
            )

        if new_description:
            wf_ex = db_api.update_workflow_execution(
                id,
                {"description": new_description}
            )

        elif new_state == states.PAUSED:
            wf_ex = rpc.get_engine_client().pause_workflow(id)
        elif new_state == states.RUNNING:
            wf_ex = rpc.get_engine_client().resume_workflow(id)
        elif new_state in [states.SUCCESS, states.ERROR]:
            wf_ex = rpc.get_engine_client().stop_workflow(id, new_state, msg)
        else:
            # To prevent changing state in other cases throw a message.
            raise exc.DataAccessException(
                "Can not change state to %s. Allowed states are: '%s" %
                (new_state, ", ".join([states.RUNNING, states.PAUSED,
                 states.SUCCESS, states.ERROR]))
            )

        return Execution.from_dict(
            wf_ex if isinstance(wf_ex, dict) else wf_ex.to_dict()
        )
Пример #21
0
def _run_at_target(action_ex_id, action_class_str, attributes,
                   action_params, target=None):
    # We'll just call executor directly for testing purposes.
    executor = default_executor.DefaultExecutor(rpc.get_engine_client())

    executor.run_action(
        action_ex_id,
        action_class_str,
        attributes,
        action_params
    )
Пример #22
0
    def put(self, id, execution):
        """Update the specified Execution.

        :param id: execution ID.
        :param execution: Execution objects
        """
        LOG.info("Update execution [id=%s, execution=%s]" % (id, execution))
        db_api.ensure_workflow_execution_exists(id)

        new_state = execution.state
        new_description = execution.description
        msg = execution.state_info

        # Currently we can change only state or description.
        if (not (new_state or new_description)
                or (new_state and new_description)):
            raise exc.DataAccessException(
                "Only state or description of execution can be changed. "
                "But they can not be changed at the same time.")

        if new_description:
            wf_ex = db_api.update_workflow_execution(
                id, {"description": new_description})

        elif new_state == states.PAUSED:
            wf_ex = rpc.get_engine_client().pause_workflow(id)
        elif new_state == states.RUNNING:
            wf_ex = rpc.get_engine_client().resume_workflow(id)
        elif new_state in [states.SUCCESS, states.ERROR]:
            wf_ex = rpc.get_engine_client().stop_workflow(id, new_state, msg)
        else:
            # To prevent changing state in other cases throw a message.
            raise exc.DataAccessException(
                "Can not change state to %s. Allowed states are: '%s" %
                (new_state, ", ".join([
                    states.RUNNING, states.PAUSED, states.SUCCESS, states.ERROR
                ])))

        return Execution.from_dict(
            wf_ex if isinstance(wf_ex, dict) else wf_ex.to_dict())
Пример #23
0
    def put(self, id, execution):
        """Update the specified Execution.

        :param id: execution ID.
        :param execution: Execution objects
        """
        LOG.info("Update execution [id=%s, execution=%s]" %
                 (id, execution))
        db_api.ensure_workflow_execution_exists(id)

        # Currently we can change only state.
        if not execution.state:
            raise exc.DataAccessException(
                "Only state of execution can change. "
                "Missing 'state' property."
            )

        new_state = execution.state
        msg = execution.state_info

        if new_state == states.PAUSED:
            wf_ex = rpc.get_engine_client().pause_workflow(id)
        elif new_state == states.RUNNING:
            wf_ex = rpc.get_engine_client().resume_workflow(id)
        elif new_state in [states.SUCCESS, states.ERROR]:
            wf_ex = rpc.get_engine_client().stop_workflow(id, new_state, msg)
        else:
            # To prevent changing state in other cases throw a message.
            raise exc.DataAccessException(
                "Can not change state to %s. Allowed states are: '%s" %
                (new_state, ", ".join([states.RUNNING, states.PAUSED,
                 states.SUCCESS, states.ERROR]))
            )

        return Execution.from_dict(
            wf_ex if isinstance(wf_ex, dict) else wf_ex.to_dict()
        )
Пример #24
0
    def post(self, execution):
        """Create a new Execution.

        :param execution: Execution object with input content.
        """
        LOG.info("Create execution [execution=%s]" % execution)

        engine = rpc.get_engine_client()
        exec_dict = execution.to_dict()

        result = engine.start_workflow(exec_dict['workflow_name'],
                                       exec_dict.get('input'),
                                       exec_dict.get('description', ''),
                                       **exec_dict.get('params') or {})

        return Execution.from_dict(result)
Пример #25
0
    def post(self, execution):
        """Create a new Execution.

        :param execution: Execution object with input content.
        """
        LOG.info("Create execution [execution=%s]" % execution)

        engine = rpc.get_engine_client()
        exec_dict = execution.to_dict()

        result = engine.start_workflow(
            exec_dict['workflow_name'],
            exec_dict.get('input'),
            **exec_dict.get('params') or {}
        )

        return Execution.from_dict(result)
Пример #26
0
def launch_executor(transport):
    target = messaging.Target(topic=cfg.CONF.executor.topic,
                              server=cfg.CONF.executor.host)

    executor_v2 = def_executor.DefaultExecutor(rpc.get_engine_client())

    endpoints = [rpc.ExecutorServer(executor_v2)]

    server = messaging.get_rpc_server(transport,
                                      target,
                                      endpoints,
                                      executor='eventlet',
                                      serializer=ctx.RpcContextSerializer(
                                          ctx.JsonPayloadSerializer()))

    server.start()
    server.wait()
Пример #27
0
    def post(self, action_ex):
        """Create new action_execution."""
        acl.enforce('action_executions:create', context.ctx())
        LOG.info("Create action_execution [action_execution=%s]" % action_ex)

        name = action_ex.name
        description = action_ex.description or None
        action_input = action_ex.input or {}
        params = action_ex.params or {}

        if not name:
            raise exc.InputException(
                "Please provide at least action name to run action.")

        action_ex = rpc.get_engine_client().start_action(
            name, action_input, description=description, **params)

        return ActionExecution.from_dict(action_ex)
Пример #28
0
    def post(self, wf_ex):
        """Create a new Execution.

        :param wf_ex: Execution object with input content.
        """
        LOG.info('Create execution [execution=%s]' % wf_ex)

        engine = rpc.get_engine_client()
        exec_dict = wf_ex.to_dict()

        result = engine.start_workflow(
            exec_dict['workflow_name'],
            exec_dict.get('input'),
            exec_dict.get('description', ''),
            **exec_dict.get('params') or {}
        )

        return Execution.from_dict(result)
Пример #29
0
def launch_executor(transport):
    target = messaging.Target(
        topic=cfg.CONF.executor.topic,
        server=cfg.CONF.executor.host
    )

    executor_v2 = def_executor.DefaultExecutor(rpc.get_engine_client())

    endpoints = [rpc.ExecutorServer(executor_v2)]

    server = messaging.get_rpc_server(
        transport,
        target,
        endpoints,
        executor='eventlet',
        serializer=ctx.RpcContextSerializer(ctx.JsonPayloadSerializer())
    )

    server.start()
    server.wait()
Пример #30
0
    def put(self, id, action_ex):
        """Update the specified action_execution."""
        LOG.info(
            "Update action_execution [id=%s, action_execution=%s]"
            % (id, action_ex)
        )

        if action_ex.state == states.SUCCESS:
            result = wf_utils.Result(data=action_ex.output)
        elif action_ex.state == states.ERROR:
            result = wf_utils.Result(error=action_ex.output)
        else:
            raise exc.InvalidResultException(
                "Error. Expected on of %s, actual: %s" %
                ([states.SUCCESS, states.ERROR], action_ex.state)
            )

        values = rpc.get_engine_client().on_action_complete(id, result)

        return ActionExecution.from_dict(values)
Пример #31
0
def launch_engine(transport):
    profiler.setup('mistral-engine', cfg.CONF.engine.host)

    target = messaging.Target(
        topic=cfg.CONF.engine.topic,
        server=cfg.CONF.engine.host
    )

    engine_v2 = def_eng.DefaultEngine(rpc.get_engine_client())

    endpoints = [rpc.EngineServer(engine_v2)]

    # Setup scheduler in engine.
    db_api.setup_db()
    scheduler.setup()

    # Setup expiration policy
    expiration_policy.setup()

    get_rpc_server = get_rpc_server_function()

    server = get_rpc_server(
        transport,
        target,
        endpoints,
        executor='eventlet',
        serializer=ctx.RpcContextSerializer(ctx.JsonPayloadSerializer())
    )

    engine_v2.register_membership()

    try:
        server.start()
        while True:
            time.sleep(604800)
    except (KeyboardInterrupt, SystemExit):
        pass
    finally:
        print("Stopping engine service...")
        server.stop()
        server.wait()
Пример #32
0
def launch_engine(transport):
    target = messaging.Target(topic=cfg.CONF.engine.topic,
                              server=cfg.CONF.engine.host)

    engine_v2 = def_eng.DefaultEngine(rpc.get_engine_client())

    endpoints = [rpc.EngineServer(engine_v2)]

    # Setup scheduler in engine.
    db_api.setup_db()
    scheduler.setup()

    server = messaging.get_rpc_server(transport,
                                      target,
                                      endpoints,
                                      executor='eventlet',
                                      serializer=ctx.RpcContextSerializer(
                                          ctx.JsonPayloadSerializer()))

    server.start()
    server.wait()
Пример #33
0
    def put(self, id, action_ex):
        """Update the specified action_execution."""
        acl.enforce('action_executions:update', context.ctx())
        LOG.info("Update action_execution [id=%s, action_execution=%s]" %
                 (id, action_ex))

        output = action_ex.output

        if action_ex.state == states.SUCCESS:
            result = wf_utils.Result(data=output)
        elif action_ex.state == states.ERROR:
            if not output:
                output = 'Unknown error'
            result = wf_utils.Result(error=output)
        else:
            raise exc.InvalidResultException(
                "Error. Expected on of %s, actual: %s" %
                ([states.SUCCESS, states.ERROR], action_ex.state))

        values = rpc.get_engine_client().on_action_complete(id, result)

        return ActionExecution.from_dict(values)
Пример #34
0
    def post(self, action_ex):
        """Create new action_execution."""
        LOG.info("Create action_execution [action_execution=%s]" % action_ex)

        name = action_ex.name
        description = action_ex.description or None
        action_input = action_ex.input or {}
        params = action_ex.params or {}

        if not name:
            raise exc.InputException(
                "Please provide at least action name to run action."
            )

        action_ex = rpc.get_engine_client().start_action(
            name,
            action_input,
            description=description,
            **params
        )

        return ActionExecution.from_dict(action_ex)
Пример #35
0
    def post(self, wf_ex):
        """Create a new Execution.

        :param wf_ex: Execution object with input content.
        """
        LOG.info('Create execution [execution=%s]' % wf_ex)

        engine = rpc.get_engine_client()
        exec_dict = wf_ex.to_dict()

        if not (exec_dict.get('workflow_id')
                or exec_dict.get('workflow_name')):
            raise exc.WorkflowException(
                "Workflow ID or workflow name must be provided. Workflow ID is"
                " recommended.")

        result = engine.start_workflow(
            exec_dict.get('workflow_id', exec_dict.get('workflow_name')),
            exec_dict.get('input'), exec_dict.get('description', ''),
            **exec_dict.get('params') or {})

        return Execution.from_dict(result)
Пример #36
0
    def post(self, action_execution):
        """Create new action_execution."""
        body = json.loads(pecan.request.body)

        LOG.info("Create action_execution [action_execution=%s]" % body)

        action_input = action_execution.input or None
        description = action_execution.description or None

        if action_input:
            try:
                action_input = json.loads(action_execution.input)

                if not isinstance(action_input, dict):
                    raise TypeError("Input should be dict type.")
            except (TypeError, ValueError) as e:
                raise exc.InputException(
                    "Input should be JSON-serialized dict string. Actual: %s, "
                    "error: %s" % (action_execution.input, e)
                )

        name = action_execution.name
        params = body.get('params', {})

        if not name:
            raise exc.InputException(
                "Please provide at least action name to run action."
            )

        action_ex = rpc.get_engine_client().start_action(
            name,
            action_input,
            description=description,
            **params
        )

        return ActionExecution.from_dict(action_ex).to_dict()
Пример #37
0
def run_workflow(wf_name, wf_input, wf_params):
    rpc.get_engine_client().start_workflow(
        wf_name,
        wf_input,
        **wf_params
    )
Пример #38
0
      task1:
        workflow: wf1
        input:
          param1: <% env().var2 %>
          param2: <% env().var3 %>
          task_name: task2
        publish:
          slogan: >
            <% task(task1).result.final_result %> is a cool <% env().var4 %>!
"""


def _run_at_target(action_ex_id, action_class_str, attributes,
                   action_params, target=None, async=True):
    # We'll just call executor directly for testing purposes.
    executor = default_executor.DefaultExecutor(rpc.get_engine_client())

    executor.run_action(
        action_ex_id,
        action_class_str,
        attributes,
        action_params
    )


MOCK_RUN_AT_TARGET = mock.MagicMock(side_effect=_run_at_target)


class EnvironmentTest(base.EngineTestCase):
    def setUp(self):
        super(EnvironmentTest, self).setUp()
Пример #39
0
    def put(self, id, wf_ex):
        """Update the specified workflow execution.

        :param id: execution ID.
        :param wf_ex: Execution object.
        """
        LOG.info('Update execution [id=%s, execution=%s]' % (id, wf_ex))

        db_api.ensure_workflow_execution_exists(id)

        delta = {}

        if wf_ex.state:
            delta['state'] = wf_ex.state

        if wf_ex.description:
            delta['description'] = wf_ex.description

        if wf_ex.params and wf_ex.params.get('env'):
            delta['env'] = wf_ex.params.get('env')

        # Currently we can change only state, description, or env.
        if len(delta.values()) <= 0:
            raise exc.InputException(
                'The property state, description, or env '
                'is not provided for update.'
            )

        # Description cannot be updated together with state.
        if delta.get('description') and delta.get('state'):
            raise exc.InputException(
                'The property description must be updated '
                'separately from state.'
            )

        # If state change, environment cannot be updated if not RUNNING.
        if (delta.get('env') and
                delta.get('state') and delta['state'] != states.RUNNING):
            raise exc.InputException(
                'The property env can only be updated when workflow '
                'execution is not running or on resume from pause.'
            )

        if delta.get('description'):
            wf_ex = db_api.update_workflow_execution(
                id,
                {'description': delta['description']}
            )

        if not delta.get('state') and delta.get('env'):
            with db_api.transaction():
                wf_ex = db_api.get_workflow_execution(id)
                wf_ex = wf_service.update_workflow_execution_env(
                    wf_ex,
                    delta.get('env')
                )

        if delta.get('state'):
            if delta.get('state') == states.PAUSED:
                wf_ex = rpc.get_engine_client().pause_workflow(id)
            elif delta.get('state') == states.RUNNING:
                wf_ex = rpc.get_engine_client().resume_workflow(
                    id,
                    env=delta.get('env')
                )
            elif delta.get('state') in [states.SUCCESS, states.ERROR]:
                msg = wf_ex.state_info if wf_ex.state_info else None
                wf_ex = rpc.get_engine_client().stop_workflow(
                    id,
                    delta.get('state'),
                    msg
                )
            else:
                # To prevent changing state in other cases throw a message.
                raise exc.InputException(
                    "Cannot change state to %s. Allowed states are: '%s" % (
                        wf_ex.state,
                        ', '.join([
                            states.RUNNING,
                            states.PAUSED,
                            states.SUCCESS,
                            states.ERROR
                        ])
                    )
                )

        return Execution.from_dict(
            wf_ex if isinstance(wf_ex, dict) else wf_ex.to_dict()
        )
Пример #40
0
def resume_workflow(wf_ex_id, env):
    rpc.get_engine_client().resume_workflow(wf_ex_id, env=env)
Пример #41
0
          param2: <% env().var3 %>
          task_name: task2
        publish:
          slogan: >
            <% task(task1).result.final_result %> is a cool <% env().var4 %>!
"""


def _run_at_target(action_ex_id,
                   action_class_str,
                   attributes,
                   action_params,
                   target=None,
                   async=True):
    # We'll just call executor directly for testing purposes.
    executor = default_executor.DefaultExecutor(rpc.get_engine_client())

    executor.run_action(action_ex_id, action_class_str, attributes,
                        action_params)


MOCK_RUN_AT_TARGET = mock.MagicMock(side_effect=_run_at_target)


class EnvironmentTest(base.EngineTestCase):
    def setUp(self):
        super(EnvironmentTest, self).setUp()

        wb_service.create_workbook_v2(WORKBOOK)

    @mock.patch.object(rpc.ExecutorClient, 'run_action', MOCK_RUN_AT_TARGET)
Пример #42
0
def resume_workflow(wf_ex_id, env):
    rpc.get_engine_client().resume_workflow(wf_ex_id, env=env)
Пример #43
0
    def put(self, id, wf_ex):
        """Update the specified workflow execution.

        :param id: execution ID.
        :param wf_ex: Execution object.
        """
        LOG.info('Update execution [id=%s, execution=%s]' % (id, wf_ex))

        db_api.ensure_workflow_execution_exists(id)

        delta = {}

        if wf_ex.state:
            delta['state'] = wf_ex.state

        if wf_ex.description:
            delta['description'] = wf_ex.description

        if wf_ex.params and wf_ex.params.get('env'):
            delta['env'] = wf_ex.params.get('env')

        # Currently we can change only state, description, or env.
        if len(delta.values()) <= 0:
            raise exc.InputException('The property state, description, or env '
                                     'is not provided for update.')

        # Description cannot be updated together with state.
        if delta.get('description') and delta.get('state'):
            raise exc.InputException(
                'The property description must be updated '
                'separately from state.')

        # If state change, environment cannot be updated if not RUNNING.
        if (delta.get('env') and delta.get('state')
                and delta['state'] != states.RUNNING):
            raise exc.InputException(
                'The property env can only be updated when workflow '
                'execution is not running or on resume from pause.')

        if delta.get('description'):
            wf_ex = db_api.update_workflow_execution(
                id, {'description': delta['description']})

        if not delta.get('state') and delta.get('env'):
            with db_api.transaction():
                wf_ex = db_api.get_workflow_execution(id)
                wf_ex = wf_service.update_workflow_execution_env(
                    wf_ex, delta.get('env'))

        if delta.get('state'):
            if delta.get('state') == states.PAUSED:
                wf_ex = rpc.get_engine_client().pause_workflow(id)
            elif delta.get('state') == states.RUNNING:
                wf_ex = rpc.get_engine_client().resume_workflow(
                    id, env=delta.get('env'))
            elif delta.get('state') in [states.SUCCESS, states.ERROR]:
                msg = wf_ex.state_info if wf_ex.state_info else None
                wf_ex = rpc.get_engine_client().stop_workflow(
                    id, delta.get('state'), msg)
            else:
                # To prevent changing state in other cases throw a message.
                raise exc.InputException(
                    "Cannot change state to %s. Allowed states are: '%s" %
                    (wf_ex.state, ', '.join([
                        states.RUNNING, states.PAUSED, states.SUCCESS,
                        states.ERROR
                    ])))

        return Execution.from_dict(
            wf_ex if isinstance(wf_ex, dict) else wf_ex.to_dict())
Пример #44
0
def run_workflow(wf_name, wf_input, wf_params):
    rpc.get_engine_client().start_workflow(wf_name, wf_input,
                                           "sub-workflow execution",
                                           **wf_params)