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

st2common/st2common/persistence/keyvalue.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 __future__ import absolute_import
17
from st2common import log as logging
18
from st2common.constants.triggers import KEY_VALUE_PAIR_CREATE_TRIGGER
19
from st2common.constants.triggers import KEY_VALUE_PAIR_UPDATE_TRIGGER
20
from st2common.constants.triggers import KEY_VALUE_PAIR_VALUE_CHANGE_TRIGGER
21
from st2common.constants.triggers import KEY_VALUE_PAIR_DELETE_TRIGGER
22
from st2common.models.api.keyvalue import KeyValuePairAPI
23
from st2common.models.db.keyvalue import keyvaluepair_access
24
from st2common.models.system.common import ResourceReference
25
from st2common.persistence.base import Access
26
27
LOG = logging.getLogger(__name__)
28
29
30
class KeyValuePair(Access):
31
    impl = keyvaluepair_access
32
    publisher = None
33
34
    api_model_cls = KeyValuePairAPI
35
    dispatch_trigger_for_operations = ['create', 'update', 'value_change', 'delete']
36
    operation_to_trigger_ref_map = {
37
        'create': ResourceReference.to_string_reference(
38
            name=KEY_VALUE_PAIR_CREATE_TRIGGER['name'],
39
            pack=KEY_VALUE_PAIR_CREATE_TRIGGER['pack']),
40
        'update': ResourceReference.to_string_reference(
41
            name=KEY_VALUE_PAIR_UPDATE_TRIGGER['name'],
42
            pack=KEY_VALUE_PAIR_UPDATE_TRIGGER['pack']),
43
        'value_change': ResourceReference.to_string_reference(
44
            name=KEY_VALUE_PAIR_VALUE_CHANGE_TRIGGER['name'],
45
            pack=KEY_VALUE_PAIR_VALUE_CHANGE_TRIGGER['pack']),
46
        'delete': ResourceReference.to_string_reference(
47
            name=KEY_VALUE_PAIR_DELETE_TRIGGER['name'],
48
            pack=KEY_VALUE_PAIR_DELETE_TRIGGER['pack']),
49
    }
50
51
    @classmethod
52
    def add_or_update(cls, model_object, publish=True, dispatch_trigger=True):
0 ignored issues
show
Arguments number differs from overridden 'add_or_update' method
Loading history...
53
        """
54
        Note: We override add_or_update because we also want to publish high level "value_change"
55
        event for this resource.
56
        """
57
        if model_object.id:
58
            existing_model_object = cls.get_by_id(value=model_object.id)
59
        else:
60
            # Not an update
61
            existing_model_object = None
62
63
        model_object = super(KeyValuePair, cls).add_or_update(model_object=model_object,
64
                                                              publish=publish,
65
                                                              dispatch_trigger=dispatch_trigger)
66
67
        # Dispatch a value_change event which is specific to this resource
68
        if existing_model_object and existing_model_object.value != model_object.value:
69
            cls.dispatch_value_change_trigger(old_model_object=existing_model_object,
70
                                              new_model_object=model_object)
71
72
        return model_object
73
74
    @classmethod
75
    def dispatch_value_change_trigger(cls, old_model_object, new_model_object):
76
        operation = 'value_change'
77
        trigger = cls._get_trigger_ref_for_operation(operation=operation)
78
79
        old_object_payload = cls.api_model_cls.from_model(old_model_object,
80
                                                          mask_secrets=True).__json__()
81
        new_object_payload = cls.api_model_cls.from_model(new_model_object,
82
                                                          mask_secrets=True).__json__()
83
        payload = {
84
            'old_object': old_object_payload,
85
            'new_object': new_object_payload
86
        }
87
88
        return cls._dispatch_trigger(operation=operation, trigger=trigger, payload=payload)
89
90
    @classmethod
91
    def get_by_names(cls, names):
92
        """
93
        Retrieve KeyValuePair objects for the provided key names.
94
        """
95
        return cls.query(name__in=names)
96
97
    @classmethod
98
    def get_by_scope_and_name(cls, scope, name):
99
        """
100
        Get a key value store given a scope and name.
101
102
        :param scope: Scope which the key belongs to.
103
        :type scope: ``str``
104
105
        :param name: Name of the key.
106
        :type key: ``str``
107
108
        :rtype: :class:`KeyValuePairDB` or ``None``
109
        """
110
        query_result = cls.impl.query(scope=scope, name=name)
111
        return query_result.first() if query_result else None
112
113
    @classmethod
114
    def _get_impl(cls):
115
        return cls.impl
116
117
    @classmethod
118
    def _get_by_object(cls, object):
119
        # For KeyValuePair name is unique.
120
        name = getattr(object, 'name', '')
121
        return cls.get_by_name(name)
122