Пример #1
0
    def test_request_task_execution(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'sequential.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Manually request task execution.
        task_id = 'task1'
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}
        st2_ctx = {'execution_id': wf_ex_db.action_execution}

        task_ex_req = {
            'id':
            task_id,
            'spec':
            task_spec,
            'ctx':
            task_ctx,
            'actions': [{
                'action': 'core.echo',
                'input': {
                    'message': 'Veni, vidi, vici.'
                }
            }]
        }

        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)

        # Check required attributes.
        task_ex_db = task_ex_dbs[0]
        self.assertIsNotNone(task_ex_db.id)
        self.assertGreater(task_ex_db.rev, 0)
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        self.assertEqual(task_ex_db.status, wf_states.RUNNING)

        # Check action execution for the task query with task execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(
            task_execution=str(task_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)

        # Check action execution for the task query with workflow execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)
Пример #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()
Пример #3
0
    def test_request_task_execution(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH, 'sequential.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Manually request task execution.
        task_route = 0
        task_id = 'task1'
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}
        st2_ctx = {'execution_id': wf_ex_db.action_execution}

        task_ex_req = {
            'id': task_id,
            'route': task_route,
            'spec': task_spec,
            'ctx': task_ctx,
            'actions': [
                {'action': 'core.echo', 'input': {'message': 'Veni, vidi, vici.'}}
            ]
        }

        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)

        # Check required attributes.
        task_ex_db = task_ex_dbs[0]
        self.assertIsNotNone(task_ex_db.id)
        self.assertGreater(task_ex_db.rev, 0)
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        self.assertEqual(task_ex_db.status, wf_statuses.RUNNING)

        # Check action execution for the task query with task execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(task_execution=str(task_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)

        # Check action execution for the task query with workflow execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)
Пример #4
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()
Пример #5
0
    def run_workflow_step(
            self,
            wf_ex_db,
            task_id,
            route,
            ctx=None,
            expected_ac_ex_db_status=ac_const.LIVEACTION_STATUS_SUCCEEDED,
            expected_tk_ex_db_status=wf_statuses.SUCCEEDED):
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)
        st2_ctx = {'execution_id': wf_ex_db.action_execution}
        task_spec = wf_spec.tasks.get_task(task_id)
        task_actions = [{
            'action': task_spec.action,
            'input': getattr(task_spec, 'input', {})
        }]

        task_req = {
            'id': task_id,
            'route': route,
            'spec': task_spec,
            'ctx': ctx or {},
            'actions': task_actions
        }

        task_ex_db = wf_svc.request_task_execution(wf_ex_db, st2_ctx, task_req)
        ac_ex_db = self.get_action_ex(str(task_ex_db.id))
        ac_ex_db = self._wait_on_ac_ex_status(ac_ex_db,
                                              expected_ac_ex_db_status)

        wf_svc.handle_action_execution_completion(ac_ex_db)
        task_ex_db = wf_db_access.TaskExecution.get_by_id(str(task_ex_db.id))
        self.assertEqual(task_ex_db.status, expected_tk_ex_db_status)
Пример #6
0
    def run_workflow_step(
        self,
        wf_ex_db,
        task_id,
        route,
        ctx=None,
        expected_ac_ex_db_status=ac_const.LIVEACTION_STATUS_SUCCEEDED,
        expected_tk_ex_db_status=wf_statuses.SUCCEEDED,
    ):
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec["catalog"])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)
        st2_ctx = {"execution_id": wf_ex_db.action_execution}
        task_spec = wf_spec.tasks.get_task(task_id)
        task_actions = [
            {"action": task_spec.action, "input": getattr(task_spec, "input", {})}
        ]

        task_req = {
            "id": task_id,
            "route": route,
            "spec": task_spec,
            "ctx": ctx or {},
            "actions": task_actions,
        }

        task_ex_db = wf_svc.request_task_execution(wf_ex_db, st2_ctx, task_req)
        ac_ex_db = self.get_action_ex(str(task_ex_db.id))
        ac_ex_db = self._wait_on_ac_ex_status(ac_ex_db, expected_ac_ex_db_status)

        wf_svc.handle_action_execution_completion(ac_ex_db)
        task_ex_db = wf_db_access.TaskExecution.get_by_id(str(task_ex_db.id))
        self.assertEqual(task_ex_db.status, expected_tk_ex_db_status)
Пример #7
0
    def test_request_task_execution(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                TEST_FIXTURES['workflows'][0])

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = wf_svc.request(wf_def, ac_ex_db, st2_ctx)

        # Manually request task execution.
        task_id = 'task1'
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}
        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)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)

        # Check required attributes.
        task_ex_db = task_ex_dbs[0]
        self.assertIsNotNone(task_ex_db.id)
        self.assertGreater(task_ex_db.rev, 0)
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        self.assertEqual(task_ex_db.status, wf_lib_states.RUNNING)

        # Check action execution for the task query with task execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(
            task_execution=str(task_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)

        # Check action execution for the task query with workflow execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)
