Passed
Push — master ( 2fdf18...019a6d )
by Lakshmi
04:12 queued 01:19
created

RulesEngine.handle_trigger_instance()   A

Complexity

Conditions 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

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