Add transport aliases
We need to support deprecated transport driver configurations like: rpc_backend = nova.rpc.impl_kombu i.e. 'nova.rpc.impl_kombu' is a deprecated alias for 'rabbit'. Initially, we supported this by adding the aliases to each project's setup.cfg: oslo.messaging.drivers = nova.rpc.impl_kombu = oslo.messaging._drivers.impl_rabbit:RabbitDriver However, this means that code like this: url = str(TransportURL(conf)) generates a bogus URL string like: nova.rpc.impl_kombu://... We need to apply these transport aliases when we load drivers, but also when we create transport URLs from configuration containing potentially deprecated aliases. To enable that, add an aliases parameter to TransportURL(), TransportURL.parse() and get_transport(). blueprint: transport-aliases Change-Id: Ifce68ff62746c2a363c719417a2bd0a78ee025dd
This commit is contained in:
parent
f9ab2e105f
commit
5b8fbdcad2
@ -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)
|
||||
|
@ -54,39 +54,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):
|
||||
@ -119,6 +143,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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user