Пример #8
0
 def run_workflow_step(self, wf_ex_db, task_id, ctx=None):
     spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
     wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)
     task_spec = wf_spec.tasks.get_task(task_id)
     st2_ctx = {'execution_id': wf_ex_db.action_execution}
     task_ex_db = wf_svc.request_task_execution(wf_ex_db, task_id, task_spec, ctx or {}, st2_ctx)
     ac_ex_db = self.get_action_ex(str(task_ex_db.id))
     self.assertEqual(ac_ex_db.status, ac_const.LIVEACTION_STATUS_SUCCEEDED)
     wf_svc.handle_action_execution_completion(ac_ex_db)
     task_ex_db = wf_db_access.TaskExecution.get_by_id(str(task_ex_db.id))
     self.assertEqual(task_ex_db.status, wf_lib_states.SUCCEEDED)
Пример #9
0
Файл: base.py Проект: versus/st2
 def run_workflow_step(self, wf_ex_db, task_id, ctx=None):
     spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
     wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)
     task_spec = wf_spec.tasks.get_task(task_id)
     st2_ctx = {'execution_id': wf_ex_db.action_execution}
     task_ex_db = wf_svc.request_task_execution(wf_ex_db, task_id,
                                                task_spec, ctx or {},
                                                st2_ctx)
     ac_ex_db = self.get_action_ex(str(task_ex_db.id))
     self.assertEqual(ac_ex_db.status, ac_const.LIVEACTION_STATUS_SUCCEEDED)
     wf_svc.handle_action_execution_completion(ac_ex_db)
     task_ex_db = wf_db_access.TaskExecution.get_by_id(str(task_ex_db.id))
     self.assertEqual(task_ex_db.status, wf_lib_states.SUCCEEDED)
Пример #10
0
    def test_request_task_execution(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH, TEST_FIXTURES['workflows'][0])

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = ac_svc.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        wf_ex_db = wf_svc.request(wf_def, ac_ex_db)

        # Manually request task execution.
        task_id = 'task1'
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}
        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)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)

        # Check required attributes.
        task_ex_db = task_ex_dbs[0]
        self.assertIsNotNone(task_ex_db.id)
        self.assertGreater(task_ex_db.rev, 0)
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        self.assertEqual(task_ex_db.status, wf_lib_states.RUNNING)

        # Check action execution for the task query with task execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(task_execution=str(task_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)

        # Check action execution for the task query with workflow execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)
Пример #11
0
Файл: base.py Проект: nzlosh/st2
    def run_workflow_step(self, wf_ex_db, task_id, route, ctx=None):
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)
        st2_ctx = {'execution_id': wf_ex_db.action_execution}
        task_spec = wf_spec.tasks.get_task(task_id)
        task_actions = [{'action': task_spec.action, 'input': getattr(task_spec, 'input', {})}]

        task_req = {
            'id': task_id,
            'route': route,
            'spec': task_spec,
            'ctx': ctx or {},
            'actions': task_actions
        }

        task_ex_db = wf_svc.request_task_execution(wf_ex_db, st2_ctx, task_req)
        ac_ex_db = self.get_action_ex(str(task_ex_db.id))
        ac_ex_db = self._wait_on_ac_ex_status(ac_ex_db, ac_const.LIVEACTION_STATUS_SUCCEEDED)

        wf_svc.handle_action_execution_completion(ac_ex_db)
        task_ex_db = wf_db_access.TaskExecution.get_by_id(str(task_ex_db.id))
        self.assertEqual(task_ex_db.status, wf_statuses.SUCCEEDED)
Пример #12
0
    def test_request_action_execution_render(self):
        # Manually create ConfigDB
        output = 'Testing'
        value = {"config_item_one": output}
        config_db = pk_db_models.ConfigDB(pack=PACK_7, values=value)
        config = pk_db_access.Config.add_or_update(config_db)
        self.assertEqual(len(config), 3)

        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                'render_config_context.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Pass down appropriate st2 context to the task and action execution(s).
        root_st2_ctx = wf_ex_db.context.get('st2', {})
        st2_ctx = {
            'execution_id': wf_ex_db.action_execution,
            'user': root_st2_ctx.get('user'),
            'pack': root_st2_ctx.get('pack')
        }

        # Manually request task execution.
        task_route = 0
        task_id = 'task1'
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}

        task_ex_req = {
            'id':
            task_id,
            'route':
            task_route,
            'spec':
            task_spec,
            'ctx':
            task_ctx,
            'actions': [{
                'action': 'dummy_pack_7.render_config_context',
                'input': None
            }]
        }
        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)
        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Manually request action execution
        task_ex_db = task_ex_dbs[0]
        action_ex_db = workflow_service.request_action_execution(
            wf_ex_db, task_ex_db, st2_ctx, task_ex_req['actions'][0])

        # Check required attributes.
        self.assertIsNotNone(str(action_ex_db.id))
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        expected_parameters = {'value1': output}
        self.assertEqual(expected_parameters, action_ex_db.parameters)
