Пример #1
0
def instantiate(spec_type, definition):
    if not definition:
        raise ValueError('Workflow definition is empty.')

    if isinstance(definition, six.string_types):
        definition = yaml.safe_load(definition)

    if not isinstance(definition, dict):
        raise ValueError('Unable to convert workflow definition into dict.')

    spec_module = spec_loader.get_spec_module(spec_type)

    version = definition.pop('version', None)

    if not version:
        raise ValueError('Version of the workflow definition is not provided.')

    spec_version = spec_module.VERSION

    if str(version) != str(spec_version):
        raise ValueError('Workflow definition is not the supported version "%s".', spec_version)

    if not definition.keys():
        raise ValueError('Workflow definition contains no workflow.')

    return spec_module.instantiate(definition)
    def test_get_spec(self):
        spec_module = spec_loader.get_spec_module(self.spec_module_name)

        self.assertEqual(
            spec_module.WorkflowSpec,
            mistral_specs.WorkflowSpec
        )
    def test_spec_catalog(self):
        spec_module = spec_loader.get_spec_module(self.spec_module_name)

        self.assertEqual(
            spec_module.WorkflowSpec.get_catalog(),
            self.spec_module_name
        )
Пример #4
0
    def test_request_task_execution_bad_action(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 = 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}

        task_spec.action = 'mock.foobar'

        self.assertRaises(ac_exc.InvalidActionReferencedException,
                          wf_svc.request_task_execution, wf_ex_db, task_id,
                          task_spec, task_ctx, st2_ctx)
Пример #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 setUpClass(cls):
        WorkflowGraphTest.setUpClass()
        WorkflowSpecTest.setUpClass()

        cls.composer = plugin_util.get_module('orquesta.composers', cls.spec_module_name)
        cls.spec_module = spec_loader.get_spec_module(cls.spec_module_name)
        cls.wf_spec_type = cls.spec_module.WorkflowSpec
Пример #7
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)
Пример #8
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)
Пример #9
0
def request(wf_def, ac_ex_db, st2_ctx):
    wf_ac_ex_id = str(ac_ex_db.id)
    LOG.info('[%s] Processing action execution request for workflow.',
             wf_ac_ex_id)

    # Load workflow definition into workflow spec model.
    spec_module = specs_loader.get_spec_module('native')
    wf_spec = spec_module.instantiate(wf_def)

    # Inspect the workflow spec.
    inspect(wf_spec, st2_ctx, raise_exception=True)

    # Identify the action to execute.
    action_db = action_utils.get_action_by_ref(ref=ac_ex_db.action['ref'])

    if not action_db:
        error = 'Unable to find action "%s".' % ac_ex_db.action['ref']
        raise ac_exc.InvalidActionReferencedException(error)

    # Identify the runner for the action.
    runner_type_db = action_utils.get_runnertype_by_name(
        action_db.runner_type['name'])

    # Render action execution parameters.
    runner_params, action_params = param_utils.render_final_params(
        runner_type_db.runner_parameters, action_db.parameters,
        ac_ex_db.parameters, ac_ex_db.context)

    # Instantiate the workflow conductor.
    conductor_params = {'inputs': action_params, 'context': st2_ctx}
    conductor = conducting.WorkflowConductor(wf_spec, **conductor_params)

    # Set the initial workflow state to requested.
    conductor.request_workflow_state(states.REQUESTED)

    # Serialize the conductor which initializes some internal values.
    data = conductor.serialize()

    # Create a record for workflow execution.
    wf_ex_db = wf_db_models.WorkflowExecutionDB(action_execution=str(
        ac_ex_db.id),
                                                spec=data['spec'],
                                                graph=data['graph'],
                                                flow=data['flow'],
                                                context=data['context'],
                                                input=data['input'],
                                                output=data['output'],
                                                errors=data['errors'],
                                                status=data['state'])

    # Insert new record into the database and publish to the message bus.
    wf_ex_db = wf_db_access.WorkflowExecution.insert(wf_ex_db, publish=True)
    LOG.info('[%s] Workflow execution "%s" created.', wf_ac_ex_id,
             str(wf_ex_db.id))

    return wf_ex_db
