Add support for multiple namespaces in Targets
In order for projects to use the namespace property of Targets in a backwards compatible way (To support rolling upgrades), a Target may now belong to more than a single namespace (i.e. 'namespace1' and None). This way, if the server is upgraded first, the version that introduces namespaces to a project will place the server RPC methods in ['some_namespace', None]. Pre-upgrade agents will send messages in the null namespace while post-upgrade agents will send messages in 'some_namespace', and both will be accepted. Change-Id: I713fe9228111c36aa3f7fb95cbd59c99100e8c96 Closes-Bug: #1430984
This commit is contained in:
parent
8836d3e43c
commit
3be95adceb
@ -111,7 +111,7 @@ class RPCDispatcher(object):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _is_namespace(target, namespace):
|
def _is_namespace(target, namespace):
|
||||||
return namespace == target.namespace
|
return namespace in target.accepted_namespaces
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _is_compatible(target, version):
|
def _is_compatible(target, version):
|
||||||
|
@ -57,16 +57,23 @@ class Target(object):
|
|||||||
servers listening on a topic by setting fanout to ``True``, rather than
|
servers listening on a topic by setting fanout to ``True``, rather than
|
||||||
just one of them.
|
just one of them.
|
||||||
:type fanout: bool
|
:type fanout: bool
|
||||||
|
:param legacy_namespaces: A server always accepts messages specified via
|
||||||
|
the 'namespace' parameter, and may also accept messages defined via
|
||||||
|
this parameter. This option should be used to switch namespaces safely
|
||||||
|
during rolling upgrades.
|
||||||
|
:type legacy_namespaces: list of strings
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, exchange=None, topic=None, namespace=None,
|
def __init__(self, exchange=None, topic=None, namespace=None,
|
||||||
version=None, server=None, fanout=None):
|
version=None, server=None, fanout=None,
|
||||||
|
legacy_namespaces=None):
|
||||||
self.exchange = exchange
|
self.exchange = exchange
|
||||||
self.topic = topic
|
self.topic = topic
|
||||||
self.namespace = namespace
|
self.namespace = namespace
|
||||||
self.version = version
|
self.version = version
|
||||||
self.server = server
|
self.server = server
|
||||||
self.fanout = fanout
|
self.fanout = fanout
|
||||||
|
self.accepted_namespaces = [namespace] + (legacy_namespaces or [])
|
||||||
|
|
||||||
def __call__(self, **kwargs):
|
def __call__(self, **kwargs):
|
||||||
for a in ('exchange', 'topic', 'namespace',
|
for a in ('exchange', 'topic', 'namespace',
|
||||||
|
@ -89,6 +89,18 @@ class TestDispatcher(test_utils.BaseTestCase):
|
|||||||
dispatch_to=None,
|
dispatch_to=None,
|
||||||
ctxt={}, msg=dict(method='foo', version='3.2'),
|
ctxt={}, msg=dict(method='foo', version='3.2'),
|
||||||
success=False, ex=oslo_messaging.UnsupportedVersion)),
|
success=False, ex=oslo_messaging.UnsupportedVersion)),
|
||||||
|
('message_in_null_namespace_with_multiple_namespaces',
|
||||||
|
dict(endpoints=[dict(namespace='testns',
|
||||||
|
legacy_namespaces=[None])],
|
||||||
|
dispatch_to=dict(endpoint=0, method='foo'),
|
||||||
|
ctxt={}, msg=dict(method='foo', namespace=None),
|
||||||
|
success=True, ex=None)),
|
||||||
|
('message_in_wrong_namespace_with_multiple_namespaces',
|
||||||
|
dict(endpoints=[dict(namespace='testns',
|
||||||
|
legacy_namespaces=['second', None])],
|
||||||
|
dispatch_to=None,
|
||||||
|
ctxt={}, msg=dict(method='foo', namespace='wrong'),
|
||||||
|
success=False, ex=oslo_messaging.UnsupportedVersion)),
|
||||||
]
|
]
|
||||||
|
|
||||||
def test_dispatcher(self):
|
def test_dispatcher(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user