Test Failed
Push — master ( e380d0...f5671d )
by W
02:58
created

st2api/st2api/controllers/v1/timers.py (1 issue)

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 six import iteritems
17
from six.moves import http_client
18
19
from st2api.controllers import resource
20
from st2common import log as logging
21
from st2common.constants.triggers import TIMER_TRIGGER_TYPES
22
from st2common.models.api.trigger import TriggerAPI
23
from st2common.models.system.common import ResourceReference
24
from st2common.persistence.trigger import Trigger
25
from st2common.models.db.timer import TimerDB
26
from st2common.rbac.types import PermissionType
27
from st2common.rbac import utils as rbac_utils
28
from st2common.services import triggers as trigger_service
29
from st2common.services.triggerwatcher import TriggerWatcher
30
from st2common.router import abort
31
32
__all__ = [
33
    'TimersController',
34
    'TimersHolder'
35
]
36
37
38
LOG = logging.getLogger(__name__)
39
40
41
class TimersHolder(object):
42
43
    def __init__(self):
44
        self._timers = {}
45
46
    def add_trigger(self, ref, trigger):
47
        self._timers[ref] = trigger
48
49
    def remove_trigger(self, ref, trigger):
50
        del self._timers[ref]
51
52
    def get_all(self, timer_type=None):
53
        timer_triggers = []
54
55
        for _, timer in iteritems(self._timers):
56
            if not timer_type or timer['type'] == timer_type:
57
                timer_triggers.append(timer)
58
59
        return timer_triggers
60
61
62
class TimersController(resource.ContentPackResourceController):
63
    model = TriggerAPI
64
    access = Trigger
65
66
    supported_filters = {
67
        'type': 'type',
68
    }
69
70
    query_options = {
71
        'sort': ['type']
72
    }
73
74
    def __init__(self):
0 ignored issues
show
The __init__ method of the super-class ContentPackResourceController is not called.

It is generally advisable to initialize the super-class by calling its __init__ method:

class SomeParent:
    def __init__(self):
        self.x = 1

class SomeChild(SomeParent):
    def __init__(self):
        # Initialize the super class
        SomeParent.__init__(self)
Loading history...
75
        self._timers = TimersHolder()
76
        self._trigger_types = TIMER_TRIGGER_TYPES.keys()
77
        queue_suffix = self.__class__.__name__
78
        self._trigger_watcher = TriggerWatcher(create_handler=self._handle_create_trigger,
79
                                               update_handler=self._handle_update_trigger,
80
                                               delete_handler=self._handle_delete_trigger,
81
                                               trigger_types=self._trigger_types,
82
                                               queue_suffix=queue_suffix,
83
                                               exclusive=True)
84
        self._trigger_watcher.start()
85
        self._register_timer_trigger_types()
86
        self._allowed_timer_types = TIMER_TRIGGER_TYPES.keys()
87
88
    def get_all(self, timer_type=None):
89
        if timer_type and timer_type not in self._allowed_timer_types:
90
            msg = 'Timer type %s not in supported types - %s.' % (timer_type,
91
                                                                  self._allowed_timer_types)
92
            abort(http_client.BAD_REQUEST, msg)
93
94
        t_all = self._timers.get_all(timer_type=timer_type)
95
        LOG.debug('Got timers: %s', t_all)
96
        return t_all
97
98
    def get_one(self, ref_or_id, requester_user):
99
        try:
100
            trigger_db = self._get_by_ref_or_id(ref_or_id=ref_or_id)
101
        except Exception as e:
102
            LOG.exception(e.message)
103
            abort(http_client.NOT_FOUND, e.message)
104
            return
105
106
        permission_type = PermissionType.TIMER_VIEW
107
        resource_db = TimerDB(pack=trigger_db.pack, name=trigger_db.name)
108
        rbac_utils.assert_user_has_resource_db_permission(user_db=requester_user,
109
                                                          resource_db=resource_db,
110
                                                          permission_type=permission_type)
111
112
        result = self.model.from_model(trigger_db)
113
        return result
114
115
    def add_trigger(self, trigger):
116
        # Note: Permission checking for creating and deleting a timer is done during rule
117
        # creation
118
        ref = self._get_timer_ref(trigger)
119
        LOG.info('Started timer %s with parameters %s', ref, trigger['parameters'])
120
        self._timers.add_trigger(ref, trigger)
121
122
    def update_trigger(self, trigger):
123
        pass
124
125
    def remove_trigger(self, trigger):
126
        # Note: Permission checking for creating and deleting a timer is done during rule
127
        # creation
128
        ref = self._get_timer_ref(trigger)
129
130
        removed = self._timers.remove_trigger(ref, trigger)
131
        if removed:
132
            LOG.info('Stopped timer %s with parameters %s.', ref, trigger['parameters'])
133
134
    def _register_timer_trigger_types(self):
135
        for trigger_type in TIMER_TRIGGER_TYPES.values():
136
            trigger_service.create_trigger_type_db(trigger_type)
137
138
    def _get_timer_ref(self, trigger):
139
        return ResourceReference.to_string_reference(pack=trigger['pack'], name=trigger['name'])
140
141
    ##############################################
142
    # Event handler methods for the trigger events
143
    ##############################################
144
145
    def _handle_create_trigger(self, trigger):
146
        LOG.debug('Calling "add_trigger" method (trigger.type=%s)' % (trigger.type))
147
        trigger = self._sanitize_trigger(trigger=trigger)
148
        self.add_trigger(trigger=trigger)
149
150
    def _handle_update_trigger(self, trigger):
151
        LOG.debug('Calling "update_trigger" method (trigger.type=%s)' % (trigger.type))
152
        trigger = self._sanitize_trigger(trigger=trigger)
153
        self.update_trigger(trigger=trigger)
154
155
    def _handle_delete_trigger(self, trigger):
156
        LOG.debug('Calling "remove_trigger" method (trigger.type=%s)' % (trigger.type))
157
        trigger = self._sanitize_trigger(trigger=trigger)
158
        self.remove_trigger(trigger=trigger)
159
160
    def _sanitize_trigger(self, trigger):
161
        sanitized = TriggerAPI.from_model(trigger).to_dict()
162
        return sanitized
163
164
165
timers_controller = TimersController()
166