diff --git a/oslo/messaging/transport.py b/oslo/messaging/transport.py index a5e496672..e61c9c260 100644 --- a/oslo/messaging/transport.py +++ b/oslo/messaging/transport.py @@ -123,7 +123,7 @@ class DriverLoadFailure(exceptions.MessagingException): self.ex = ex -def get_transport(conf, url=None, allowed_remote_exmods=[]): +def get_transport(conf, url=None, allowed_remote_exmods=[], aliases=None): """A factory method for Transport objects. This method will construct a Transport object from transport configuration @@ -150,12 +150,14 @@ def get_transport(conf, url=None, allowed_remote_exmods=[]): transport will deserialize remote exceptions from :type allowed_remote_exmods: list + :param aliases: A map of transport alias to transport name + :type aliases: dict """ conf.register_opts(_transport_opts) if not isinstance(url, TransportURL): url = url or conf.transport_url - parsed = TransportURL.parse(conf, url) + parsed = TransportURL.parse(conf, url, aliases) if not parsed.transport: raise InvalidTransportURL(url, 'No scheme specified in "%s"' % url) url = parsed @@ -220,9 +222,12 @@ class TransportURL(object): :type virtual_host: str :param hosts: a list of TransportHost objects :type hosts: list + :param aliases: A map of transport alias to transport name + :type aliases: dict """ - def __init__(self, conf, transport=None, virtual_host=None, hosts=None): + def __init__(self, conf, transport=None, virtual_host=None, hosts=None, + aliases=None): self.conf = conf self.conf.register_opts(_transport_opts) self._transport = transport @@ -231,13 +236,18 @@ class TransportURL(object): self.hosts = [] else: self.hosts = hosts + if aliases is None: + self.aliases = {} + else: + self.aliases = aliases @property def transport(self): if self._transport is None: - return self.conf.rpc_backend + transport = self.conf.rpc_backend else: - return self._transport + transport = self._transport + return self.aliases.get(transport, transport) @transport.setter def transport(self, value): @@ -300,7 +310,7 @@ class TransportURL(object): return url @classmethod - def parse(cls, conf, url): + def parse(cls, conf, url, aliases=None): """Parse an url. Assuming a URL takes the form of: @@ -337,10 +347,12 @@ class TransportURL(object): :type conf: oslo.config.cfg.ConfigOpts :param url: The URL to parse :type url: str + :param aliases: A map of transport alias to transport name + :type aliases: dict :returns: A TransportURL """ if not url: - return cls(conf) + return cls(conf, aliases=aliases) # FIXME(flaper87): Not PY3K compliant if not isinstance(url, basestring): @@ -402,4 +414,4 @@ class TransportURL(object): username=username, password=password)) - return cls(conf, url.scheme, virtual_host, hosts) + return cls(conf, url.scheme, virtual_host, hosts, aliases) diff --git a/tests/test_transport.py b/tests/test_transport.py index 317bb91b0..f16f36faf 100644 --- a/tests/test_transport.py +++ b/tests/test_transport.py @@ -55,39 +55,63 @@ class GetTransportTestCase(test_utils.BaseTestCase): scenarios = [ ('rpc_backend', dict(url=None, transport_url=None, rpc_backend='testbackend', - control_exchange=None, allowed=None, + control_exchange=None, allowed=None, aliases=None, expect=dict(backend='testbackend', exchange=None, url='testbackend:', allowed=[]))), ('transport_url', dict(url=None, transport_url='testtransport:', rpc_backend=None, - control_exchange=None, allowed=None, + control_exchange=None, allowed=None, aliases=None, expect=dict(backend='testtransport', exchange=None, url='testtransport:', allowed=[]))), ('url_param', dict(url='testtransport:', transport_url=None, rpc_backend=None, - control_exchange=None, allowed=None, + control_exchange=None, allowed=None, aliases=None, expect=dict(backend='testtransport', exchange=None, url='testtransport:', allowed=[]))), ('control_exchange', dict(url=None, transport_url=None, rpc_backend='testbackend', - control_exchange='testexchange', allowed=None, + control_exchange='testexchange', allowed=None, aliases=None, expect=dict(backend='testbackend', exchange='testexchange', url='testbackend:', allowed=[]))), ('allowed_remote_exmods', dict(url=None, transport_url=None, rpc_backend='testbackend', - control_exchange=None, allowed=['foo', 'bar'], + control_exchange=None, allowed=['foo', 'bar'], aliases=None, expect=dict(backend='testbackend', exchange=None, url='testbackend:', allowed=['foo', 'bar']))), + ('rpc_backend_aliased', + dict(url=None, transport_url=None, rpc_backend='testfoo', + control_exchange=None, allowed=None, + aliases=dict(testfoo='testbackend'), + expect=dict(backend='testbackend', + exchange=None, + url='testbackend:', + allowed=[]))), + ('transport_url_aliased', + dict(url=None, transport_url='testfoo:', rpc_backend=None, + control_exchange=None, allowed=None, + aliases=dict(testfoo='testtransport'), + expect=dict(backend='testtransport', + exchange=None, + url='testtransport:', + allowed=[]))), + ('url_param_aliased', + dict(url='testfoo:', transport_url=None, rpc_backend=None, + control_exchange=None, allowed=None, + aliases=dict(testfoo='testtransport'), + expect=dict(backend='testtransport', + exchange=None, + url='testtransport:', + allowed=[]))), ] def setUp(self): @@ -120,6 +144,8 @@ class GetTransportTestCase(test_utils.BaseTestCase): kwargs = dict(url=self.url) if self.allowed is not None: kwargs['allowed_remote_exmods'] = self.allowed + if self.aliases is not None: + kwargs['aliases'] = self.aliases transport = messaging.get_transport(self.conf, **kwargs) self.assertIsNotNone(transport) diff --git a/tests/test_urls.py b/tests/test_urls.py index 84f5a177a..1f190adf9 100644 --- a/tests/test_urls.py +++ b/tests/test_urls.py @@ -27,51 +27,54 @@ class TestParseURL(test_utils.BaseTestCase): scenarios = [ ('transport', - dict(url='foo:', + dict(url='foo:', aliases=None, + expect=dict(transport='foo'))), + ('transport_aliased', + dict(url='bar:', aliases=dict(bar='foo'), expect=dict(transport='foo'))), ('virtual_host_slash', - dict(url='foo:////', + dict(url='foo:////', aliases=None, expect=dict(transport='foo', virtual_host='/'))), ('virtual_host', - dict(url='foo:///bar', + dict(url='foo:///bar', aliases=None, expect=dict(transport='foo', virtual_host='bar'))), ('host', - dict(url='foo://host/bar', + dict(url='foo://host/bar', aliases=None, expect=dict(transport='foo', virtual_host='bar', hosts=[ dict(host='host'), ]))), ('ipv6_host', - dict(url='foo://[ffff::1]/bar', + dict(url='foo://[ffff::1]/bar', aliases=None, expect=dict(transport='foo', virtual_host='bar', hosts=[ dict(host='ffff::1'), ]))), ('port', - dict(url='foo://host:1234/bar', + dict(url='foo://host:1234/bar', aliases=None, expect=dict(transport='foo', virtual_host='bar', hosts=[ dict(host='host', port=1234), ]))), ('ipv6_port', - dict(url='foo://[ffff::1]:1234/bar', + dict(url='foo://[ffff::1]:1234/bar', aliases=None, expect=dict(transport='foo', virtual_host='bar', hosts=[ dict(host='ffff::1', port=1234), ]))), ('username', - dict(url='foo://u@host:1234/bar', + dict(url='foo://u@host:1234/bar', aliases=None, expect=dict(transport='foo', virtual_host='bar', hosts=[ dict(host='host', port=1234, username='u'), ]))), ('password', - dict(url='foo://u:p@host:1234/bar', + dict(url='foo://u:p@host:1234/bar', aliases=None, expect=dict(transport='foo', virtual_host='bar', hosts=[ @@ -79,14 +82,14 @@ class TestParseURL(test_utils.BaseTestCase): username='u', password='p'), ]))), ('creds_no_host', - dict(url='foo://u:p@/bar', + dict(url='foo://u:p@/bar', aliases=None, expect=dict(transport='foo', virtual_host='bar', hosts=[ dict(username='u', password='p'), ]))), ('multi_host', - dict(url='foo://u:p@host1:1234,host2:4321/bar', + dict(url='foo://u:p@host1:1234,host2:4321/bar', aliases=None, expect=dict(transport='foo', virtual_host='bar', hosts=[ @@ -95,7 +98,7 @@ class TestParseURL(test_utils.BaseTestCase): dict(host='host2', port=4321), ]))), ('multi_creds', - dict(url='foo://u1:p1@host1:1234,u2:p2@host2:4321/bar', + dict(url='foo://u1:p1@host1:1234,u2:p2@host2:4321/bar', aliases=None, expect=dict(transport='foo', virtual_host='bar', hosts=[ @@ -106,6 +109,7 @@ class TestParseURL(test_utils.BaseTestCase): ]))), ('multi_creds_ipv6', dict(url='foo://u1:p1@[ffff::1]:1234,u2:p2@[ffff::2]:4321/bar', + aliases=None, expect=dict(transport='foo', virtual_host='bar', hosts=[ @@ -123,7 +127,7 @@ class TestParseURL(test_utils.BaseTestCase): def test_parse_url(self): self.config(rpc_backend=None) - url = messaging.TransportURL.parse(self.conf, self.url) + url = messaging.TransportURL.parse(self.conf, self.url, self.aliases) hosts = [] for host in self.expect.get('hosts', []): @@ -147,18 +151,35 @@ class TestFormatURL(test_utils.BaseTestCase): transport=None, virtual_host=None, hosts=[], + aliases=None, + expected='testbackend:///')), + ('rpc_backend_aliased', + dict(rpc_backend='testfoo', + transport=None, + virtual_host=None, + hosts=[], + aliases=dict(testfoo='testbackend'), expected='testbackend:///')), ('transport', dict(rpc_backend=None, transport='testtransport', virtual_host=None, hosts=[], + aliases=None, + expected='testtransport:///')), + ('transport_aliased', + dict(rpc_backend=None, + transport='testfoo', + virtual_host=None, + hosts=[], + aliases=dict(testfoo='testtransport'), expected='testtransport:///')), ('virtual_host', dict(rpc_backend=None, transport='testtransport', virtual_host='/vhost', hosts=[], + aliases=None, expected='testtransport:////vhost')), ('host', dict(rpc_backend=None, @@ -170,6 +191,7 @@ class TestFormatURL(test_utils.BaseTestCase): username='bob', password='secret'), ], + aliases=None, expected='testtransport://bob:secret@host:10//')), ('multi_host', dict(rpc_backend=None, @@ -185,6 +207,7 @@ class TestFormatURL(test_utils.BaseTestCase): username='b2', password='s2'), ], + aliases=None, expected='testtransport://b1:s1@h1:1000,b2:s2@h2:2000/')), ('quoting', dict(rpc_backend=None, @@ -196,6 +219,7 @@ class TestFormatURL(test_utils.BaseTestCase): username='b$', password='s&'), ], + aliases=None, expected='testtransport://b%24:s%26@host:10//%24')), ] @@ -216,6 +240,7 @@ class TestFormatURL(test_utils.BaseTestCase): url = messaging.TransportURL(self.conf, self.transport, self.virtual_host, - hosts) + hosts, + self.aliases) self.assertEqual(str(url), self.expected)