Пример #10
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)
Пример #11
0
    def post(self, wf_def):
        # Load workflow definition into workflow spec model.
        spec_module = specs_loader.get_spec_module('native')
        wf_spec = spec_module.instantiate(wf_def)

        # Mock the st2 context that is typically passed to the workflow engine.
        st2_ctx = self.mock_st2_ctx()

        # Inspect the workflow spec and return the errors instead of raising exception.
        errors = workflow_service.inspect(wf_spec, st2_ctx, raise_exception=False)

        # Return the result of the inspection.
        return router.Response(json=errors)
Пример #12
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)
Пример #13
0
    def __init__(self, session, *args, **kwargs):
        super(WorkflowRehearsal, self).__init__(*args, **kwargs)

        if not session:
            raise exc.WorkflowRehearsalError(
                "The session object is not provided.")

        if not isinstance(session, WorkflowTestCase) and not isinstance(
                session, WorkflowRerunTestCase):
            raise exc.WorkflowRehearsalError(
                "The session object is not type of WorkflowTestCase or WorkflowRerunTestCase."
            )

        self.session = session
        self.inspection_errors = {}
        self.rerun = False

        if isinstance(session, WorkflowTestCase):
            self.spec_module = spec_loader.get_spec_module(
                session.spec_module_name)
            self.wf_spec = self.spec_module.instantiate(self.session.wf_def)
            self.conductor = None
        elif isinstance(session, WorkflowRerunTestCase):
            self.conductor = self.session.conductor
            self.spec_module = self.conductor.spec_module
            self.wf_spec = self.conductor.spec
            self.rerun = True

        for mock_ac_ex in self.session.mock_action_executions:
            if not self.wf_spec.tasks.has_task(mock_ac_ex.task_id):
                raise exc.InvalidTask(mock_ac_ex.task_id)

            task_spec = self.wf_spec.tasks.get_task(mock_ac_ex.task_id)

            if task_spec.has_items() and mock_ac_ex.item_id is None:
                msg = 'Mock action execution for with items task "%s" is misssing "item_id".'
                raise exc.WorkflowRehearsalError(msg % mock_ac_ex.task_id)

            if not mock_ac_ex.result_path:
                continue

            if not os.path.isfile(mock_ac_ex.result_path):
                msg = 'The result path "%s" for the mock action execution does not exist.'
                raise exc.WorkflowRehearsalError(msg % mock_ac_ex.result_path)

            name, ext = os.path.splitext(mock_ac_ex.result_path)

            with open(mock_ac_ex.result_path) as f:
                mock_ac_ex.result = (fixture_loader.FIXTURE_EXTS[ext](f)
                                     if ext in fixture_loader.FIXTURE_EXTS else
                                     f.read())
Пример #14
0
    def deserialize(cls, data):
        spec_module = spec_loader.get_spec_module(data['spec']['catalog'])
        spec = spec_module.WorkflowSpec.deserialize(data['spec'])

        graph = graphing.WorkflowGraph.deserialize(data['graph'])
        inputs = copy.deepcopy(data['input'])
        context = copy.deepcopy(data['context'])
        state = WorkflowState.deserialize(data['state'])
        log = copy.deepcopy(data.get('log', []))
        errors = copy.deepcopy(data['errors'])
        outputs = copy.deepcopy(data['output'])

        instance = cls(spec)
        instance.restore(graph, log, errors, state, inputs, outputs, context)

        return instance
Пример #15
0
    def __init__(self, spec, context=None, inputs=None):
        if not spec or not isinstance(spec, spec_base.Spec):
            raise ValueError('The value of "spec" is not type of Spec.')

        self.spec = spec
        self.catalog = self.spec.get_catalog()
        self.spec_module = spec_loader.get_spec_module(self.catalog)
        self.composer = plugin_util.get_module('orquesta.composers', self.catalog)

        self._errors = []
        self._graph = None
        self._inputs = inputs or {}
        self._log = []
        self._outputs = None
        self._parent_ctx = context or {}
        self._workflow_state = None
