Passed
Pull Request — master (#3398)
by Lakshmi
05:34
created

RulesEngine.enforce_rules()   A

Complexity

Conditions 3

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
dl 0
loc 6
rs 9.4285
c 0
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
from st2common import log as logging
17
from st2common.services.rules import get_rules_given_trigger
18
from st2common.services.triggers import get_trigger_db_given_type_and_params
19
from st2common.services.triggers import get_trigger_db_by_ref
20
from st2reactor.rules.enforcer import RuleEnforcer
21
from st2reactor.rules.matcher import RulesMatcher
22
23
LOG = logging.getLogger('st2reactor.rules.RulesEngine')
24
25
26
class RulesEngine(object):
27
    def handle_trigger_instance(self, trigger_instance):
28
        # Find matching rules for trigger instance.
29
        matching_rules = self.get_matching_rules_for_trigger(trigger_instance)
30
31
        if matching_rules:
32
            # Create rule enforcers.
33
            enforcers = self.create_rule_enforcers(trigger_instance, matching_rules)
34
35
            # Enforce the rules.
36
            self.enforce_rules(enforcers)
37
        else:
38
            LOG.info('No matching rules found for trigger instance %s.', trigger_instance['id'])
39
40
    def get_matching_rules_for_trigger(self, trigger_instance):
41
        trigger = trigger_instance.trigger
42
43
        trigger_type_with_params = False
44
45
        if trigger.get('type', None) and trigger.get('parameters', None):
46
            trigger_type_with_params = True
47
48
        if trigger_type_with_params:
49
            trigger_type = trigger['type']
50
            trigger_params = trigger['parameters']
51
            trigger_db = get_trigger_db_given_type_and_params(
52
                type=trigger_type,
53
                parameters=trigger_params
54
            )
55
            if trigger_db:
56
                rules = get_rules_given_trigger(trigger=trigger)
57
        else:
58
            trigger_db = get_trigger_db_by_ref(trigger_instance.trigger.get('ref'))
59
            if trigger_db:
60
                rules = get_rules_given_trigger(trigger=trigger)
61
62
        if not trigger_db:
63
            LOG.error('No matching trigger found in db for trigger instance %s.', trigger_instance)
64
            return None
65
66
        LOG.info('Found %d rules defined for trigger %s', len(rules), trigger['ref'])
67
68
        if len(rules) < 1:
69
            return rules
70
71
        matcher = RulesMatcher(trigger_instance=trigger_instance,
72
                               trigger=trigger_db, rules=rules)
73
74
        matching_rules = matcher.get_matching_rules()
75
        LOG.info('Matched %s rule(s) for trigger_instance %s (trigger=%s)', len(matching_rules),
76
                 trigger_instance['id'], trigger_db.ref)
77
        return matching_rules
78
79
    def create_rule_enforcers(self, trigger_instance, matching_rules):
80
        """
81
        Creates a RuleEnforcer matching to each rule.
82
83
        This method is trigger_instance specific therefore if creation of 1 RuleEnforcer
84
        fails it is likely that all wil be broken.
85
        """
86
        enforcers = []
87
        for matching_rule in matching_rules:
88
            enforcers.append(RuleEnforcer(trigger_instance, matching_rule))
89
        return enforcers
90
91
    def enforce_rules(self, enforcers):
92
        for enforcer in enforcers:
93
            try:
94
                enforcer.enforce()  # Should this happen in an eventlet pool?
95
            except:
96
                LOG.exception('Exception enforcing rule %s.', enforcer.rule)
97