Beispiel #1
0
    def fail_workflow_execution(self, message, exception):
        # Prepare attributes based on message type.
        if isinstance(message, wf_db_models.WorkflowExecutionDB):
            msg_type = 'workflow'
            wf_ex_db = message
            wf_ex_id = str(wf_ex_db.id)
            task = None
        else:
            msg_type = 'task'
            ac_ex_db = message
            wf_ex_id = ac_ex_db.context['orquesta']['workflow_execution_id']
            task_ex_id = ac_ex_db.context['orquesta']['task_execution_id']
            wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_id)
            task_ex_db = wf_db_access.TaskExecution.get_by_id(task_ex_id)
            task = {'id': task_ex_db.task_id, 'route': task_ex_db.task_route}

        # Log the error.
        LOG.error('[%s] Unknown error while processing %s execution. %s: %s',
                  wf_ex_db.action_execution, msg_type,
                  exception.__class__.__name__, str(exception))

        # Fail the task execution so it's marked correctly in the
        # conductor state to allow for task rerun if needed.
        if isinstance(message, ex_db_models.ActionExecutionDB):
            msg = '[%s] Unknown error while processing %s execution. Failing task execution "%s".'
            LOG.error(msg, wf_ex_db.action_execution, msg_type, task_ex_id)
            wf_svc.update_task_execution(task_ex_id,
                                         ac_const.LIVEACTION_STATUS_FAILED)
            wf_svc.update_task_state(task_ex_id,
                                     ac_const.LIVEACTION_STATUS_FAILED)

        # Fail the workflow execution.
        msg = '[%s] Unknown error while processing %s execution. Failing workflow execution "%s".'
        LOG.error(msg, wf_ex_db.action_execution, msg_type, wf_ex_id)
        wf_svc.fail_workflow_execution(wf_ex_id, exception, task=task)
Beispiel #2
0
    def process(self, wf_ex_db):
        # Refresh record from the database in case the request is in the queue for too long.
        conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))

        # Continue if workflow is still active.
        if conductor.get_workflow_state() not in states.COMPLETED_STATES:
            # Set workflow to running state.
            conductor.set_workflow_state(states.RUNNING)

        # Identify the next set of tasks to execute.
        next_tasks = conductor.get_next_tasks()

        # If there is no new tasks, update execution records to handle possible completion.
        if not next_tasks:
            # Update workflow execution and related liveaction and action execution.
            wf_svc.update_execution_records(wf_ex_db, conductor)

        # If workflow execution is no longer active, then stop processing here.
        if wf_ex_db.status in states.COMPLETED_STATES:
            return

        # Iterate while there are next tasks identified for processing. In the case for
        # task with no action execution defined, the task execution will complete
        # immediately with a new set of tasks available.
        while next_tasks:
            # Mark the tasks as running in the task flow before actual task execution.
            for task in next_tasks:
                conductor.update_task_flow(task['id'], states.RUNNING)

            # Update workflow execution and related liveaction and action execution.
            wf_svc.update_execution_records(wf_ex_db, conductor)

            # If workflow execution is no longer active, then stop processing here.
            if wf_ex_db.status in states.COMPLETED_STATES:
                break

            # Request task execution for the tasks.
            for task in next_tasks:
                try:
                    task_id, task_spec, task_ctx = task['id'], task[
                        'spec'], task['ctx']
                    st2_ctx = {'execution_id': wf_ex_db.action_execution}
                    wf_svc.request_task_execution(wf_ex_db, task_id, task_spec,
                                                  task_ctx, st2_ctx)
                except Exception as e:
                    wf_svc.fail_workflow_execution(str(wf_ex_db.id),
                                                   e,
                                                   task_id=task['id'])
                    return

            # Identify the next set of tasks to execute.
            conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))
            next_tasks = conductor.get_next_tasks()
