aboutsummaryrefslogtreecommitdiffstats
path: root/keystone-moon/keystone/common/kvs/core.py
diff options
context:
space:
mode:
Diffstat (limited to 'keystone-moon/keystone/common/kvs/core.py')
-rw-r--r--keystone-moon/keystone/common/kvs/core.py66
1 files changed, 47 insertions, 19 deletions
diff --git a/keystone-moon/keystone/common/kvs/core.py b/keystone-moon/keystone/common/kvs/core.py
index 6ce7b318..064825f8 100644
--- a/keystone-moon/keystone/common/kvs/core.py
+++ b/keystone-moon/keystone/common/kvs/core.py
@@ -25,6 +25,7 @@ from dogpile.core import nameregistry
from oslo_config import cfg
from oslo_log import log
from oslo_utils import importutils
+from oslo_utils import reflection
from keystone import exception
from keystone.i18n import _
@@ -32,8 +33,8 @@ from keystone.i18n import _LI
from keystone.i18n import _LW
-__all__ = ['KeyValueStore', 'KeyValueStoreLock', 'LockTimeout',
- 'get_key_value_store']
+__all__ = ('KeyValueStore', 'KeyValueStoreLock', 'LockTimeout',
+ 'get_key_value_store')
BACKENDS_REGISTERED = False
@@ -66,6 +67,23 @@ def _register_backends():
BACKENDS_REGISTERED = True
+def sha1_mangle_key(key):
+ """Wrapper for dogpile's sha1_mangle_key.
+
+ Taken from oslo_cache.core._sha1_mangle_key
+
+ dogpile's sha1_mangle_key function expects an encoded string, so we
+ should take steps to properly handle multiple inputs before passing
+ the key through.
+ """
+ try:
+ key = key.encode('utf-8', errors='xmlcharrefreplace')
+ except (UnicodeError, AttributeError): # nosec
+ # NOTE(stevemar): if encoding fails just continue anyway.
+ pass
+ return dogpile_util.sha1_mangle_key(key)
+
+
class LockTimeout(exception.UnexpectedError):
debug_message_format = _('Lock Timeout occurred for key, %(target)s')
@@ -76,6 +94,7 @@ class KeyValueStore(object):
This manager also supports the concept of locking a given key resource to
allow for a guaranteed atomic transaction to the backend.
"""
+
def __init__(self, kvs_region):
self.locking = True
self._lock_timeout = 0
@@ -95,7 +114,6 @@ class KeyValueStore(object):
this instantiation
:param region_config_args: key-word args passed to the dogpile.cache
backend for configuration
- :return:
"""
if self.is_configured:
# NOTE(morganfainberg): It is a bad idea to reconfigure a backend,
@@ -130,12 +148,16 @@ class KeyValueStore(object):
if issubclass(pxy, proxy.ProxyBackend):
proxies.append(pxy)
else:
+ pxy_cls_name = reflection.get_class_name(
+ pxy, fully_qualified=False)
LOG.warning(_LW('%s is not a dogpile.proxy.ProxyBackend'),
- pxy.__name__)
+ pxy_cls_name)
for proxy_cls in reversed(proxies):
+ proxy_cls_name = reflection.get_class_name(
+ proxy_cls, fully_qualified=False)
LOG.info(_LI('Adding proxy \'%(proxy)s\' to KVS %(name)s.'),
- {'proxy': proxy_cls.__name__,
+ {'proxy': proxy_cls_name,
'name': self._region.name})
self._region.wrap(proxy_cls)
@@ -196,14 +218,14 @@ class KeyValueStore(object):
raise exception.ValidationError(
_('`key_mangler` option must be a function reference'))
else:
- LOG.info(_LI('Using default dogpile sha1_mangle_key as KVS '
- 'region %s key_mangler'), self._region.name)
- # NOTE(morganfainberg): Sane 'default' keymangler is the
- # dogpile sha1_mangle_key function. This ensures that unless
- # explicitly changed, we mangle keys. This helps to limit
- # unintended cases of exceeding cache-key in backends such
- # as memcache.
- self._region.key_mangler = dogpile_util.sha1_mangle_key
+ msg = _LI('Using default keystone.common.kvs.sha1_mangle_key '
+ 'as KVS region %s key_mangler')
+ LOG.info(msg, self._region.name)
+ # NOTE(morganfainberg): Use 'default' keymangler to ensure
+ # that unless explicitly changed, we mangle keys. This helps
+ # to limit unintended cases of exceeding cache-key in backends
+ # such as memcache.
+ self._region.key_mangler = sha1_mangle_key
self._set_keymangler_on_backend(self._region.key_mangler)
else:
LOG.info(_LI('KVS region %s key_mangler disabled.'),
@@ -251,6 +273,7 @@ class KeyValueStore(object):
class _LockWrapper(object):
"""weakref-capable threading.Lock wrapper."""
+
def __init__(self, lock_timeout):
self.lock = threading.Lock()
self.lock_timeout = lock_timeout
@@ -339,8 +362,9 @@ class KeyValueStore(object):
@contextlib.contextmanager
def _action_with_lock(self, key, lock=None):
- """Wrapper context manager to validate and handle the lock and lock
- timeout if passed in.
+ """Wrapper context manager.
+
+ Validates and handles the lock and lock timeout if passed in.
"""
if not isinstance(lock, KeyValueStoreLock):
# NOTE(morganfainberg): Locking only matters if a lock is passed in
@@ -362,11 +386,13 @@ class KeyValueStore(object):
class KeyValueStoreLock(object):
- """Basic KeyValueStoreLock context manager that hooks into the
- dogpile.cache backend mutex allowing for distributed locking on resources.
+ """Basic KeyValueStoreLock context manager.
- This is only a write lock, and will not prevent reads from occurring.
+ Hooks into the dogpile.cache backend mutex allowing for distributed locking
+ on resources. This is only a write lock, and will not prevent reads from
+ occurring.
"""
+
def __init__(self, mutex, key, locking_enabled=True, lock_timeout=0):
self.mutex = mutex
self.key = key
@@ -407,7 +433,9 @@ class KeyValueStoreLock(object):
def get_key_value_store(name, kvs_region=None):
- """Instantiate a new :class:`.KeyValueStore` or return a previous
+ """Retrieve key value store.
+
+ Instantiate a new :class:`.KeyValueStore` or return a previous
instantiation that has the same name.
"""
global KEY_VALUE_STORE_REGISTRY