Пример #16
0
    def test_request_task_execution_bad_action(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": "mock.echo",
                "input": {
                    "message": "Veni, vidi, vici."
                }
            }],
        }

        self.assertRaises(
            action_exc.InvalidActionReferencedException,
            workflow_service.request_task_execution,
            wf_ex_db,
            st2_ctx,
            task_ex_req,
        )
Пример #17
0
    def test_duplicate_tasks(self):
        wf_def = """
            version: 1.0

            description: A sample workflow with a single task loop.

            input:
              - count: 0

            tasks:
              init:
                action: core.noop
                next:
                  - do: task1
              task1:
                action: core.noop
              task1:
                action: core.noop
                next:
                  - when: <% ctx().count < 2 %>
                    publish:
                      - count: <% ctx().count + 1 %>
                    do: task1
        """

        expected_error = 'Failed to load workflow definition because found duplicate key "task1"'

        assertRaisesRegex = self.assertRaisesRegex if six.PY3 else self.assertRaisesRegexp

        assertRaisesRegex(
            ValueError,
            expected_error,
            spec_util.instantiate,
            self.spec_module_name,
            wf_def,
        )

        spec_module = spec_loader.get_spec_module(self.spec_module_name)

        assertRaisesRegex(
            ValueError,
            expected_error,
            spec_module.instantiate,
            wf_def,
        )
Пример #18
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)
Пример #19
0
    def test_request_task_execution_bad_action(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': 'mock.echo',
                'input': {
                    'message': 'Veni, vidi, vici.'
                }
            }]
        }

        self.assertRaises(action_exc.InvalidActionReferencedException,
                          workflow_service.request_task_execution, wf_ex_db,
                          st2_ctx, task_ex_req)
Пример #20
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)
Пример #21
0
    def test_request_task_execution_bad_action(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': 'mock.echo', 'input': {'message': 'Veni, vidi, vici.'}}
            ]
        }

        self.assertRaises(
            action_exc.InvalidActionReferencedException,
            workflow_service.request_task_execution,
            wf_ex_db,
            st2_ctx,
            task_ex_req
        )
Пример #22
0
 def test_get_module(self):
     self.assertEqual(loader.get_spec_module(self.spec_module_name),
                      orquesta_specs)
Пример #23
0
 def test_get_module(self):
     self.assertEqual(loader.get_spec_module('mock'), mock)
Пример #24
0
    def test_get_spec(self):
        spec_module = loader.get_spec_module('mock')

        self.assertEqual(spec_module.WorkflowSpec.get_catalog(), 'mock')
        self.assertEqual(spec_module.WorkflowSpec, mock.WorkflowSpec)
Пример #25
0
 def test_get_module(self):
     self.assertEqual(loader.get_spec_module(self.spec_module_name),
                      mistral)