Beispiel #3
0
    def process(self, wf_ex_db):
        # Refresh record from the database in case the request is in the queue for too long.
        conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))

        # Continue if workflow is still active.
        if conductor.get_workflow_state() not in states.COMPLETED_STATES:
            # Set workflow to running state.
            conductor.set_workflow_state(states.RUNNING)

        # Identify the next set of tasks to execute.
        next_tasks = conductor.get_next_tasks()

        # If there is no new tasks, update execution records to handle possible completion.
        if not next_tasks:
            # Update workflow execution and related liveaction and action execution.
            wf_svc.update_execution_records(wf_ex_db, conductor)

        # If workflow execution is no longer active, then stop processing here.
        if wf_ex_db.status in states.COMPLETED_STATES:
            return

        # Iterate while there are next tasks identified for processing. In the case for
        # task with no action execution defined, the task execution will complete
        # immediately with a new set of tasks available.
        while next_tasks:
            # Mark the tasks as running in the task flow before actual task execution.
            for task in next_tasks:
                conductor.update_task_flow(task['id'], states.RUNNING)

            # Update workflow execution and related liveaction and action execution.
            wf_svc.update_execution_records(wf_ex_db, conductor)

            # If workflow execution is no longer active, then stop processing here.
            if wf_ex_db.status in states.COMPLETED_STATES:
                break

            # Request task execution for the tasks.
            for task in next_tasks:
                try:
                    task_id, task_spec, task_ctx = task['id'], task['spec'], task['ctx']
                    st2_ctx = {'execution_id': wf_ex_db.action_execution}
                    wf_svc.request_task_execution(wf_ex_db, task_id, task_spec, task_ctx, st2_ctx)
                except Exception as e:
                    wf_svc.fail_workflow_execution(str(wf_ex_db.id), e, task_id=task['id'])
                    return

            # Identify the next set of tasks to execute.
            conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))
            next_tasks = conductor.get_next_tasks()
Beispiel #4
0
    def fail_workflow_execution(self, message, exception):
        # Prepare attributes based on message type.
        if isinstance(message, wf_db_models.WorkflowExecutionDB):
            msg_type = "workflow"
            wf_ex_db = message
            wf_ex_id = str(wf_ex_db.id)
            task = None
        else:
            msg_type = "task"
            ac_ex_db = message
            wf_ex_id = ac_ex_db.context["orquesta"]["workflow_execution_id"]
            task_ex_id = ac_ex_db.context["orquesta"]["task_execution_id"]
            wf_ex_db = wf_db_access.WorkflowExecution.get_by_id(wf_ex_id)
            task_ex_db = wf_db_access.TaskExecution.get_by_id(task_ex_id)
            task = {"id": task_ex_db.task_id, "route": task_ex_db.task_route}

        # Log the error.
        msg = "Unknown error while processing %s execution. %s: %s"
        wf_svc.update_progress(
            wf_ex_db,
            msg % (msg_type, exception.__class__.__name__, str(exception)),
            severity="error",
        )

        # Fail the task execution so it's marked correctly in the
        # conductor state to allow for task rerun if needed.
        if isinstance(message, ex_db_models.ActionExecutionDB):
            msg = 'Unknown error while processing %s execution. Failing task execution "%s".'
            wf_svc.update_progress(
                wf_ex_db, msg % (msg_type, task_ex_id), severity="error"
            )
            wf_svc.update_task_execution(task_ex_id, ac_const.LIVEACTION_STATUS_FAILED)
            wf_svc.update_task_state(task_ex_id, ac_const.LIVEACTION_STATUS_FAILED)

        # Fail the workflow execution.
        msg = 'Unknown error while processing %s execution. Failing workflow execution "%s".'
        wf_svc.update_progress(wf_ex_db, msg % (msg_type, wf_ex_id), severity="error")
        wf_svc.fail_workflow_execution(wf_ex_id, exception, task=task)
