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:
		| @@ -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): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Assaf Muller
					Assaf Muller