Test Failed
Pull Request — master (#3398)
by Lakshmi
07:34
created

RulesEngine.handle_trigger_instance()   A

Complexity

Conditions 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
dl 0
loc 12
rs 9.4285
c 1
b 0
f 0
1
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
2
# contributor license agreements.  See the NOTICE file distributed with
3
# this work for additional information regarding copyright ownership.
4
# The ASF licenses this file to You under the Apache License, Version 2.0
5
# (the "License"); you may not use this file except in compliance with
6
# the License.  You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
16
import six
0 ignored issues
show
Unused Code introduced by
The import six seems to be unused.
Loading history...
17
18
from st2common import log as logging
19
from st2common.persistence.rule import Rule
20
from st2common.services.triggers import get_trigger_db_given_type_and_params
21
from st2common.services.triggers import get_trigger_db_by_ref
22
from st2reactor.rules.enforcer import RuleEnforcer
23
from st2reactor.rules.matcher import RulesMatcher
24
25
LOG = logging.getLogger('st2reactor.rules.RulesEngine')
26
27
28
class RulesEngine(object):
29
    def handle_trigger_instance(self, trigger_instance):
30
        # Find matching rules for trigger instance.
31
        matching_rules = self.get_matching_rules_for_trigger(trigger_instance)
32
33
        if matching_rules:
34
            # Create rule enforcers.
35
            enforcers = self.create_rule_enforcers(trigger_instance, matching_rules)
36
37
            # Enforce the rules.
38
            self.enforce_rules(enforcers)
39
        else:
40
            LOG.info('No matching rules found for trigger instance %s.', trigger_instance)
41
42
    def get_matching_rules_for_trigger(self, trigger_instance):
43
        trigger = trigger_instance.trigger
44
45
        trigger_type_with_params = False
46
47
        if getattr(trigger, 'type', None) and getattr(trigger, 'parameters', None):
48
            trigger_type_with_params = True
49
50
        LOG.info('Type(trigger) = %s', type(trigger))
51
        trigger_ptr = None
52
        if trigger_type_with_params:
53
            trigger_type = trigger.type
54
            trigger_params = trigger.parameters
55
            trigger_db = get_trigger_db_given_type_and_params(
56
                type=trigger_type,
57
                parameters=trigger_params
58
            )
59
            if trigger_db:
60
                trigger_ptr = {
61
                    'ref': trigger_db.get_reference().ref,
62
                    'type': trigger_type,
63
                    'parameters': trigger_params
64
                }
65
        else:
66
            trigger_db = get_trigger_db_by_ref(trigger_instance.trigger.ref)
67
            if trigger_db:
68
                trigger_ptr = trigger_db.get_reference().ref
69
70
71
        if not trigger_ptr:
72
            LOG.error('No matching trigger found for trigger instance %s.', trigger_instance)
73
            return None
74
75
        rules = Rule.query(trigger=trigger_ptr, enabled=True)
76
        LOG.info('Found %d rules defined for trigger %s (type=%s)', len(rules), trigger['name'],
77
                 trigger['type'])
78
        matcher = RulesMatcher(trigger_instance=trigger_instance,
79
                               trigger=trigger_db, rules=rules)
80
81
        matching_rules = matcher.get_matching_rules()
82
        LOG.info('Matched %s rule(s) for trigger_instance %s (type=%s)', len(matching_rules),
83
                 trigger['name'], trigger['type'])
84
        return matching_rules
85
86
    def create_rule_enforcers(self, trigger_instance, matching_rules):
87
        """
88
        Creates a RuleEnforcer matching to each rule.
89
90
        This method is trigger_instance specific therefore if creation of 1 RuleEnforcer
91
        fails it is likely that all wil be broken.
92
        """
93
        enforcers = []
94
        for matching_rule in matching_rules:
95
            enforcers.append(RuleEnforcer(trigger_instance, matching_rule))
96
        return enforcers
97
98
    def enforce_rules(self, enforcers):
99
        for enforcer in enforcers:
100
            try:
101
                enforcer.enforce()  # Should this happen in an eventlet pool?
102
            except:
103
                LOG.exception('Exception enforcing rule %s.', enforcer.rule)
104