Completed
Pull Request — master (#2290)
by Manas
05:20
created

st2reactor.rules.RuleTester._get_rule_db()   A

Complexity

Conditions 3

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 7
rs 9.4286
cc 3
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 os
17
18
from st2common import log as logging
19
from st2common.content.loader import MetaLoader
20
from st2common.models.db.rule import RuleDB
21
from st2common.models.db.trigger import TriggerDB
22
from st2common.models.db.trigger import TriggerInstanceDB
23
from st2common.models.system.common import ResourceReference
24
from st2common.persistence.reactor import Rule, TriggerInstance, Trigger
25
26
from st2reactor.rules.matcher import RulesMatcher
27
28
__all__ = [
29
    'RuleTester'
30
]
31
32
LOG = logging.getLogger(__name__)
33
34
35
class RuleTester(object):
36
    def __init__(self, rule_file_path=None, rule_ref=None, trigger_instance_file_path=None,
37
                 trigger_instance_id=None):
38
        """
39
        :param rule_file_path: Path to the file containing rule definition.
40
        :type rule_file_path: ``str``
41
42
        :param trigger_instance_file_path: Path to the file containg trigger instance definition.
43
        :type trigger_instance_file_path: ``str``
44
        """
45
        self._rule_file_path = rule_file_path
46
        self._rule_ref = rule_ref
47
        self._trigger_instance_file_path = trigger_instance_file_path
48
        self._trigger_instance_id = trigger_instance_id
49
        self._meta_loader = MetaLoader()
50
51
    def evaluate(self):
52
        """
53
        Evaluate trigger instance against the rule.
54
55
        :return: ``True`` if the rule matches, ``False`` otherwise.
56
        :rtype: ``boolean``
57
        """
58
59
        rule_db = self._get_rule_db()
60
        trigger_instance_db, trigger_db = self._get_trigger_instance_db()
61
62
        # The trigger check needs to be performed here as that is not performed
63
        # by RulesMatcher.
64
        if rule_db.trigger != trigger_db.ref:
65
            LOG.info('rule.trigger "%s" and trigger.ref "%s" do not match.',
66
                     rule_db.trigger, trigger_db.ref)
67
            return False
68
69
        matcher = RulesMatcher(trigger_instance=trigger_instance_db, trigger=trigger_db,
70
                               rules=[rule_db], extra_info=True)
71
        matching_rules = matcher.get_matching_rules()
72
73
        return len(matching_rules) >= 1
74
75
    def _get_rule_db(self):
76
        if self._rule_file_path:
77
            return self._get_rule_db_from_file(
78
                file_path=os.path.realpath(self._rule_file_path))
79
        elif self._rule_ref:
80
            return Rule.get_by_ref(self._rule_ref)
81
        raise ValueError('One of _rule_file_path or _rule_ref should be specified.')
82
83
    def _get_trigger_instance_db(self):
84
        if self._trigger_instance_file_path:
85
            return self._get_trigger_instance_db_from_file(
86
                file_path=os.path.realpath(self._trigger_instance_file_path))
87
        elif self._trigger_instance_id:
88
            trigger_instance_db = TriggerInstance.get_by_id(self._trigger_instance_id)
89
            trigger_db = Trigger.get_by_ref(trigger_instance_db.trigger)
90
            return trigger_instance_db, trigger_db
91
        raise ValueError('One of _trigger_instance_file_path or'
92
                         '_trigger_instance_id should be specified.')
93
94
    def _get_rule_db_from_file(self, file_path):
95
        data = self._meta_loader.load(file_path=file_path)
96
        pack = data.get('pack', 'unknown')
97
        name = data.get('name', 'unknown')
98
        trigger = data['trigger']['type']
99
        criteria = data.get('criteria', None)
100
101
        rule_db = RuleDB(pack=pack, name=name, trigger=trigger, criteria=criteria, action={},
102
                         enabled=True)
103
        return rule_db
104
105
    def _get_trigger_instance_db_from_file(self, file_path):
106
        data = self._meta_loader.load(file_path=file_path)
107
        instance = TriggerInstanceDB(**data)
108
109
        trigger_ref = ResourceReference.from_string_reference(instance['trigger'])
110
        trigger_db = TriggerDB(pack=trigger_ref.pack, name=trigger_ref.name, type=trigger_ref.ref)
111
        return instance, trigger_db
112