Beispiel #5
0
    def handle_workflow_execution(self, wf_ex_db):
        iteration = 0
        wf_ac_ex_id = wf_ex_db.action_execution
        LOG.info('[%s] Processing request for workflow execution.',
                 wf_ac_ex_id)

        # Refresh record from the database in case the request is in the queue for too long.
        conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))

        # Continue if workflow is still active and set workflow to running state.
        if conductor.get_workflow_state() not in states.COMPLETED_STATES:
            LOG.info(
                '[%s] Requesting conductor to start running workflow execution.',
                wf_ac_ex_id)
            conductor.request_workflow_state(states.RUNNING)

        # Identify the next set of tasks to execute.
        msg = '[%s] Identifying next set (%s) of tasks for workflow execution in state "%s".'
        LOG.info(msg, wf_ac_ex_id, str(iteration),
                 conductor.get_workflow_state())
        LOG.debug('[%s] %s', wf_ac_ex_id, conductor.serialize())
        next_tasks = conductor.get_next_tasks()

        # If there is no new tasks, update execution records to handle possible completion.
        if not next_tasks:
            # Update workflow execution and related liveaction and action execution.
            LOG.info('[%s] No tasks identified to execute next.', wf_ac_ex_id)
            wf_svc.update_execution_records(wf_ex_db, conductor)

        # If workflow execution is no longer active, then stop processing here.
        if wf_ex_db.status in states.COMPLETED_STATES:
            msg = '[%s] Workflow execution is in completed state "%s".'
            LOG.info(msg, wf_ac_ex_id, wf_ex_db.status)
            return

        # Iterate while there are next tasks identified for processing. In the case for
        # task with no action execution defined, the task execution will complete
        # immediately with a new set of tasks available.
        while next_tasks:
            msg = '[%s] Identified the following set of tasks to execute next: %s'
            LOG.info(msg, wf_ac_ex_id,
                     ', '.join([task['id'] for task in next_tasks]))

            # Mark the tasks as running in the task flow before actual task execution.
            for task in next_tasks:
                msg = '[%s] Mark task "%s" in conductor as running.'
                LOG.info(msg, wf_ac_ex_id, task['id'])
                ac_ex_event = events.ActionExecutionEvent(states.RUNNING)
                conductor.update_task_flow(task['id'], ac_ex_event)

            # Update workflow execution and related liveaction and action execution.
            wf_svc.update_execution_records(wf_ex_db, conductor)

            # If workflow execution is no longer active, then stop processing here.
            if wf_ex_db.status in states.COMPLETED_STATES:
                msg = '[%s] Workflow execution is in completed state "%s".'
                LOG.info(msg, wf_ac_ex_id, wf_ex_db.status)
                break

            # Request task execution for the tasks.
            for task in next_tasks:
                try:
                    LOG.info('[%s] Requesting execution for task "%s".',
                             wf_ac_ex_id, task['id'])
                    task_id, task_spec, task_ctx = task['id'], task[
                        'spec'], task['ctx']
                    st2_ctx = {'execution_id': wf_ex_db.action_execution}
                    wf_svc.request_task_execution(wf_ex_db, task_id, task_spec,
                                                  task_ctx, st2_ctx)
                except Exception as e:
                    LOG.exception('[%s] Failed task execution for "%s".',
                                  wf_ac_ex_id, task['id'])
                    wf_svc.fail_workflow_execution(str(wf_ex_db.id),
                                                   e,
                                                   task_id=task['id'])
                    return

            # Identify the next set of tasks to execute.
            iteration += 1
            conductor, wf_ex_db = wf_svc.refresh_conductor(str(wf_ex_db.id))
            msg = '[%s] Identifying next set (%s) of tasks for workflow execution in state "%s".'
            LOG.info(msg, wf_ac_ex_id, str(iteration),
                     conductor.get_workflow_state())
            LOG.debug('[%s] %s', wf_ac_ex_id, conductor.serialize())
            next_tasks = conductor.get_next_tasks()

            if not next_tasks:
                LOG.info('[%s] No tasks identified to execute next.',
                         wf_ac_ex_id)