Пример #13
0
    def test_request_action_execution_render(self):
        # Manually create ConfigDB
        output = "Testing"
        value = {"config_item_one": output}
        config_db = pk_db_models.ConfigDB(pack=PACK_7, values=value)
        config = pk_db_access.Config.add_or_update(config_db)
        self.assertEqual(len(config), 3)

        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                "render_config_context.yaml")

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta["name"])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec["catalog"])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Pass down appropriate st2 context to the task and action execution(s).
        root_st2_ctx = wf_ex_db.context.get("st2", {})
        st2_ctx = {
            "execution_id": wf_ex_db.action_execution,
            "user": root_st2_ctx.get("user"),
            "pack": root_st2_ctx.get("pack"),
        }

        # Manually request task execution.
        task_route = 0
        task_id = "task1"
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {"foo": "bar"}

        task_ex_req = {
            "id":
            task_id,
            "route":
            task_route,
            "spec":
            task_spec,
            "ctx":
            task_ctx,
            "actions": [{
                "action": "dummy_pack_7.render_config_context",
                "input": None
            }],
        }
        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)
        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Manually request action execution
        task_ex_db = task_ex_dbs[0]
        action_ex_db = workflow_service.request_action_execution(
            wf_ex_db, task_ex_db, st2_ctx, task_ex_req["actions"][0])

        # Check required attributes.
        self.assertIsNotNone(str(action_ex_db.id))
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        expected_parameters = {"value1": output}
        self.assertEqual(expected_parameters, action_ex_db.parameters)
Пример #14
0
    def test_request_task_execution(self):
        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH,
                                                "sequential.yaml")

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta["name"])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec["catalog"])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Manually request task execution.
        task_route = 0
        task_id = "task1"
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {"foo": "bar"}
        st2_ctx = {"execution_id": wf_ex_db.action_execution}

        task_ex_req = {
            "id":
            task_id,
            "route":
            task_route,
            "spec":
            task_spec,
            "ctx":
            task_ctx,
            "actions": [{
                "action": "core.echo",
                "input": {
                    "message": "Veni, vidi, vici."
                }
            }],
        }

        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)

        # Check required attributes.
        task_ex_db = task_ex_dbs[0]
        self.assertIsNotNone(task_ex_db.id)
        self.assertGreater(task_ex_db.rev, 0)
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        self.assertEqual(task_ex_db.status, wf_statuses.RUNNING)

        # Check action execution for the task query with task execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(
            task_execution=str(task_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)

        # Check action execution for the task query with workflow execution ID.
        ac_ex_dbs = ex_db_access.ActionExecution.query(
            workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(ac_ex_dbs), 1)
Пример #15
0
    def test_request_action_execution_render(self):
        # Manually create ConfigDB
        output = 'Testing'
        value = {
            "config_item_one": output
        }
        config_db = pk_db_models.ConfigDB(pack=PACK_7, values=value)
        config = pk_db_access.Config.add_or_update(config_db)
        self.assertEqual(len(config), 3)

        wf_meta = self.get_wf_fixture_meta_data(TEST_PACK_PATH, 'render_config_context.yaml')

        # Manually create the liveaction and action execution objects without publishing.
        lv_ac_db = lv_db_models.LiveActionDB(action=wf_meta['name'])
        lv_ac_db, ac_ex_db = action_service.create_request(lv_ac_db)

        # Request the workflow execution.
        wf_def = self.get_wf_def(TEST_PACK_PATH, wf_meta)
        st2_ctx = self.mock_st2_context(ac_ex_db)
        wf_ex_db = workflow_service.request(wf_def, ac_ex_db, st2_ctx)
        spec_module = specs_loader.get_spec_module(wf_ex_db.spec['catalog'])
        wf_spec = spec_module.WorkflowSpec.deserialize(wf_ex_db.spec)

        # Pass down appropriate st2 context to the task and action execution(s).
        root_st2_ctx = wf_ex_db.context.get('st2', {})
        st2_ctx = {
            'execution_id': wf_ex_db.action_execution,
            'user': root_st2_ctx.get('user'),
            'pack': root_st2_ctx.get('pack')
        }

        # Manually request task execution.
        task_route = 0
        task_id = 'task1'
        task_spec = wf_spec.tasks.get_task(task_id)
        task_ctx = {'foo': 'bar'}

        task_ex_req = {
            'id': task_id,
            'route': task_route,
            'spec': task_spec,
            'ctx': task_ctx,
            'actions': [
                {'action': 'dummy_pack_7.render_config_context', 'input': None}
            ]
        }
        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Check task execution is saved to the database.
        task_ex_dbs = wf_db_access.TaskExecution.query(workflow_execution=str(wf_ex_db.id))
        self.assertEqual(len(task_ex_dbs), 1)
        workflow_service.request_task_execution(wf_ex_db, st2_ctx, task_ex_req)

        # Manually request action execution
        task_ex_db = task_ex_dbs[0]
        action_ex_db = workflow_service.request_action_execution(wf_ex_db, task_ex_db, st2_ctx,
                                                                 task_ex_req['actions'][0])

        # Check required attributes.
        self.assertIsNotNone(str(action_ex_db.id))
        self.assertEqual(task_ex_db.workflow_execution, str(wf_ex_db.id))
        expected_parameters = {'value1': output}
        self.assertEqual(expected_parameters, action_ex_db.parameters)
Пример #16
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)