1 # Licensed to the Apache Software Foundation (ASF) 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
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
17 Storage API management.
21 from contextlib import contextmanager
23 from aria.logger import LoggerMixin
24 from . import sql_mapi
33 class Storage(LoggerMixin):
35 Base class for storage managers.
42 initiator_kwargs=None,
45 :param api_cls: API class for each entry
47 :param items: items to register
48 :param initiator: function which initializes the storage before the first use; this function
49 should return a dict, this dict would be passed in addition to the API kwargs; this enables
50 the creation of non-serializable objects
51 :param initiator_kwargs:
54 super(Storage, self).__init__(**kwargs)
57 self._initiator = initiator
58 self._initiator_kwargs = initiator_kwargs or {}
59 self._api_kwargs = api_kwargs or {}
60 self._additional_api_kwargs = {}
62 self._additional_api_kwargs = self._initiator(**self._initiator_kwargs)
65 self.logger.debug('{name} object is ready: {0!r}'.format(
66 self, name=self.__class__.__name__))
69 def _all_api_kwargs(self):
70 kwargs = self._api_kwargs.copy()
71 kwargs.update(self._additional_api_kwargs)
75 return '{name}(api={self.api})'.format(name=self.__class__.__name__, self=self)
77 def __getattr__(self, item):
79 return self.registered[item]
81 return super(Storage, self).__getattribute__(item)
84 def serialization_dict(self):
87 'api_kwargs': self._api_kwargs,
88 'initiator': self._initiator,
89 'initiator_kwargs': self._initiator_kwargs
92 def register(self, entry):
98 raise NotImplementedError('Subclass must implement abstract register method')
101 class ResourceStorage(Storage):
103 Manages storage resource APIs ("RAPIs").
105 def register(self, name):
107 Register a storage resource API ("RAPI").
111 self.registered[name] = self.api(name=name, **self._all_api_kwargs)
112 self.registered[name].create()
113 self.logger.debug('setup {name} in storage {self!r}'.format(name=name, self=self))
116 class ModelStorage(Storage):
118 Manages storage model APIs ("MAPIs").
120 def __init__(self, *args, **kwargs):
121 if kwargs.get('initiator', None) is None:
122 kwargs['initiator'] = sql_mapi.init_storage
123 super(ModelStorage, self).__init__(*args, **kwargs)
125 def register(self, model_cls):
127 Register a storage model API ("MAPI").
129 :param model_cls: model API to register
131 model_name = model_cls.__modelname__
132 if model_name in self.registered:
133 self.logger.debug('{name} already in storage {self!r}'.format(name=model_name,
136 self.registered[model_name] = self.api(name=model_name,
138 **self._all_api_kwargs)
139 self.registered[model_name].create()
140 self.logger.debug('setup {name} in storage {self!r}'.format(name=model_name, self=self))
146 for mapi in self.registered.itervalues():
150 def instrument(self, *instrumentation):
151 original_instrumentation = {}
154 for mapi in self.registered.itervalues():
155 original_instrumentation[mapi] = copy.copy(mapi._instrumentation)
156 mapi._instrumentation.extend(instrumentation)
159 for mapi in self.registered.itervalues():
160 mapi._instrumentation[:] = original_instrumentation[mapi]