stackstorm 24. 源碼分析之----stackstorm的rulesengine服務分析---3

目標:
弄清楚st2rulesengine服務原理

1和2的分析參見:
https://blog.csdn.net/qingyuanluofeng/article/details/105374863

3的分析參見:
https://blog.csdn.net/qingyuanluofeng/article/details/105374978

4 分析RulesEngine規則引擎
分析RulesEngine類對象的handle_trigger_instance方法
class RulesEngine(object):
    def handle_trigger_instance(self, trigger_instance):
        # Find matching rules for trigger instance.
        matching_rules = self.get_matching_rules_for_trigger(trigger_instance)

        if matching_rules:
            # Create rule enforcers.
            enforcers = self.create_rule_enforcers(trigger_instance, matching_rules)

            # Enforce the rules.
            self.enforce_rules(enforcers)
        else:
            LOG.info('No matching rules found for trigger instance %s.', trigger_instance['id'])

分析:
handle_trigger_instance(self, trigger_instance):
1 根據給定的trigger_instance,形如:
(Pdb) p trigger_instance
<TriggerInstanceDB: TriggerInstanceDB(id=5e79d4d58dc0dd00ea0f362f, occurrence_time="2020-03-24 09:31:27.463733+00:00", payload={'executed_at': '2020-03-24 09:17:33.887548+00:00', 'schedule': None}, status="processing", trigger="core.8c13d9a3-12a3-4cff-88d3-66c804a47590")>
2 調用get_matching_rules_for_trigger方法,獲得匹配的rule列表,具體是:
3 調用create_rule_enforcers(self, trigger_instance, matching_rules):
    遍歷所有匹配的rule列表,對每個rule,實例化一個RuleEnforcer(trigger_instance, matching_rule)並加入
    結果列表中,最後返回結果列表
4 調用enforce_rules(self, enforcers):
遍歷enforcers中每個enforcer,對每個enforcer,調用enforce方法,具體是

4.1) 分析get_matching_rules_for_trigger方法
class RulesEngine(object):

    def get_matching_rules_for_trigger(self, trigger_instance):
        trigger = trigger_instance.trigger

        trigger_db = get_trigger_db_by_ref(trigger_instance.trigger)

        if not trigger_db:
            LOG.error('No matching trigger found in db for trigger instance %s.', trigger_instance)
            return None

        rules = get_rules_given_trigger(trigger=trigger)

        LOG.info('Found %d rules defined for trigger %s', len(rules),
                 trigger_db.get_reference().ref)

        if len(rules) < 1:
            return rules

        matcher = RulesMatcher(trigger_instance=trigger_instance,
                               trigger=trigger_db, rules=rules)

        matching_rules = matcher.get_matching_rules()
        LOG.info('Matched %s rule(s) for trigger_instance %s (trigger=%s)', len(matching_rules),
                 trigger_instance['id'], trigger_db.ref)
        return matching_rules

分析:
get_matching_rules_for_trigger(self, trigger_instance):
1 根據給定trigger_instance中的trigger信息,形如:
(Pdb) p trigger
u'core.8c13d9a3-12a3-4cff-88d3-66c804a47590'
向trigger_d_b表查詢該trigger記錄
2 根據trigger記錄查詢到對應的rules。
原理: 由於特定的觸發器會在trigger表生成一條trigger記錄,包含ref字段。
而rule中會持有這個trigger的ref。所以通過trigger的ref可以查詢到對應的rule。
3 用trigger_instance,trigger,rules實例化一個RulesMatcher。
對rules列表處理,對每個rule根據trigger_instance,trigger等信息實例化RuleFileter對象, 調用其filter方法,
判斷其trigger_instance中的payload是否符合rule中criteria字典的校驗要求。返回匹配criteria的rules列表。


4.2) 分析enforce_rules(self, enforcers)方法
class RulesEngine(object):

    def enforce_rules(self, enforcers):
        for enforcer in enforcers:
            try:
                enforcer.enforce()  # Should this happen in an eventlet pool?
            except:
                LOG.exception('Exception enforcing rule %s.', enforcer.rule)

分析:
遍歷enforcers中每個enforcer,對每個enforcer,調用enforce方法,

4.2.1) 調用RuleEnforcer的
class RuleEnforcer(object):
    def __init__(self, trigger_instance, rule):
        self.trigger_instance = trigger_instance
        self.rule = rule

        try:
            self.data_transformer = get_transformer(trigger_instance.payload)
        except Exception as e:
            message = ('Failed to template-ize trigger payload: %s. If the payload contains '
                       'special characters such as "{{" which dont\'t reference value in '
                       'a datastore, those characters need to be escaped' % (str(e)))
            raise ValueError(message)

    def enforce(self):
        rule_spec = {'ref': self.rule.ref, 'id': str(self.rule.id), 'uid': self.rule.uid}
        enforcement_db = RuleEnforcementDB(trigger_instance_id=str(self.trigger_instance.id),
                                           rule=rule_spec)
        extra = {
            'trigger_instance_db': self.trigger_instance,
            'rule_db': self.rule
        }
        execution_db = None
        try:
            execution_db = self._do_enforce()
            # pylint: disable=no-member
            enforcement_db.execution_id = str(execution_db.id)
            extra['execution_db'] = execution_db
        except Exception as e:
            # Record the failure reason in the RuleEnforcement.
            enforcement_db.failure_reason = e.message
            LOG.exception('Failed kicking off execution for rule %s.', self.rule, extra=extra)
        finally:
            self._update_enforcement(enforcement_db)

        # pylint: disable=no-member
        if not execution_db or execution_db.status not in EXEC_KICKED_OFF_STATES:
            LOG.audit('Rule enforcement failed. Execution of Action %s failed. '
                      'TriggerInstance: %s and Rule: %s',
                      self.rule.action.ref, self.trigger_instance, self.rule,
                      extra=extra)
        else:                 
            LOG.audit('Rule enforced. Execution %s, TriggerInstance %s and Rule %s.',
                      execution_db, self.trigger_instance, self.rule, extra=extra)

        return execution_db