Пример #26
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)
Пример #27
0
def request(wf_def, ac_ex_db, st2_ctx, notify_cfg=None):
    wf_ac_ex_id = str(ac_ex_db.id)
    LOG.info('[%s] Processing action execution request for workflow.', wf_ac_ex_id)

    # Load workflow definition into workflow spec model.
    spec_module = specs_loader.get_spec_module('native')
    wf_spec = spec_module.instantiate(wf_def)

    # Inspect the workflow spec.
    inspect(wf_spec, st2_ctx, raise_exception=True)

    # Identify the action to execute.
    action_db = action_utils.get_action_by_ref(ref=ac_ex_db.action['ref'])

    if not action_db:
        error = 'Unable to find action "%s".' % ac_ex_db.action['ref']
        raise ac_exc.InvalidActionReferencedException(error)

    # Identify the runner for the action.
    runner_type_db = action_utils.get_runnertype_by_name(action_db.runner_type['name'])

    # Render action execution parameters.
    runner_params, action_params = param_utils.render_final_params(
        runner_type_db.runner_parameters,
        action_db.parameters,
        ac_ex_db.parameters,
        ac_ex_db.context
    )

    # Instantiate the workflow conductor.
    conductor_params = {'inputs': action_params, 'context': st2_ctx}
    conductor = conducting.WorkflowConductor(wf_spec, **conductor_params)

    # Serialize the conductor which initializes some internal values.
    data = conductor.serialize()

    # Create a record for workflow execution.
    wf_ex_db = wf_db_models.WorkflowExecutionDB(
        action_execution=str(ac_ex_db.id),
        spec=data['spec'],
        graph=data['graph'],
        input=data['input'],
        context=data['context'],
        state=data['state'],
        status=data['state']['status'],
        output=data['output'],
        errors=data['errors']
    )

    # Inspect that the list of tasks in the notify parameter exist in the workflow spec.
    if runner_params.get('notify'):
        invalid_tasks = list(set(runner_params.get('notify')) - set(wf_spec.tasks.keys()))

        if invalid_tasks:
            raise wf_exc.WorkflowExecutionException(
                'The following tasks in the notify parameter do not exist '
                'in the workflow definition: %s.' % ', '.join(invalid_tasks)
            )

    # Write notify instruction to record.
    if notify_cfg:
        # Set up the notify instruction in the workflow execution record.
        wf_ex_db.notify = {
            'config': notify_cfg,
            'tasks': runner_params.get('notify')
        }

    # Insert new record into the database and do not publish to the message bus yet.
    wf_ex_db = wf_db_access.WorkflowExecution.insert(wf_ex_db, publish=False)
    LOG.info('[%s] Workflow execution "%s" is created.', wf_ac_ex_id, str(wf_ex_db.id))

    # Update the context with the workflow execution id created on database insert.
    # Publish the workflow execution requested status to the message bus.
    if wf_ex_db.status not in statuses.COMPLETED_STATUSES:
        # Set the initial workflow status to requested.
        conductor.request_workflow_status(statuses.REQUESTED)
        data = conductor.serialize()
        wf_ex_db.state = data['state']
        wf_ex_db.status = data['state']['status']

        # Put the ID of the workflow execution record in the context.
        wf_ex_db.context['st2']['workflow_execution_id'] = str(wf_ex_db.id)
        wf_ex_db.state['contexts'][0]['st2']['workflow_execution_id'] = str(wf_ex_db.id)

        # Update the workflow execution record.
        wf_ex_db = wf_db_access.WorkflowExecution.update(wf_ex_db, publish=False)
        wf_db_access.WorkflowExecution.publish_status(wf_ex_db)
        msg = '[%s] Workflow execution "%s" is published.'
        LOG.info(msg, wf_ac_ex_id, str(wf_ex_db.id))
    else:
        msg = '[%s] Unable to request workflow execution. It is already in completed status "%s".'
        LOG.info(msg, wf_ac_ex_id, wf_ex_db.status)

    return wf_ex_db
Пример #28
0
 def setUp(self):
     super(SpecsUtilTest, self).setUp()
     self.spec_module = loader.get_spec_module(self.spec_module_name)
Пример #29
0
def deserialize(data):
    spec_type = data.get('catalog')
    spec_module = spec_loader.get_spec_module(spec_type)

    return spec_module.deserialize(data)
Пример #30
0
 def test_get_module(self):
     self.assertEqual(spec_loader.get_spec_module(self.spec_module_name),
                      native_specs)
Пример #31
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)
Пример #32
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)
Пример #33
0
    def test_get_spec(self):
        spec_module = loader.get_spec_module(self.spec_module_name)

        self.assertEqual(spec_module.WorkflowSpec, orquesta_specs.WorkflowSpec)
Пример #34
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)
Пример #35
0
def request(wf_def, ac_ex_db, st2_ctx, notify_cfg=None):
    wf_ac_ex_id = str(ac_ex_db.id)
    LOG.info('[%s] Processing action execution request for workflow.',
             wf_ac_ex_id)

    # Load workflow definition into workflow spec model.
    spec_module = specs_loader.get_spec_module('native')
    wf_spec = spec_module.instantiate(wf_def)

    # Inspect the workflow spec.
    inspect(wf_spec, st2_ctx, raise_exception=True)

    # Identify the action to execute.
    action_db = action_utils.get_action_by_ref(ref=ac_ex_db.action['ref'])

    if not action_db:
        error = 'Unable to find action "%s".' % ac_ex_db.action['ref']
        raise ac_exc.InvalidActionReferencedException(error)

    # Identify the runner for the action.
    runner_type_db = action_utils.get_runnertype_by_name(
        action_db.runner_type['name'])

    # Render action execution parameters.
    runner_params, action_params = param_utils.render_final_params(
        runner_type_db.runner_parameters, action_db.parameters,
        ac_ex_db.parameters, ac_ex_db.context)

    # Instantiate the workflow conductor.
    conductor_params = {'inputs': action_params, 'context': st2_ctx}
    conductor = conducting.WorkflowConductor(wf_spec, **conductor_params)

    # Serialize the conductor which initializes some internal values.
    data = conductor.serialize()

    # Create a record for workflow execution.
    wf_ex_db = wf_db_models.WorkflowExecutionDB(action_execution=str(
        ac_ex_db.id),
                                                spec=data['spec'],
                                                graph=data['graph'],
                                                input=data['input'],
                                                context=data['context'],
                                                state=data['state'],
                                                status=data['state']['status'],
                                                output=data['output'],
                                                errors=data['errors'])

    # Inspect that the list of tasks in the notify parameter exist in the workflow spec.
    if runner_params.get('notify'):
        invalid_tasks = list(
            set(runner_params.get('notify')) - set(wf_spec.tasks.keys()))

        if invalid_tasks:
            raise wf_exc.WorkflowExecutionException(
                'The following tasks in the notify parameter do not exist '
                'in the workflow definition: %s.' % ', '.join(invalid_tasks))

    # Write notify instruction to record.
    if notify_cfg:
        # Set up the notify instruction in the workflow execution record.
        wf_ex_db.notify = {
            'config': notify_cfg,
            'tasks': runner_params.get('notify')
        }

    # Insert new record into the database and do not publish to the message bus yet.
    wf_ex_db = wf_db_access.WorkflowExecution.insert(wf_ex_db, publish=False)
    LOG.info('[%s] Workflow execution "%s" is created.', wf_ac_ex_id,
             str(wf_ex_db.id))

    # Update the context with the workflow execution id created on database insert.
    # Publish the workflow execution requested status to the message bus.
    if wf_ex_db.status not in statuses.COMPLETED_STATUSES:
        # Set the initial workflow status to requested.
        conductor.request_workflow_status(statuses.REQUESTED)
        data = conductor.serialize()
        wf_ex_db.state = data['state']
        wf_ex_db.status = data['state']['status']

        # Put the ID of the workflow execution record in the context.
        wf_ex_db.context['st2']['workflow_execution_id'] = str(wf_ex_db.id)
        wf_ex_db.state['contexts'][0]['st2']['workflow_execution_id'] = str(
            wf_ex_db.id)

        # Update the workflow execution record.
        wf_ex_db = wf_db_access.WorkflowExecution.update(wf_ex_db,
                                                         publish=False)
        wf_db_access.WorkflowExecution.publish_status(wf_ex_db)
        msg = '[%s] Workflow execution "%s" is published.'
        LOG.info(msg, wf_ac_ex_id, str(wf_ex_db.id))
    else:
        msg = '[%s] Unable to request workflow execution. It is already in completed status "%s".'
        LOG.info(msg, wf_ac_ex_id, wf_ex_db.status)

    return wf_ex_db