分析:
enforce(self):
1 根據trigger_instance_id和 rule_spec具體是一個字典,實例化一個rule_enforcement_d_b
rule_spec 樣例:{'ref': self.rule.ref, 'id': str(self.rule.id), 'uid': self.rule.uid}
2 調用_do_enforce方法,具體是:
3 指定enforcement_db的execution_id爲execution對象的id,相當於做了關聯,然後更新rule_enforcement,
4 返回execution_db,樣例如下:
<ActionExecutionDB: ActionExecutionDB(action={'name': u'mistral-network-check', 'runner_type': u'mistral-v2', 'tags': [], 'description': u'Run network check script and output the result then send email.', 'enabled': True, 'entry_point': u'workflows/mistral-network-check.yaml', 'notify': {}, 'uid': u'action:email:mistral-network-check', 'parameters': {u'email_account': {u'default': u'esdozer', u'type': u'string'}, u'cmd': {u'required': True, u'type': u'string'}, u'email_to': {u'required': True, u'type': u'array'}, u'email_from': {u'type': u'string'}, u'timeout': {u'default': 1800, u'type': u'integer'}}, 'ref': u'email.mistral-network-check', 'id': '5e8067ae146db400130967e8', 'pack': u'email'}, children=[], context={'trigger_instance': {'id': '5e81d44bb99f2a002b34aeed', 'name': None}, 'trace_context': {'id_': '5e81d44bb99f2a002b34aeee', 'trace_tag': u'st2.IntervalTimer-ac7abf3a-9966-480a-8376-1b156bdbef56'}, 'rule': {'id': '5e8067b3146db4001309686c', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e81d44cb99f2a002b34aef0, liveaction={'callback': {}, 'runner_info': {}, 'parameters': {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, 'action': u'email.mistral-network-check', 'action_is_workflow': True, 'id': '5e81d44cb99f2a002b34aeef'}, log=[{'status': 'requested', 'timestamp': datetime.datetime(2020, 3, 30, 11, 13, 16, 797752, tzinfo=tzutc())}], parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, parent=None, result={}, rule={'description': u'Check L3 vRouter & LB & DHCP', 'tags': [], 'ref': u'email.network-check', 'enabled': True, 'trigger': {'type': u'core.st2.IntervalTimer', 'ref': u'core.ac7abf3a-9966-480a-8376-1b156bdbef56', 'parameters': {u'unit': u'minutes', u'delta': 10}}, 'context': {}, 'criteria': {}, 'action': {'ref': u'email.mistral-network-check', 'parameters': {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}}, 'uid': u'rule:email:network-check', 'pack': u'email', 'type': {'ref': u'standard', 'parameters': {}}, 'id': '5e8067b3146db4001309686c', 'name': u'network-check'}, runner={'runner_module': u'mistral_v2', 'uid': u'runner_type:mistral-v2', 'name': u'mistral-v2', 'enabled': True, 'query_module': u'mistral_v2', 'runner_parameters': {u'skip_notify': {u'default': [], u'type': u'array', u'description': u'List of tasks to skip notifications for.'}, u'task': {u'type': u'string', u'description': u'The name of the task to run for reverse workflow.'}, u'context': {u'default': {}, u'type': u'object', u'description': u'Additional workflow inputs.'}, u'workflow': {u'type': u'string', u'description': u'The name of the workflow to run if the entry_point is a workbook of many workflows. The name should be in the format "<pack_name>.<action_name>.<workflow_name>". If entry point is a workflow or a workbook with a single workflow, the runner will identify the workflow automatically.'}}, 'id': '5e806772146db40013096339', 'description': u'A runner for executing mistral v2 workflow.'}, start_timestamp="2020-03-30 11:13:16.718857+00:00", status="requested", trigger={'uid': u'trigger:core:ac7abf3a-9966-480a-8376-1b156bdbef56:d561c05e470c37028940525af03d7eb5', 'parameters': {u'unit': u'minutes', u'delta': 10}, 'type': u'core.st2.IntervalTimer', 'pack': u'core', 'ref': u'core.ac7abf3a-9966-480a-8376-1b156bdbef56', 'id': '5e8160e028d08b002d5ecd0c', 'name': u'ac7abf3a-9966-480a-8376-1b156bdbef56'}, trigger_instance={'status': u'processing', 'occurrence_time': '2020-03-30T11:13:15.815000Z', 'trigger': u'core.ac7abf3a-9966-480a-8376-1b156bdbef56', 'id': '5e81d44bb99f2a002b34aeed', 'payload': {u'executed_at': u'2020-03-30 11:13:15.770559+00:00', u'schedule': None}}, trigger_type={'uid': u'trigger_type:core:st2.IntervalTimer', 'tags': [], 'parameters_schema': {u'additionalProperties': False, u'type': u'object', u'properties': {u'timezone': {u'type': u'string'}, u'unit': {u'enum': [u'weeks', u'days', u'hours', u'minutes', u'seconds'], u'required': True}, u'delta': {u'required': True, u'type': u'integer'}}}, 'name': u'st2.IntervalTimer', 'payload_schema': {u'type': u'object', u'properties': {u'executed_at': {u'default': u'2014-07-30 05:04:24.578325', u'type': u'string', u'format': u'date-time'}, u'schedule': {u'default': {u'units': u'seconds', u'delta': 30}, u'type': u'object'}}}, 'pack': u'core', 'ref': u'core.st2.IntervalTimer', 'id': '5e80674e4a20a500018b1713', 'description': u'Triggers on specified intervals. e.g. every 30s, 1week etc.'}, web_url="https://dozer-st2rulesengine-5b6cc5466-ttchq/#/history/5e81d44cb99f2a002b34aef0/general")>

4.2.2) 分析_do_enforce方法
class RuleEnforcer(object):

    def _do_enforce(self):
        params = self.get_resolved_parameters()
        LOG.info('Invoking action %s for trigger_instance %s with params %s.',
                 self.rule.action.ref, self.trigger_instance.id,
                 json.dumps(params))

        # update trace before invoking the action.
        trace_context = self._update_trace()
        LOG.debug('Updated trace %s with rule %s.', trace_context, self.rule.id)

        context = {
            'trigger_instance': reference.get_ref_from_model(self.trigger_instance),
            'rule': reference.get_ref_from_model(self.rule),
            'user': get_system_username(),
            TRACE_CONTEXT: trace_context
        }

        return RuleEnforcer._invoke_action(self.rule.action, params, context)

分析:
_do_enforce(self):
1 獲取參數字典,形如:
{u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}
2 調用 update_trace方法,具體是:
s1  調用get_trace_db_by_trigger_instance(trigger_instance=None, trigger_instance_id=None):
        根據trigger_instance的id,調用_get_single_trace_by_component(**component_filter):
        根據形如如下的參數:
        {'trigger_instances__object_id': '5e79d4d58dc0dd00ea0f362f'}
        向trace_d_b表查詢屬於該trigger_instance id的trace記錄,結果樣例如下:
        <TraceDB: TraceDB(action_executions=[], id=5e79ec278dc0dd00ea0f3630, rules=[], start_timestamp="2020-03-24 11:09:19.309179+00:00", trace_tag="st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590", trigger_instances=[<TraceComponentDB: TraceComponentDB@(object_id:5e79d4d58dc0dd00ea0f362f, updated_at:2020-03-24 11:14:41.289695+00:00)>], uid="trace:aaa8de00c846febf51ac71bd86a776c9")>
s2   更新trace記錄,設置該trace記錄的rules爲形如如下的結果
    [{'caused_by': {'type': 'trigger_instance', 'id': '5e79d4d58dc0dd00ea0f362f'}, 'ref': u'email.network-check', 'id': '5e660433c75b50001c06b822'}]
s3 返回TraceContext對象的字典
3 調用RuleEnforcer._invoke_action(self.rule.action, params, context)方法

4.2.3) 分析RuleEnforcer._invoke_action方法
class RuleEnforcer(object):

    @staticmethod
    def _invoke_action(action_exec_spec, params, context=None):
        """
        Schedule an action execution.

        :type action_exec_spec: :class:`ActionExecutionSpecDB`

        :param params: Parameters to execute the action with.
        :type params: ``dict``

        :rtype: :class:`LiveActionDB` on successful schedueling, None otherwise.
        """
        action_ref = action_exec_spec['ref']

        # prior to shipping off the params cast them to the right type.
        params = action_param_utils.cast_params(action_ref, params)
        liveaction = LiveActionDB(action=action_ref, context=context, parameters=params)
        liveaction, execution = action_service.request(liveaction)

        return execution

分析:
_invoke_action(action_exec_spec, params, context=None):
1 根據輸入參數,樣例如下:
(Pdb) p action_exec_spec
<ActionExecutionSpecDB: ActionExecutionSpecDB@71113936(ref="email.mistral-network-check", parameters="{u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}")>
(Pdb) p params
{u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}
(Pdb) p context
{'trigger_instance': {'id': '5e79d4d58dc0dd00ea0f362f', 'name': None}, 'trace_context': {'id_': '5e79ec278dc0dd00ea0f3630', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'user': '[email protected]', 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}}
2 解析獲得參數字典,形如:
{u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}
3 實例化一個LiveActionDB(action=action_ref, context=context, parameters=params)對象,形如:
<LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=False, callback={}, context={'trigger_instance': {'id': '5e79d4d58dc0dd00ea0f362f', 'name': None}, 'trace_context': {'id_': '5e79ec278dc0dd00ea0f3630', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=None, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-24 13:24:21.009098+00:00", status=None)>
4 調用/opt/stackstorm/st2/lib/python2.7/site-packages/st2common/services/action.py(155)request(liveaction)方法


4.2.4) 分析/opt/stackstorm/st2/lib/python2.7/site-packages/st2common/services/action.py的request(liveaction)方法
def request(liveaction):
    liveaction, execution = create_request(liveaction)
    liveaction, execution = publish_request(liveaction, execution)

    return liveaction, execution

分析:
request(liveaction):
1 根據輸入參數liveaction,樣例如下:
<LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=False, callback={}, context={'trigger_instance': {'id': '5e79d4d58dc0dd00ea0f362f', 'name': None}, 'trace_context': {'id_': '5e79ec278dc0dd00ea0f3630', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=None, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-24 13:24:21.009098+00:00", status=None)>
2 調用 create_request(liveaction): 創建一個action的執行,返回(liveaction, execution)
3 調用 publish_request(liveaction, execution),具體是
4 返回: liveaction, execution
樣例如下:
(Pdb) p liveaction
<LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e81d44bb99f2a002b34aeed', 'name': None}, 'trace_context': {'id_': '5e81d44bb99f2a002b34aeee', 'trace_tag': u'st2.IntervalTimer-ac7abf3a-9966-480a-8376-1b156bdbef56'}, 'rule': {'id': '5e8067b3146db4001309686c', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e81d44cb99f2a002b34aeef, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-30 11:13:16.718857+00:00", status="requested")>
(Pdb) p execution
<ActionExecutionDB: ActionExecutionDB(action={'name': u'mistral-network-check', 'runner_type': u'mistral-v2', 'tags': [], 'description': u'Run network check script and output the result then send email.', 'enabled': True, 'entry_point': u'workflows/mistral-network-check.yaml', 'notify': {}, 'uid': u'action:email:mistral-network-check', 'parameters': {u'email_account': {u'default': u'esdozer', u'type': u'string'}, u'cmd': {u'required': True, u'type': u'string'}, u'email_to': {u'required': True, u'type': u'array'}, u'email_from': {u'type': u'string'}, u'timeout': {u'default': 1800, u'type': u'integer'}}, 'ref': u'email.mistral-network-check', 'id': '5e8067ae146db400130967e8', 'pack': u'email'}, children=[], context={'trigger_instance': {'id': '5e81d44bb99f2a002b34aeed', 'name': None}, 'trace_context': {'id_': '5e81d44bb99f2a002b34aeee', 'trace_tag': u'st2.IntervalTimer-ac7abf3a-9966-480a-8376-1b156bdbef56'}, 'rule': {'id': '5e8067b3146db4001309686c', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e81d44cb99f2a002b34aef0, liveaction={'callback': {}, 'runner_info': {}, 'parameters': {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, 'action': u'email.mistral-network-check', 'action_is_workflow': True, 'id': '5e81d44cb99f2a002b34aeef'}, log=[{'status': 'requested', 'timestamp': datetime.datetime(2020, 3, 30, 11, 13, 16, 797752, tzinfo=tzutc())}], parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, parent=None, result={}, rule={'description': u'Check L3 vRouter & LB & DHCP', 'tags': [], 'ref': u'email.network-check', 'enabled': True, 'trigger': {'type': u'core.st2.IntervalTimer', 'ref': u'core.ac7abf3a-9966-480a-8376-1b156bdbef56', 'parameters': {u'unit': u'minutes', u'delta': 10}}, 'context': {}, 'criteria': {}, 'action': {'ref': u'email.mistral-network-check', 'parameters': {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}}, 'uid': u'rule:email:network-check', 'pack': u'email', 'type': {'ref': u'standard', 'parameters': {}}, 'id': '5e8067b3146db4001309686c', 'name': u'network-check'}, runner={'runner_module': u'mistral_v2', 'uid': u'runner_type:mistral-v2', 'name': u'mistral-v2', 'enabled': True, 'query_module': u'mistral_v2', 'runner_parameters': {u'skip_notify': {u'default': [], u'type': u'array', u'description': u'List of tasks to skip notifications for.'}, u'task': {u'type': u'string', u'description': u'The name of the task to run for reverse workflow.'}, u'context': {u'default': {}, u'type': u'object', u'description': u'Additional workflow inputs.'}, u'workflow': {u'type': u'string', u'description': u'The name of the workflow to run if the entry_point is a workbook of many workflows. The name should be in the format "<pack_name>.<action_name>.<workflow_name>". If entry point is a workflow or a workbook with a single workflow, the runner will identify the workflow automatically.'}}, 'id': '5e806772146db40013096339', 'description': u'A runner for executing mistral v2 workflow.'}, start_timestamp="2020-03-30 11:13:16.718857+00:00", status="requested", trigger={'uid': u'trigger:core:ac7abf3a-9966-480a-8376-1b156bdbef56:d561c05e470c37028940525af03d7eb5', 'parameters': {u'unit': u'minutes', u'delta': 10}, 'type': u'core.st2.IntervalTimer', 'pack': u'core', 'ref': u'core.ac7abf3a-9966-480a-8376-1b156bdbef56', 'id': '5e8160e028d08b002d5ecd0c', 'name': u'ac7abf3a-9966-480a-8376-1b156bdbef56'}, trigger_instance={'status': u'processing', 'occurrence_time': '2020-03-30T11:13:15.815000Z', 'trigger': u'core.ac7abf3a-9966-480a-8376-1b156bdbef56', 'id': '5e81d44bb99f2a002b34aeed', 'payload': {u'executed_at': u'2020-03-30 11:13:15.770559+00:00', u'schedule': None}}, trigger_type={'uid': u'trigger_type:core:st2.IntervalTimer', 'tags': [], 'parameters_schema': {u'additionalProperties': False, u'type': u'object', u'properties': {u'timezone': {u'type': u'string'}, u'unit': {u'enum': [u'weeks', u'days', u'hours', u'minutes', u'seconds'], u'required': True}, u'delta': {u'required': True, u'type': u'integer'}}}, 'name': u'st2.IntervalTimer', 'payload_schema': {u'type': u'object', u'properties': {u'executed_at': {u'default': u'2014-07-30 05:04:24.578325', u'type': u'string', u'format': u'date-time'}, u'schedule': {u'default': {u'units': u'seconds', u'delta': 30}, u'type': u'object'}}}, 'pack': u'core', 'ref': u'core.st2.IntervalTimer', 'id': '5e80674e4a20a500018b1713', 'description': u'Triggers on specified intervals. e.g. every 30s, 1week etc.'}, web_url="https://dozer-st2rulesengine-5b6cc5466-ttchq/#/history/5e81d44cb99f2a002b34aef0/general")>

4.2.5) 分析create_request(liveaction)方法
def create_request(liveaction):
    """
    Create an action execution.

    :return: (liveaction, execution)
    :rtype: tuple
    """
    # Use the user context from the parent action execution. Subtasks in a workflow
    # action can be invoked by a system user and so we want to use the user context
    # from the original workflow action.
    parent_context = executions.get_parent_context(liveaction)
    if parent_context:
        parent_user = parent_context.get('user', None)
        if parent_user:
            liveaction.context['user'] = parent_user

    # Validate action.
    action_db = action_utils.get_action_by_ref(liveaction.action)
    if not action_db:
        raise ValueError('Action "%s" cannot be found.' % liveaction.action)
    if not action_db.enabled:
        raise ValueError('Unable to execute. Action "%s" is disabled.' % liveaction.action)

    runnertype_db = action_utils.get_runnertype_by_name(action_db.runner_type['name'])

    if not hasattr(liveaction, 'parameters'):
        liveaction.parameters = dict()

    # Validate action parameters.
    schema = util_schema.get_schema_for_action_parameters(action_db)
    validator = util_schema.get_validator()
    util_schema.validate(liveaction.parameters, schema, validator, use_default=True,
                         allow_default_none=True)

    # validate that no immutable params are being overriden. Although possible to
    # ignore the override it is safer to inform the user to avoid surprises.
    immutables = _get_immutable_params(action_db.parameters)
    immutables.extend(_get_immutable_params(runnertype_db.runner_parameters))
    overridden_immutables = [p for p in six.iterkeys(liveaction.parameters) if p in immutables]
    if len(overridden_immutables) > 0:
        raise ValueError('Override of immutable parameter(s) %s is unsupported.'
                         % str(overridden_immutables))

    # Set notification settings for action.
    # XXX: There are cases when we don't want notifications to be sent for a particular
    # execution. So we should look at liveaction.parameters['notify']
    # and not set liveaction.notify.
    if not _is_notify_empty(action_db.notify):
        liveaction.notify = action_db.notify

    # Write to database and send to message queue.
    liveaction.status = action_constants.LIVEACTION_STATUS_REQUESTED
    liveaction.start_timestamp = date_utils.get_datetime_utc_now()

    # Set the "action_is_workflow" attribute
    liveaction.action_is_workflow = action_db.is_workflow()

    # Publish creation after both liveaction and actionexecution are created.
    liveaction = LiveAction.add_or_update(liveaction, publish=False)

    # Get trace_db if it exists. This could throw. If it throws, we have to cleanup
    # liveaction object so we don't see things in requested mode.
    trace_db = None
    try:
        _, trace_db = trace_service.get_trace_db_by_live_action(liveaction)
    except db_exc.StackStormDBObjectNotFoundError as e:
        _cleanup_liveaction(liveaction)
        raise trace_exc.TraceNotFoundException(str(e))

    execution = executions.create_execution_object(liveaction, publish=False)

    if trace_db:
        trace_service.add_or_update_given_trace_db(
            trace_db=trace_db,
            action_executions=[
                trace_service.get_trace_component_for_action_execution(execution, liveaction)
            ])

    return liveaction, execution

分析:
create_request(liveaction): 創建一個action的執行,返回(liveaction, execution)
1 根據輸入參數liveaction,樣例如下:
<LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=False, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=None, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:10:02.048723+00:00", status=None)>
2 根據liveaction.action(例如: u'email.mistral-network-check'),查詢到對應action記錄,樣例如下:
<ActionDB: ActionDB(description="Run network check script and output the result then send email.", enabled=True, entry_point="workflows/mistral-network-check.yaml", id=5e660431c75b50001c06b807, name="mistral-network-check", notify=NotifySchema@74879184(on_complete="None", on_success="None", on_failure="None"), pack="email", parameters={u'email_account': {u'default': u'esdozer', u'type': u'string'}, u'cmd': {u'required': True, u'type': u'string'}, u'email_to': {u'required': True, u'type': u'array'}, u'email_from': {u'type': u'string'}, u'timeout': {u'default': 1800, u'type': u'integer'}}, ref="email.mistral-network-check", runner_type={u'name': u'mistral-v2'}, tags=[], uid="action:email:mistral-network-check")>
3 根據action_db.runner_type['name'] (例如: u'mistral-v2'),查詢到runnertype_db,樣例如下:
<RunnerTypeDB: RunnerTypeDB(description="A runner for executing mistral v2 workflow.", enabled=True, id=5e6603dcc75b50001c06b2ec, name="mistral-v2", query_module="mistral_v2", runner_module="mistral_v2", runner_parameters={u'skip_notify': {u'default': [], u'type': u'array', u'description': u'List of tasks to skip notifications for.'}, u'task': {u'type': u'string', u'description': u'The name of the task to run for reverse workflow.'}, u'context': {u'default': {}, u'type': u'object', u'description': u'Additional workflow inputs.'}, u'workflow': {u'type': u'string', u'description': u'The name of the workflow to run if the entry_point is a workbook of many workflows. The name should be in the format "<pack_name>.<action_name>.<workflow_name>". If entry point is a workflow or a workbook with a single workflow, the runner will identify the workflow automatically.'}}, uid="runner_type:mistral-v2")>
4 根據如下代碼來向live_action_d_b表添加或更新liveaction
liveaction = LiveAction.add_or_update(liveaction, publish=False)
返回結果樣例如下:
<LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
5 獲取該liveaction的trace信息
6 調用create_execution_object方法來創建execution。具體如下:
    create_execution_object(liveaction, publish=True):
    s1 根據輸入參數,樣例如下:
    (Pdb) p liveaction
    <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
    (Pdb) p publish
    False
    s2 根據liveaction.action(例如: u'email.mistral-network-check')查詢到action信息,樣例如下:
    <ActionDB: ActionDB(description="Run network check script and output the result then send email.", enabled=True, entry_point="workflows/mistral-network-check.yaml", id=5e660431c75b50001c06b807, name="mistral-network-check", notify=NotifySchema@75062992(on_complete="None", on_success="None", on_failure="None"), pack="email", parameters={u'email_account': {u'default': u'esdozer', u'type': u'string'}, u'cmd': {u'required': True, u'type': u'string'}, u'email_to': {u'required': True, u'type': u'array'}, u'email_from': {u'type': u'string'}, u'timeout': {u'default': 1800, u'type': u'integer'}}, ref="email.mistral-network-check", runner_type={u'name': u'mistral-v2'}, tags=[], uid="action:email:mistral-network-check")>
    s3 根據action_db.runner_type['name'](例如: u'mistral-v2')查詢到runner信息,樣例如下:
    <RunnerTypeDB: RunnerTypeDB(description="A runner for executing mistral v2 workflow.", enabled=True, id=5e6603dcc75b50001c06b2ec, name="mistral-v2", query_module="mistral_v2", runner_module="mistral_v2", runner_parameters={u'skip_notify': {u'default': [], u'type': u'array', u'description': u'List of tasks to skip notifications for.'}, u'task': {u'type': u'string', u'description': u'The name of the task to run for reverse workflow.'}, u'context': {u'default': {}, u'type': u'object', u'description': u'Additional workflow inputs.'}, u'workflow': {u'type': u'string', u'description': u'The name of the workflow to run if the entry_point is a workbook of many workflows. The name should be in the format "<pack_name>.<action_name>.<workflow_name>". If entry point is a workflow or a workbook with a single workflow, the runner will identify the workflow automatically.'}}, uid="runner_type:mistral-v2")>
    s4 根據liveaction.context.get('rule', {}) (例如: {'id': '5e660433c75b50001c06b822', 'name': u'network-check'} )
    獲取rule信息,樣例如下:
    <RuleDB: RuleDB(action=ActionExecutionSpecDB@75234512(ref="email.mistral-network-check", parameters="{u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}"), context={}, criteria={}, description="Check L3 vRouter & LB & DHCP", enabled=True, id=5e660433c75b50001c06b822, name="network-check", pack="email", ref="email.network-check", tags=[], trigger="core.8c13d9a3-12a3-4cff-88d3-66c804a47590", type=RuleTypeSpecDB@75234384(ref="standard", parameters="{}"), uid="rule:email:network-check")>
    s5 根據liveaction.context.get('trigger_instance', {}) (例如: {'id': '5e7abd778dc0dd0113f02625', 'name': None} )
    的trigger_instance_id,查詢到trigger_instance信息,樣例如下:
    <TriggerInstanceDB: TriggerInstanceDB(id=5e7abd778dc0dd0113f02625, occurrence_time="2020-03-25 02:09:58.990000+00:00", payload={u'executed_at': u'2020-03-25 02:07:30.775464+00:00', u'schedule': None}, status="processing", trigger="core.8c13d9a3-12a3-4cff-88d3-66c804a47590")>
    s6 獲取parent action execution記錄,具體調用: _get_parent_execution(child_liveaction_db):
        s1 根據輸入參數,樣例如下:
        (Pdb) p child_liveaction_db
        <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
        s2 獲取 parent_context = child_liveaction_db.context.get('parent', None)信息
        s3 獲取 parent_id = parent_context['execution_id']
        s4 通過: ActionExecution.get_by_id(parent_id) 獲取 action_execution記錄並返回
    s7 根據 action, parameters, runner, rule, trigger_instance, trigger, trigger_type, parent, log等信息得到attrs字典,
    用該字典實例化得到一個ActionExecution對象,即execution。
    樣例如下:
    (Pdb) p attrs
    {'status': 'requested', 'start_timestamp': datetime.datetime(2020, 3, 25, 2, 52, 7, 783440, tzinfo=tzutc()), 'parameters': {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, 'trigger_type': {'description': u'Triggers on specified intervals. e.g. every 30s, 1week etc.', 'tags': [], 'parameters_schema': {u'additionalProperties': False, u'type': u'object', u'properties': {u'timezone': {u'type': u'string'}, u'unit': {u'enum': [u'weeks', u'days', u'hours', u'minutes', u'seconds'], u'required': True}, u'delta': {u'required': True, u'type': u'integer'}}}, 'name': u'st2.IntervalTimer', 'payload_schema': {u'type': u'object', u'properties': {u'executed_at': {u'default': u'2014-07-30 05:04:24.578325', u'type': u'string', u'format': u'date-time'}, u'schedule': {u'default': {u'units': u'seconds', u'delta': 30}, u'type': u'object'}}}, 'pack': u'core', 'ref': u'core.st2.IntervalTimer', 'id': '5e6603b9a7918a0001b8a3b3', 'uid': u'trigger_type:core:st2.IntervalTimer'}, 'runner': {'runner_module': u'mistral_v2', 'uid': u'runner_type:mistral-v2', 'description': u'A runner for executing mistral v2 workflow.', 'enabled': True, 'query_module': u'mistral_v2', 'runner_parameters': {u'skip_notify': {u'default': [], u'type': u'array', u'description': u'List of tasks to skip notifications for.'}, u'task': {u'type': u'string', u'description': u'The name of the task to run for reverse workflow.'}, u'context': {u'default': {}, u'type': u'object', u'description': u'Additional workflow inputs.'}, u'workflow': {u'type': u'string', u'description': u'The name of the workflow to run if the entry_point is a workbook of many workflows. The name should be in the format "<pack_name>.<action_name>.<workflow_name>". If entry point is a workflow or a workbook with a single workflow, the runner will identify the workflow automatically.'}}, 'id': '5e6603dcc75b50001c06b2ec', 'name': u'mistral-v2'}, 'rule': {'description': u'Check L3 vRouter & LB & DHCP', 'tags': [], 'type': SON([('ref', u'standard'), ('parameters', {})]), 'enabled': True, 'name': u'network-check', 'trigger': {'ref': u'core.8c13d9a3-12a3-4cff-88d3-66c804a47590', 'type': u'core.st2.IntervalTimer', 'parameters': {u'unit': u'minutes', u'delta': 5}}, 'context': {}, 'criteria': {}, 'action': SON([('ref', u'email.mistral-network-check'), ('parameters', {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'})]), 'pack': u'email', 'ref': u'email.network-check', 'id': '5e660433c75b50001c06b822', 'uid': u'rule:email:network-check'}, 'trigger_instance': {'status': u'processing', 'occurrence_time': '2020-03-25T02:09:58.990000Z', 'trigger': u'core.8c13d9a3-12a3-4cff-88d3-66c804a47590', 'id': '5e7abd778dc0dd0113f02625', 'payload': {u'executed_at': u'2020-03-25 02:07:30.775464+00:00', u'schedule': None}}, 'trigger': {'uid': u'trigger:core:8c13d9a3-12a3-4cff-88d3-66c804a47590:5e0acee19fa878c4fa07d596f7a893d6', 'parameters': {u'unit': u'minutes', u'delta': 5}, 'ref': u'core.8c13d9a3-12a3-4cff-88d3-66c804a47590', 'name': u'8c13d9a3-12a3-4cff-88d3-66c804a47590', 'type': u'core.st2.IntervalTimer', 'id': '5e78a2f0618fd301a43e2284', 'pack': u'core'}, 'result': {}, 'context': {'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, 'action': {'name': u'mistral-network-check', 'parameters': {u'email_account': {u'default': u'esdozer', u'type': u'string'}, u'cmd': {u'required': True, u'type': u'string'}, u'email_to': {u'required': True, u'type': u'array'}, u'email_from': {u'type': u'string'}, u'timeout': {u'default': 1800, u'type': u'integer'}}, 'tags': [], 'description': u'Run network check script and output the result then send email.', 'enabled': True, 'entry_point': u'workflows/mistral-network-check.yaml', 'notify': {}, 'uid': u'action:email:mistral-network-check', 'pack': u'email', 'ref': u'email.mistral-network-check', 'id': '5e660431c75b50001c06b807', 'runner_type': u'mistral-v2'}, 'liveaction': {'runner_info': {}, 'parameters': {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, 'action_is_workflow': True, 'callback': {}, 'action': u'email.mistral-network-check', 'id': '5e7ac84b8dc0dd0113f02627'}}
    然後得到execution.web_url,樣例如下:
    'https://dozer-st2rulesengine-dfddf8d47-7c8bw/#/history/5e7ad9048dc0dd0113f02628/general'
    並再次更新該execution記錄到數據庫中
    (Pdb) p execution
    <ActionExecutionDB: ActionExecutionDB(action={'name': u'mistral-network-check', 'runner_type': u'mistral-v2', 'tags': [], 'description': u'Run network check script and output the result then send email.', 'enabled': True, 'entry_point': u'workflows/mistral-network-check.yaml', 'notify': {}, 'uid': u'action:email:mistral-network-check', 'parameters': {u'email_account': {u'default': u'esdozer', u'type': u'string'}, u'cmd': {u'required': True, u'type': u'string'}, u'email_to': {u'required': True, u'type': u'array'}, u'email_from': {u'type': u'string'}, u'timeout': {u'default': 1800, u'type': u'integer'}}, 'ref': u'email.mistral-network-check', 'id': '5e660431c75b50001c06b807', 'pack': u'email'}, children=[], context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ad9048dc0dd0113f02628, liveaction={'callback': {}, 'runner_info': {}, 'parameters': {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, 'action': u'email.mistral-network-check', 'action_is_workflow': True, 'id': '5e7ac84b8dc0dd0113f02627'}, log=[{'status': 'requested', 'timestamp': datetime.datetime(2020, 3, 25, 4, 4, 53, 94189, tzinfo=tzutc())}], parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, parent=None, result={}, rule={'description': u'Check L3 vRouter & LB & DHCP', 'tags': [], 'ref': u'email.network-check', 'enabled': True, 'trigger': {'type': u'core.st2.IntervalTimer', 'ref': u'core.8c13d9a3-12a3-4cff-88d3-66c804a47590', 'parameters': {u'unit': u'minutes', u'delta': 5}}, 'context': {}, 'criteria': {}, 'action': {'ref': u'email.mistral-network-check', 'parameters': {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}}, 'uid': u'rule:email:network-check', 'pack': u'email', 'type': {'ref': u'standard', 'parameters': {}}, 'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, runner={'runner_module': u'mistral_v2', 'uid': u'runner_type:mistral-v2', 'name': u'mistral-v2', 'enabled': True, 'query_module': u'mistral_v2', 'runner_parameters': {u'skip_notify': {u'default': [], u'type': u'array', u'description': u'List of tasks to skip notifications for.'}, u'task': {u'type': u'string', u'description': u'The name of the task to run for reverse workflow.'}, u'context': {u'default': {}, u'type': u'object', u'description': u'Additional workflow inputs.'}, u'workflow': {u'type': u'string', u'description': u'The name of the workflow to run if the entry_point is a workbook of many workflows. The name should be in the format "<pack_name>.<action_name>.<workflow_name>". If entry point is a workflow or a workbook with a single workflow, the runner will identify the workflow automatically.'}}, 'id': '5e6603dcc75b50001c06b2ec', 'description': u'A runner for executing mistral v2 workflow.'}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested", trigger={'uid': u'trigger:core:8c13d9a3-12a3-4cff-88d3-66c804a47590:5e0acee19fa878c4fa07d596f7a893d6', 'parameters': {u'unit': u'minutes', u'delta': 5}, 'type': u'core.st2.IntervalTimer', 'pack': u'core', 'ref': u'core.8c13d9a3-12a3-4cff-88d3-66c804a47590', 'id': '5e78a2f0618fd301a43e2284', 'name': u'8c13d9a3-12a3-4cff-88d3-66c804a47590'}, trigger_instance={'status': u'processing', 'occurrence_time': '2020-03-25T02:09:58.990000Z', 'trigger': u'core.8c13d9a3-12a3-4cff-88d3-66c804a47590', 'id': '5e7abd778dc0dd0113f02625', 'payload': {u'executed_at': u'2020-03-25 02:07:30.775464+00:00', u'schedule': None}}, trigger_type={'uid': u'trigger_type:core:st2.IntervalTimer', 'tags': [], 'parameters_schema': {u'additionalProperties': False, u'type': u'object', u'properties': {u'timezone': {u'type': u'string'}, u'unit': {u'enum': [u'weeks', u'days', u'hours', u'minutes', u'seconds'], u'required': True}, u'delta': {u'required': True, u'type': u'integer'}}}, 'name': u'st2.IntervalTimer', 'payload_schema': {u'type': u'object', u'properties': {u'executed_at': {u'default': u'2014-07-30 05:04:24.578325', u'type': u'string', u'format': u'date-time'}, u'schedule': {u'default': {u'units': u'seconds', u'delta': 30}, u'type': u'object'}}}, 'pack': u'core', 'ref': u'core.st2.IntervalTimer', 'id': '5e6603b9a7918a0001b8a3b3', 'description': u'Triggers on specified intervals. e.g. every 30s, 1week etc.'}, web_url="https://dozer-st2rulesengine-dfddf8d47-7c8bw/#/history/5e7ad9048dc0dd0113f02628/general")>
    返回該execution對象
    
    附mongodb中該exeuction信息如下:
    > db.action_execution_d_b.find({"_id": ObjectId('5e7ad9048dc0dd0113f02628')}).pretty();
    {
        "_id" : ObjectId("5e7ad9048dc0dd0113f02628"),
        "trigger" : {
            "uid" : "trigger:core:8c13d9a3-12a3-4cff-88d3-66c804a47590:5e0acee19fa878c4fa07d596f7a893d6",
            "parameters" : {
                "unit" : "minutes",
                "delta" : 5
            },
            "type" : "core.st2.IntervalTimer",
            "pack" : "core",
            "ref" : "core.8c13d9a3-12a3-4cff-88d3-66c804a47590",
            "id" : "5e78a2f0618fd301a43e2284",
            "name" : "8c13d9a3-12a3-4cff-88d3-66c804a47590"
        },
        "trigger_type" : {
            "description" : "Triggers on specified intervals. e.g. every 30s, 1week etc.",
            "tags" : [ ],
            "parameters_schema" : {
                "additionalProperties" : false,
                "type" : "object",
                "properties" : {
                    "timezone" : {
                        "type" : "string"
                    },
                    "unit" : {
                        "enum" : [
                            "weeks",
                            "days",
                            "hours",
                            "minutes",
                            "seconds"
                        ],
                        "required" : true
                    },
                    "delta" : {
                        "required" : true,
                        "type" : "integer"
                    }
                }
            },
            "name" : "st2.IntervalTimer",
            "payload_schema" : {
                "type" : "object",
                "properties" : {
                    "executed_at" : {
                        "default" : "2014-07-30 05:04:24.578325",
                        "type" : "string",
                        "format" : "date-time"
                    },
                    "schedule" : {
                        "default" : {
                            "units" : "seconds",
                            "delta" : 30
                        },
                        "type" : "object"
                    }
                }
            },
            "uid" : "trigger_type:core:st2.IntervalTimer",
            "ref" : "core.st2.IntervalTimer",
            "id" : "5e6603b9a7918a0001b8a3b3",
            "pack" : "core"
        },
        "trigger_instance" : {
            "status" : "processing",
            "occurrence_time" : "2020-03-25T02:09:58.990000Z",
            "trigger" : "core.8c13d9a3-12a3-4cff-88d3-66c804a47590",
            "id" : "5e7abd778dc0dd0113f02625",
            "payload" : {
                "executed_at" : "2020-03-25 02:07:30.775464+00:00",
                "schedule" : null
            }
        },
        "rule" : {
            "description" : "Check L3 vRouter & LB & DHCP",
            "tags" : [ ],
            "ref" : "email.network-check",
            "enabled" : true,
            "trigger" : {
                "ref" : "core.8c13d9a3-12a3-4cff-88d3-66c804a47590",
                "type" : "core.st2.IntervalTimer",
                "parameters" : {
                    "unit" : "minutes",
                    "delta" : 5
                }
            },
            "context" : {
                
            },
            "criteria" : {
                
            },
            "action" : {
                "ref" : "email.mistral-network-check",
                "parameters" : {
                    "cmd" : "curl busybox:80/cmd/network/check.sh%20cn",
                    "email_to" : [
                        "[email protected]"
                    ],
                    "email_from" : "[email protected]"
                }
            },
            "uid" : "rule:email:network-check",
            "pack" : "email",
            "type" : {
                "ref" : "standard",
                "parameters" : {
                    
                }
            },
            "id" : "5e660433c75b50001c06b822",
            "name" : "network-check"
        },
        "action" : {
            "runner_type" : "mistral-v2",
            "name" : "mistral-network-check",
            "parameters" : {
                "email_account" : {
                    "default" : "esdozer",
                    "type" : "string"
                },
                "cmd" : {
                    "required" : true,
                    "type" : "string"
                },
                "email_to" : {
                    "required" : true,
                    "type" : "array"
                },
                "email_from" : {
                    "type" : "string"
                },
                "timeout" : {
                    "default" : 1800,
                    "type" : "integer"
                }
            },
            "tags" : [ ],
            "enabled" : true,
            "entry_point" : "workflows/mistral-network-check.yaml",
            "notify" : {
                
            },
            "uid" : "action:email:mistral-network-check",
            "pack" : "email",
            "ref" : "email.mistral-network-check",
            "id" : "5e660431c75b50001c06b807",
            "description" : "Run network check script and output the result then send email."
        },
        "runner" : {
            "runner_module" : "mistral_v2",
            "uid" : "runner_type:mistral-v2",
            "name" : "mistral-v2",
            "enabled" : true,
            "query_module" : "mistral_v2",
            "runner_parameters" : {
                "skip_notify" : {
                    "default" : [ ],
                    "type" : "array",
                    "description" : "List of tasks to skip notifications for."
                },
                "task" : {
                    "type" : "string",
                    "description" : "The name of the task to run for reverse workflow."
                },
                "context" : {
                    "default" : {
                        
                    },
                    "type" : "object",
                    "description" : "Additional workflow inputs."
                },
                "workflow" : {
                    "type" : "string",
                    "description" : "The name of the workflow to run if the entry_point is a workbook of many workflows. The name should be in the format \"<pack_name>.<action_name>.<workflow_name>\". If entry point is a workflow or a workbook with a single workflow, the runner will identify the workflow automatically."
                }
            },
            "id" : "5e6603dcc75b50001c06b2ec",
            "description" : "A runner for executing mistral v2 workflow."
        },
        "liveaction" : {
            "runner_info" : {
                
            },
            "parameters" : {
                "cmd" : "curl busybox:80/cmd/network/check.sh%20cn",
                "email_to" : [
                    "[email protected]"
                ],
                "email_from" : "[email protected]"
            },
            "action_is_workflow" : true,
            "callback" : {
                
            },
            "action" : "email.mistral-network-check",
            "id" : "5e7ac84b8dc0dd0113f02627"
        },
        "status" : "requested",
        "start_timestamp" : NumberLong("1585104727783440"),
        "parameters" : {
            "cmd" : "curl busybox:80/cmd/network/check.sh%20cn",
            "email_to" : [
                "[email protected]"
            ],
            "email_from" : "[email protected]"
        },
        "result" : {
            
        },
        "context" : {
            "trigger_instance" : {
                "id" : "5e7abd778dc0dd0113f02625",
                "name" : null
            },
            "trace_context" : {
                "id_" : "5e7abd798dc0dd0113f02626",
                "trace_tag" : "st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590"
            },
            "rule" : {
                "id" : "5e660433c75b50001c06b822",
                "name" : "network-check"
            },
            "user" : "[email protected]"
        },
        "children" : [ ],
        "log" : [
            {
                "status" : "requested",
                "timestamp" : ISODate("2020-03-25T04:04:53.094Z")
            }
        ]
    }

7 更新trace_db信息,具體更新:
trace_db的action_executions一個列表,樣例如下:
[{'caused_by': {'type': 'rule', 'id': '5e660433c75b50001c06b822:5e7abd778dc0dd0113f02625'}, 'ref': 'email.mistral-network-check', 'id': '5e7ad9048dc0dd0113f02628'}]
8 返回liveaction和execution,樣例如下:


4.2.6)分析 publish_request(liveaction, execution)
def publish_request(liveaction, execution):
    """
    Publish an action execution.

    :return: (liveaction, execution)
    :rtype: tuple
    """
    # Assume that this is a creation.
    LiveAction.publish_create(liveaction)
    LiveAction.publish_status(liveaction)
    ActionExecution.publish_create(execution)

    extra = {'liveaction_db': liveaction, 'execution_db': execution}
    LOG.audit('Action execution requested. LiveAction.id=%s, ActionExecution.id=%s' %
              (liveaction.id, execution.id), extra=extra)

    return liveaction, execution

分析:
publish_request(liveaction, execution):
1 根據輸入參數,樣例如下:
<LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
(Pdb) p execution
<ActionExecutionDB: ActionExecutionDB(action={'name': u'mistral-network-check', 'runner_type': u'mistral-v2', 'tags': [], 'description': u'Run network check script and output the result then send email.', 'enabled': True, 'entry_point': u'workflows/mistral-network-check.yaml', 'notify': {}, 'uid': u'action:email:mistral-network-check', 'parameters': {u'email_account': {u'default': u'esdozer', u'type': u'string'}, u'cmd': {u'required': True, u'type': u'string'}, u'email_to': {u'required': True, u'type': u'array'}, u'email_from': {u'type': u'string'}, u'timeout': {u'default': 1800, u'type': u'integer'}}, 'ref': u'email.mistral-network-check', 'id': '5e660431c75b50001c06b807', 'pack': u'email'}, children=[], context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ad9048dc0dd0113f02628, liveaction={'callback': {}, 'runner_info': {}, 'parameters': {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, 'action': u'email.mistral-network-check', 'action_is_workflow': True, 'id': '5e7ac84b8dc0dd0113f02627'}, log=[{'status': 'requested', 'timestamp': datetime.datetime(2020, 3, 25, 4, 4, 53, 94189, tzinfo=tzutc())}], parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, parent=None, result={}, rule={'description': u'Check L3 vRouter & LB & DHCP', 'tags': [], 'ref': u'email.network-check', 'enabled': True, 'trigger': {'type': u'core.st2.IntervalTimer', 'ref': u'core.8c13d9a3-12a3-4cff-88d3-66c804a47590', 'parameters': {u'unit': u'minutes', u'delta': 5}}, 'context': {}, 'criteria': {}, 'action': {'ref': u'email.mistral-network-check', 'parameters': {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}}, 'uid': u'rule:email:network-check', 'pack': u'email', 'type': {'ref': u'standard', 'parameters': {}}, 'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, runner={'runner_module': u'mistral_v2', 'uid': u'runner_type:mistral-v2', 'name': u'mistral-v2', 'enabled': True, 'query_module': u'mistral_v2', 'runner_parameters': {u'skip_notify': {u'default': [], u'type': u'array', u'description': u'List of tasks to skip notifications for.'}, u'task': {u'type': u'string', u'description': u'The name of the task to run for reverse workflow.'}, u'context': {u'default': {}, u'type': u'object', u'description': u'Additional workflow inputs.'}, u'workflow': {u'type': u'string', u'description': u'The name of the workflow to run if the entry_point is a workbook of many workflows. The name should be in the format "<pack_name>.<action_name>.<workflow_name>". If entry point is a workflow or a workbook with a single workflow, the runner will identify the workflow automatically.'}}, 'id': '5e6603dcc75b50001c06b2ec', 'description': u'A runner for executing mistral v2 workflow.'}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested", trigger={'uid': u'trigger:core:8c13d9a3-12a3-4cff-88d3-66c804a47590:5e0acee19fa878c4fa07d596f7a893d6', 'parameters': {u'unit': u'minutes', u'delta': 5}, 'type': u'core.st2.IntervalTimer', 'pack': u'core', 'ref': u'core.8c13d9a3-12a3-4cff-88d3-66c804a47590', 'id': '5e78a2f0618fd301a43e2284', 'name': u'8c13d9a3-12a3-4cff-88d3-66c804a47590'}, trigger_instance={'status': u'processing', 'occurrence_time': '2020-03-25T02:09:58.990000Z', 'trigger': u'core.8c13d9a3-12a3-4cff-88d3-66c804a47590', 'id': '5e7abd778dc0dd0113f02625', 'payload': {u'executed_at': u'2020-03-25 02:07:30.775464+00:00', u'schedule': None}}, trigger_type={'uid': u'trigger_type:core:st2.IntervalTimer', 'tags': [], 'parameters_schema': {u'additionalProperties': False, u'type': u'object', u'properties': {u'timezone': {u'type': u'string'}, u'unit': {u'enum': [u'weeks', u'days', u'hours', u'minutes', u'seconds'], u'required': True}, u'delta': {u'required': True, u'type': u'integer'}}}, 'name': u'st2.IntervalTimer', 'payload_schema': {u'type': u'object', u'properties': {u'executed_at': {u'default': u'2014-07-30 05:04:24.578325', u'type': u'string', u'format': u'date-time'}, u'schedule': {u'default': {u'units': u'seconds', u'delta': 30}, u'type': u'object'}}}, 'pack': u'core', 'ref': u'core.st2.IntervalTimer', 'id': '5e6603b9a7918a0001b8a3b3', 'description': u'Triggers on specified intervals. e.g. every 30s, 1week etc.'}, web_url="https://dozer-st2rulesengine-dfddf8d47-7c8bw/#/history/5e7ad9048dc0dd0113f02628/general")>
2 調用LiveAction.publish_create(liveaction),具體是:
     調用Access類的publish_create(cls, model_object):
    s1 根據輸入參數,樣例如下:
    <class 'st2common.persistence.liveaction.LiveAction'>
    (Pdb) p model_object
    <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
    s2 獲取到publisher,樣例如下:
    (Pdb) p publisher.__dict__
    {'_exchange': <unbound Exchange st2.liveaction(topic)>, '_state_publisher': <st2common.transport.publishers.PoolPublisher object at 0x47ce110>, '_state_exchange': <unbound Exchange st2.liveaction.status(topic)>, '_publisher': <st2common.transport.publishers.PoolPublisher object at 0x47ce110>}
    s3 調用CUDPublisher的publish_create(model_object),具體如下:
      publish_create(self, payload):
      s3.1 根據輸入參數,樣例如下:
        (Pdb) p payload
         <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
      s3.2 發送消息,指定exchange爲:
        (Pdb) p self._exchange.__dict__
        {'type': 'topic', 'arguments': None, 'name': 'st2.liveaction'}
         routing_key爲'create'
3 調用 LiveAction.publish_status(liveaction),具體是:
    調用StatusBasedResource類的publish_status(cls, model_object):
    s1 根據輸入參數,樣例如下:
        (Pdb) p model_object
        <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
    s2 獲取publisher,樣例如下:
        (Pdb) p publisher
        <st2common.transport.liveaction.LiveActionPublisher object at 0x47ce610>
        (Pdb) p publisher.__dict__
        {'_exchange': <unbound Exchange st2.liveaction(topic)>, '_state_publisher': <st2common.transport.publishers.PoolPublisher object at 0x47ce110>, '_state_exchange': <unbound Exchange st2.liveaction.status(topic)>, '_publisher': <st2common.transport.publishers.PoolPublisher object at 0x47ce110>}
    s3 調用 StatePublisherMixin類的publish_state(self, payload, state)方法發送消息,具體是
        s3.1 根據輸入參數,樣例如下:
            (Pdb) p payload
            <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
            (Pdb) p state
            'requested'
        s3.2 調用SharedPoolPublishers對象的publish方法
          exchange是: <unbound Exchange st2.liveaction.status(topic)>
          將payload發送出去,routing_key是'requested'
3 調用ActionExecution.publish_create(execution),具體是:
   execution記錄調試:
    s1 publish_create(cls, model_object):
     根據輸入參數,樣例如下:
     (Pdb) p cls
     <class 'st2common.persistence.execution.ActionExecution'>
     (Pdb) p model_object
     <ActionExecutionDB: ActionExecutionDB(action={'name': u'mistral-network-check', 'runner_type': u'mistral-v2', 'tags': [], 'description': u'Run network check script and output the result then send email.', 'enabled': True, 'entry_point': u'workflows/mistral-network-check.yaml', 'notify': {}, ......
    s2 獲取publisher,樣例如下:
      (Pdb) p publisher
        <st2common.transport.execution.ActionExecutionPublisher object at 0x3b6e690>
        (Pdb) p publisher.__dict__
        {'_exchange': <unbound Exchange st2.execution(topic)>, '_publisher': <st2common.transport.publishers.PoolPublisher object at 0x3c9e850>}
        (Pdb) p publisher._exchange.__dict__
        {'type': 'topic', 'arguments': None, 'name': 'st2.execution'}
    s3 調用 /opt/stackstorm/st2/lib/python2.7/site-packages/st2common/transport/publishers.py(92)publish_create()
      的def publish_create(self, payload)方法
       def publish_create(self, payload):
            self._publisher.publish(payload, self._exchange, CREATE_RK)
        分析: (Pdb) p CREATE_RK
              'create'
      總結: ActionExecution的publish_create方法中exchange是topic類型,exchange名稱是
          'st2.execution',routing_key是'create'
4 返回: liveaction, execution
==============================
==============================
總結規則引擎RulesEngine的流程
總入口是handle_trigger_instance(self, trigger_instance)方法,處理流程如下:
    1 根據給定的trigger_instance,形如:
    (Pdb) p trigger_instance
<TriggerInstanceDB: TriggerInstanceDB(id=5e79d4d58dc0dd00ea0f362f, occurrence_time="2020-03-24 09:31:27.463733+00:00", payload={'executed_at': '2020-03-24 09:17:33.887548+00:00', 'schedule': None}, status="processing", trigger="core.8c13d9a3-12a3-4cff-88d3-66c804a47590")>
    2 調用get_matching_rules_for_trigger方法,獲得匹配的rule列表,具體是:
        2.1 根據給定trigger_instance中的trigger信息,形如:
            (Pdb) p trigger
            u'core.8c13d9a3-12a3-4cff-88d3-66c804a47590'
          向trigger_d_b表查詢該trigger記錄
        2.2 根據trigger記錄查詢到對應的rules。
          原理: 由於特定的觸發器會在trigger表生成一條trigger記錄,包含ref字段。
          而rule中會持有這個trigger的ref。所以通過trigger的ref可以查詢到對應的rule。
        2.3 用trigger_instance,trigger,rules實例化一個RulesMatcher。
          對rules列表處理,對每個rule根據trigger_instance,trigger等信息實例化RuleFileter對象, 調用其filter方法,
          判斷其trigger_instance中的payload是否符合rule中criteria字典的校驗要求。返回匹配criteria的rules列表。
    3 調用create_rule_enforcers(self, trigger_instance, matching_rules):
            遍歷所有匹配的rule列表,對每個rule,實例化一個RuleEnforcer(trigger_instance, matching_rule)並加入
            結果列表中,最後返回結果列表
    4 調用enforce_rules(self, enforcers):
    遍歷enforcers中每個enforcer,對每個enforcer,調用enforce方法,具體是:
        enforce(self):
        1 根據trigger_instance_id和 rule_spec具體是一個字典,實例化一個rule_enforcement_d_b
         rule_spec 樣例:{'ref': self.rule.ref, 'id': str(self.rule.id), 'uid': self.rule.uid}
        2 調用_do_enforce方法,具體是:
            # Enforce the rules.
                1 獲取參數字典,形如:
                  {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}
                2 調用 update_trace方法,具體是:
                    s1  調用get_trace_db_by_trigger_instance(trigger_instance=None, trigger_instance_id=None):
                            根據trigger_instance的id,調用_get_single_trace_by_component(**component_filter):
                            根據形如如下的參數:
                            {'trigger_instances__object_id': '5e79d4d58dc0dd00ea0f362f'}
                            向trace_d_b表查詢屬於該trigger_instance id的trace記錄,結果樣例如下:
                            <TraceDB: TraceDB(action_executions=[], id=5e79ec278dc0dd00ea0f3630, rules=[], start_timestamp="2020-03-24 11:09:19.309179+00:00", trace_tag="st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590", trigger_instances=[<TraceComponentDB: TraceComponentDB@(object_id:5e79d4d58dc0dd00ea0f362f, updated_at:2020-03-24 11:14:41.289695+00:00)>], uid="trace:aaa8de00c846febf51ac71bd86a776c9")>
                    s2   更新trace記錄,設置該trace記錄的rules爲形如如下的結果
                        [{'caused_by': {'type': 'trigger_instance', 'id': '5e79d4d58dc0dd00ea0f362f'}, 'ref': u'email.network-check', 'id': '5e660433c75b50001c06b822'}]
                    s3 返回TraceContext對象的字典
                3 調用RuleEnforcer._invoke_action(self.rule.action, params, context)方法,具體是:
                            _invoke_action(action_exec_spec, params, context=None):
                            1 根據輸入參數,樣例如下:
                                (Pdb) p action_exec_spec
                        <ActionExecutionSpecDB: ActionExecutionSpecDB@71113936(ref="email.mistral-network-check", parameters="{u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}")>
                        (Pdb) p params
                        {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}
                        (Pdb) p context
                        {'trigger_instance': {'id': '5e79d4d58dc0dd00ea0f362f', 'name': None}, 'trace_context': {'id_': '5e79ec278dc0dd00ea0f3630', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'user': '[email protected]', 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}}
                            2 解析獲得參數字典,形如:
                            {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}
                            3 實例化一個LiveActionDB(action=action_ref, context=context, parameters=params)對象,形如:
                            <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=False, callback={}, context={'trigger_instance': {'id': '5e79d4d58dc0dd00ea0f362f', 'name': None}, 'trace_context': {'id_': '5e79ec278dc0dd00ea0f3630', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=None, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-24 13:24:21.009098+00:00", status=None)>
                            4 調用/opt/stackstorm/st2/lib/python2.7/site-packages/st2common/services/action.py(155)request(liveaction)方法,具體是:
                                request(liveaction):
                                    1 根據輸入參數liveaction,樣例如下:
                                    <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=False, callback={}, context={'trigger_instance': {'id': '5e79d4d58dc0dd00ea0f362f', 'name': None}, 'trace_context': {'id_': '5e79ec278dc0dd00ea0f3630', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=None, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-24 13:24:21.009098+00:00", status=None)>
                                    2 調用 create_request(liveaction): 創建一個action的執行,返回(liveaction, execution)
                                        s1 根據輸入參數liveaction,樣例如下:
                                        <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=False, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=None, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:10:02.048723+00:00", status=None)>
                                        s2 根據liveaction.action(例如: u'email.mistral-network-check'),查詢到對應action記錄,樣例如下:
                                        <ActionDB: ActionDB(description="Run network check script and output the result then send email.", enabled=True, entry_point="workflows/mistral-network-check.yaml", id=5e660431c75b50001c06b807, name="mistral-network-check", notify=NotifySchema@74879184(on_complete="None", on_success="None", on_failure="None"), pack="email", parameters={u'email_account': {u'default': u'esdozer', u'type': u'string'}, u'cmd': {u'required': True, u'type': u'string'}, u'email_to': {u'required': True, u'type': u'array'}, u'email_from': {u'type': u'string'}, u'timeout': {u'default': 1800, u'type': u'integer'}}, ref="email.mistral-network-check", runner_type={u'name': u'mistral-v2'}, tags=[], uid="action:email:mistral-network-check")>
                                        s3 根據action_db.runner_type['name'] (例如: u'mistral-v2'),查詢到runnertype_db,樣例如下:
                                        <RunnerTypeDB: RunnerTypeDB(description="A runner for executing mistral v2 workflow.", enabled=True, id=5e6603dcc75b50001c06b2ec, name="mistral-v2", query_module="mistral_v2", runner_module="mistral_v2", runner_parameters={u'skip_notify': {u'default': [], u'type': u'array', u'description': u'List of tasks to skip notifications for.'}, u'task': {u'type': u'string', u'description': u'The name of the task to run for reverse workflow.'}, u'context': {u'default': {}, u'type': u'object', u'description': u'Additional workflow inputs.'}, u'workflow': {u'type': u'string', u'description': u'The name of the workflow to run if the entry_point is a workbook of many workflows. The name should be in the format "<pack_name>.<action_name>.<workflow_name>". If entry point is a workflow or a workbook with a single workflow, the runner will identify the workflow automatically.'}}, uid="runner_type:mistral-v2")>
                                        s4 根據如下代碼來向live_action_d_b表添加或更新liveaction
                                        liveaction = LiveAction.add_or_update(liveaction, publish=False)
                                        返回結果樣例如下:
                                        <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
                                        s5 獲取該liveaction的trace信息
                                        s6 調用create_execution_object方法來創建execution。具體如下:
                                            create_execution_object(liveaction, publish=True):
                                            s6.1 根據輸入參數,樣例如下:
                                            (Pdb) p liveaction
                                            <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
                                            (Pdb) p publish
                                            False
                                            s6.2 根據liveaction.action(例如: u'email.mistral-network-check')查詢到action信息,樣例如下:
                                            <ActionDB: ActionDB(description="Run network check script and output the result then send email.", enabled=True, entry_point="workflows/mistral-network-check.yaml", id=5e660431c75b50001c06b807, name="mistral-network-check", notify=NotifySchema@75062992(on_complete="None", on_success="None", on_failure="None"), pack="email", parameters={u'email_account': {u'default': u'esdozer', u'type': u'string'}, u'cmd': {u'required': True, u'type': u'string'}, u'email_to': {u'required': True, u'type': u'array'}, u'email_from': {u'type': u'string'}, u'timeout': {u'default': 1800, u'type': u'integer'}}, ref="email.mistral-network-check", runner_type={u'name': u'mistral-v2'}, tags=[], uid="action:email:mistral-network-check")>
                                            s6.3 根據action_db.runner_type['name'](例如: u'mistral-v2')查詢到runner信息,樣例如下:
                                            <RunnerTypeDB: RunnerTypeDB(description="A runner for executing mistral v2 workflow.", enabled=True, id=5e6603dcc75b50001c06b2ec, name="mistral-v2", query_module="mistral_v2", runner_module="mistral_v2", runner_parameters={u'skip_notify': {u'default': [], u'type': u'array', u'description': u'List of tasks to skip notifications for.'}, u'task': {u'type': u'string', u'description': u'The name of the task to run for reverse workflow.'}, u'context': {u'default': {}, u'type': u'object', u'description': u'Additional workflow inputs.'}, u'workflow': {u'type': u'string', u'description': u'The name of the workflow to run if the entry_point is a workbook of many workflows. The name should be in the format "<pack_name>.<action_name>.<workflow_name>". If entry point is a workflow or a workbook with a single workflow, the runner will identify the workflow automatically.'}}, uid="runner_type:mistral-v2")>
                                            s6.4 根據liveaction.context.get('rule', {}) (例如: {'id': '5e660433c75b50001c06b822', 'name': u'network-check'} )
                                            獲取rule信息,樣例如下:
                                            <RuleDB: RuleDB(action=ActionExecutionSpecDB@75234512(ref="email.mistral-network-check", parameters="{u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}"), context={}, criteria={}, description="Check L3 vRouter & LB & DHCP", enabled=True, id=5e660433c75b50001c06b822, name="network-check", pack="email", ref="email.network-check", tags=[], trigger="core.8c13d9a3-12a3-4cff-88d3-66c804a47590", type=RuleTypeSpecDB@75234384(ref="standard", parameters="{}"), uid="rule:email:network-check")>
                                            s6.5 根據liveaction.context.get('trigger_instance', {}) (例如: {'id': '5e7abd778dc0dd0113f02625', 'name': None} )
                                            的trigger_instance_id,查詢到trigger_instance信息,樣例如下:
                                            <TriggerInstanceDB: TriggerInstanceDB(id=5e7abd778dc0dd0113f02625, occurrence_time="2020-03-25 02:09:58.990000+00:00", payload={u'executed_at': u'2020-03-25 02:07:30.775464+00:00', u'schedule': None}, status="processing", trigger="core.8c13d9a3-12a3-4cff-88d3-66c804a47590")>
                                            s6.6 獲取parent action execution記錄,具體調用: _get_parent_execution(child_liveaction_db):
                                                A1 根據輸入參數,樣例如下:
                                                (Pdb) p child_liveaction_db
                                                <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
                                                A2 獲取 parent_context = child_liveaction_db.context.get('parent', None)信息
                                                A3 獲取 parent_id = parent_context['execution_id']
                                                A4 通過: ActionExecution.get_by_id(parent_id) 獲取 action_execution記錄並返回
                                            s6.7 根據 action, parameters, runner, rule, trigger_instance, trigger, trigger_type, parent, log等信息得到attrs字典,
                                            用該字典實例化得到一個ActionExecution對象,即execution。
                                            樣例如下:
                                            然後得到execution.web_url,樣例如下:
                                            'https://dozer-st2rulesengine-dfddf8d47-7c8bw/#/history/5e7ad9048dc0dd0113f02628/general'
                                            並再次更新該execution記錄到數據庫中
                                            返回該execution對象
                                        s7 更新trace_db信息,具體更新:
                                        trace_db的action_executions一個列表,樣例如下:
                                        [{'caused_by': {'type': 'rule', 'id': '5e660433c75b50001c06b822:5e7abd778dc0dd0113f02625'}, 'ref': 'email.mistral-network-check', 'id': '5e7ad9048dc0dd0113f02628'}]
                                        s8 返回liveaction和execution,樣例如下:
                                    3 調用 publish_request(liveaction, execution),具體是
                                        s1 根據輸入參數,樣例如下:
                                        s2 調用LiveAction.publish_create(liveaction),具體是:
                                             調用Access類的publish_create(cls, model_object):
                                            s2.1 根據輸入參數,樣例如下:
                                            <class 'st2common.persistence.liveaction.LiveAction'>
                                            (Pdb) p model_object
                                            <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
                                            s2.2 獲取到publisher,樣例如下:
                                            (Pdb) p publisher.__dict__
                                            {'_exchange': <unbound Exchange st2.liveaction(topic)>, '_state_publisher': <st2common.transport.publishers.PoolPublisher object at 0x47ce110>, '_state_exchange': <unbound Exchange st2.liveaction.status(topic)>, '_publisher': <st2common.transport.publishers.PoolPublisher object at 0x47ce110>}
                                            s2.3 調用CUDPublisher的publish_create(model_object),具體如下:
                                              publish_create(self, payload):
                                              s2.3.1 根據輸入參數,樣例如下:
                                                (Pdb) p payload
                                                 <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
                                              s2.3.2 發送消息,指定exchange爲:
                                                (Pdb) p self._exchange.__dict__
                                                {'type': 'topic', 'arguments': None, 'name': 'st2.liveaction'}
                                                 routing_key爲'create'
                                        s3 調用 LiveAction.publish_status(liveaction),具體是:
                                            調用StatusBasedResource類的publish_status(cls, model_object):
                                            s3.1 根據輸入參數,樣例如下:
                                                (Pdb) p model_object
                                                <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
                                            s3.2 獲取publisher,樣例如下:
                                                (Pdb) p publisher
                                                <st2common.transport.liveaction.LiveActionPublisher object at 0x47ce610>
                                                (Pdb) p publisher.__dict__
                                                {'_exchange': <unbound Exchange st2.liveaction(topic)>, '_state_publisher': <st2common.transport.publishers.PoolPublisher object at 0x47ce110>, '_state_exchange': <unbound Exchange st2.liveaction.status(topic)>, '_publisher': <st2common.transport.publishers.PoolPublisher object at 0x47ce110>}
                                            s3.3 調用 StatePublisherMixin類的publish_state(self, payload, state)方法發送消息,具體是
                                                s3.3.1 根據輸入參數,樣例如下:
                                                    (Pdb) p payload
                                                    <LiveActionDB: LiveActionDB(action="email.mistral-network-check", action_is_workflow=True, callback={}, context={'trigger_instance': {'id': '5e7abd778dc0dd0113f02625', 'name': None}, 'trace_context': {'id_': '5e7abd798dc0dd0113f02626', 'trace_tag': u'st2.IntervalTimer-8c13d9a3-12a3-4cff-88d3-66c804a47590'}, 'rule': {'id': '5e660433c75b50001c06b822', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e7ac84b8dc0dd0113f02627, notify=None, parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, result={}, runner_info={}, start_timestamp="2020-03-25 02:52:07.783440+00:00", status="requested")>
                                                    (Pdb) p state
                                                    'requested'
                                                s3.3.2 調用SharedPoolPublishers對象的publish方法
                                                  exchange是: <unbound Exchange st2.liveaction.status(topic)>
                                                  將payload發送出去,routing_key是'requested'
                                        s4 調用ActionExecution.publish_create(execution),具體是:
                                           execution記錄調試:
                                            s4.1 publish_create(cls, model_object):
                                             根據輸入參數,樣例如下:
                                             (Pdb) p cls
                                             <class 'st2common.persistence.execution.ActionExecution'>
                                             (Pdb) p model_object
                                             <ActionExecutionDB: ActionExecutionDB(action={'name': u'mistral-network-check', 'runner_type': u'mistral-v2', 'tags': [], 'description': u'Run network check script and output the result then send email.', 'enabled': True, 'entry_point': u'workflows/mistral-network-check.yaml', 'notify': {}, 'uid': u'action:email:mistral-network-check', 'parameters': {u'email_account': {u'default': u'esdozer', u'type': u'string'}, u'cmd': {u'required': True, u'type': u'string'}, u'email_to': {u'required': True, u'type': u'array'}, u'email_from': {u'type': u'string'}, u'timeout': {u'default': 1800, u'type': u'integer'}}, 'ref': u'email.mistral-network-check', 'id': '5e8067ae146db400130967e8', 'pack': u'email'}, children=[], context={'trigger_instance': {'id': '5e81d44bb99f2a002b34aeed', 'name': None}, 'trace_context': {'id_': '5e81d44bb99f2a002b34aeee', 'trace_tag': u'st2.IntervalTimer-ac7abf3a-9966-480a-8376-1b156bdbef56'}, 'rule': {'id': '5e8067b3146db4001309686c', 'name': u'network-check'}, 'user': '[email protected]'}, end_timestamp=None, id=5e81d44cb99f2a002b34aef0, liveaction={'callback': {}, 'runner_info': {}, 'parameters': {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, 'action': u'email.mistral-network-check', 'action_is_workflow': True, 'id': '5e81d44cb99f2a002b34aeef'}, log=[{'status': 'requested', 'timestamp': datetime.datetime(2020, 3, 30, 11, 13, 16, 797752, tzinfo=tzutc())}], parameters={u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}, parent=None, result={}, rule={'description': u'Check L3 vRouter & LB & DHCP', 'tags': [], 'ref': u'email.network-check', 'enabled': True, 'trigger': {'type': u'core.st2.IntervalTimer', 'ref': u'core.ac7abf3a-9966-480a-8376-1b156bdbef56', 'parameters': {u'unit': u'minutes', u'delta': 10}}, 'context': {}, 'criteria': {}, 'action': {'ref': u'email.mistral-network-check', 'parameters': {u'cmd': u'curl busybox:80/cmd/network/check.sh%20cn', u'email_to': [u'[email protected]'], u'email_from': u'[email protected]'}}, 'uid': u'rule:email:network-check', 'pack': u'email', 'type': {'ref': u'standard', 'parameters': {}}, 'id': '5e8067b3146db4001309686c', 'name': u'network-check'}, runner={'runner_module': u'mistral_v2', 'uid': u'runner_type:mistral-v2', 'name': u'mistral-v2', 'enabled': True, 'query_module': u'mistral_v2', 'runner_parameters': {u'skip_notify': {u'default': [], u'type': u'array', u'description': u'List of tasks to skip notifications for.'}, u'task': {u'type': u'string', u'description': u'The name of the task to run for reverse workflow.'}, u'context': {u'default': {}, u'type': u'object', u'description': u'Additional workflow inputs.'}, u'workflow': {u'type': u'string', u'description': u'The name of the workflow to run if the entry_point is a workbook of many workflows. The name should be in the format "<pack_name>.<action_name>.<workflow_name>". If entry point is a workflow or a workbook with a single workflow, the runner will identify the workflow automatically.'}}, 'id': '5e806772146db40013096339', 'description': u'A runner for executing mistral v2 workflow.'}, start_timestamp="2020-03-30 11:13:16.718857+00:00", status="requested", trigger={'uid': u'trigger:core:ac7abf3a-9966-480a-8376-1b156bdbef56:d561c05e470c37028940525af03d7eb5', 'parameters': {u'unit': u'minutes', u'delta': 10}, 'type': u'core.st2.IntervalTimer', 'pack': u'core', 'ref': u'core.ac7abf3a-9966-480a-8376-1b156bdbef56', 'id': '5e8160e028d08b002d5ecd0c', 'name': u'ac7abf3a-9966-480a-8376-1b156bdbef56'}, trigger_instance={'status': u'processing', 'occurrence_time': '2020-03-30T11:13:15.815000Z', 'trigger': u'core.ac7abf3a-9966-480a-8376-1b156bdbef56', 'id': '5e81d44bb99f2a002b34aeed', 'payload': {u'executed_at': u'2020-03-30 11:13:15.770559+00:00', u'schedule': None}}, trigger_type={'uid': u'trigger_type:core:st2.IntervalTimer', 'tags': [], 'parameters_schema': {u'additionalProperties': False, u'type': u'object', u'properties': {u'timezone': {u'type': u'string'}, u'unit': {u'enum': [u'weeks', u'days', u'hours', u'minutes', u'seconds'], u'required': True}, u'delta': {u'required': True, u'type': u'integer'}}}, 'name': u'st2.IntervalTimer', 'payload_schema': {u'type': u'object', u'properties': {u'executed_at': {u'default': u'2014-07-30 05:04:24.578325', u'type': u'string', u'format': u'date-time'}, u'schedule': {u'default': {u'units': u'seconds', u'delta': 30}, u'type': u'object'}}}, 'pack': u'core', 'ref': u'core.st2.IntervalTimer', 'id': '5e80674e4a20a500018b1713', 'description': u'Triggers on specified intervals. e.g. every 30s, 1week etc.'}, web_url="https://dozer-st2rulesengine-5b6cc5466-ttchq/#/history/5e81d44cb99f2a002b34aef0/general")>
                                            s4.2 獲取publisher,樣例如下:
                                              (Pdb) p publisher
                                                <st2common.transport.execution.ActionExecutionPublisher object at 0x3b6e690>
                                                (Pdb) p publisher.__dict__
                                                {'_exchange': <unbound Exchange st2.execution(topic)>, '_publisher': <st2common.transport.publishers.PoolPublisher object at 0x3c9e850>}
                                                (Pdb) p publisher._exchange.__dict__
                                                {'type': 'topic', 'arguments': None, 'name': 'st2.execution'}
                                            s4.3 調用 /opt/stackstorm/st2/lib/python2.7/site-packages/st2common/transport/publishers.py(92)publish_create()
                                              的def publish_create(self, payload)方法
                                               def publish_create(self, payload):
                                                    self._publisher.publish(payload, self._exchange, CREATE_RK)
                                                分析: (Pdb) p CREATE_RK
                                                      'create'
                                              總結: ActionExecution的publish_create方法中exchange是topic類型,exchange名稱是
                                                  'st2.execution',routing_key是'create'
                                    4 返回: liveaction, execution
                            5 返回execution,樣例如下:
        3 指定enforcement_db的execution_id爲execution對象的id,相當於做了關聯,然後更新rule_enforcement,
        4 返回execution_db,樣例如下:


參考:
stackstorm 2.6代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章