diff --git a/oslo/messaging/_drivers/impl_fake.py b/oslo/messaging/_drivers/impl_fake.py index 96b4e5b8e..db78d8add 100644 --- a/oslo/messaging/_drivers/impl_fake.py +++ b/oslo/messaging/_drivers/impl_fake.py @@ -22,7 +22,7 @@ import time from oslo import messaging from oslo.messaging._drivers import base -from oslo.messaging import _utils as utils +from oslo.messaging import _urls as urls class InvalidTarget(base.TransportDriverError, ValueError): @@ -102,7 +102,7 @@ class FakeDriver(base.BaseDriver): def __init__(self, conf, url=None, default_exchange=None): super(FakeDriver, self).__init__(conf, url, default_exchange) - self._default_exchange = utils.exchange_from_url(url, default_exchange) + self._default_exchange = urls.exchange_from_url(url, default_exchange) self._exchanges_lock = threading.Lock() self._exchanges = {} diff --git a/oslo/messaging/_urls.py b/oslo/messaging/_urls.py new file mode 100644 index 000000000..7b8f6ee77 --- /dev/null +++ b/oslo/messaging/_urls.py @@ -0,0 +1,139 @@ + +# Copyright 2013 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import urlparse + + +def parse_url(url, default_exchange=None): + """Parse an url. + + Assuming a URL takes the form of: + + transport://user:pass@host1:port[,hostN:portN]/exchange[?opt=val] + + then parse the URL and return a dictionary with the following structure: + + { + 'exchange': 'exchange' + 'transport': 'transport', + 'hosts': [{'username': 'username', + 'password': 'password' + 'host': 'host1:port1'}, + ...], + 'parameters': {'option': 'value'} + } + + Netloc is parsed following the sequence bellow: + + * It is first splitted by ',' in order to support multiple hosts + * The last parsed username and password will be propagated to the rest + of hotsts specified: + + user:passwd@host1:port1,host2:port2 + + [ + {"username": "user", "password": "passwd", "host": "host1:port1"}, + {"username": "user", "password": "passwd", "host": "host2:port2"} + ] + + * In order to avoid the above propagation, it is possible to alter the + order in which the hosts are specified or specify a set of fake credentials + using ",:@host2:port2" + + + user:passwd@host1:port1,:@host2:port2 + + [ + {"username": "user", "password": "passwd", "host": "host1:port1"}, + {"username": "", "password": "", "host": "host2:port2"} + ] + + :param url: The URL to parse + :type url: str + :param default_exchange: what to return if no exchange found in URL + :type default_exchange: str + :returns: A dictionary with the parsed data + """ + + # NOTE(flaper87): Not PY3K compliant + if not isinstance(url, basestring): + raise TypeError("Wrong URL type") + + url = urlparse.urlparse(url) + + parsed = dict(transport=url.scheme) + + # NOTE(flaper87): Set the exchange. + # if it is / or None then use the + # default one. + exchange = default_exchange + if url.path and url.path != "/": + exchange = url.path[1:].split("/")[0] + parsed["exchange"] = exchange + + # NOTE(flaper87): Parse netloc. + hosts = [] + username = password = '' + for host in url.netloc.split(","): + if not host: + continue + + if "@" in host: + creds, host = host.split("@") + username, password = creds.split(":") + + hosts.append({ + "host": host, + "username": username, + "password": password, + }) + + parsed["hosts"] = hosts + + parameters = {} + if url.query: + # NOTE(flaper87): This returns a dict with + # key -> [value], those values need to be + # normalized + parameters = urlparse.parse_qs(url.query) + parsed['parameters'] = parameters + + return parsed + + +def exchange_from_url(url, default_exchange=None): + """Parse an exchange name from a URL. + + Assuming a URL takes the form of: + + transport:///myexchange + + then parse the URL and return the exchange name. + + :param url: the URL to parse + :type url: str + :param default_exchange: what to return if no exchange found in URL + :type default_exchange: str + """ + if not url: + return default_exchange + + url = urlparse.urlparse(url) + if not url.path.startswith('/'): + return default_exchange + + parts = url.path[1:].split('/') + + return parts[0] if parts[0] else default_exchange diff --git a/oslo/messaging/_utils.py b/oslo/messaging/_utils.py index d3850b4e2..fcbfd1f1c 100644 --- a/oslo/messaging/_utils.py +++ b/oslo/messaging/_utils.py @@ -1,7 +1,4 @@ -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. # Copyright 2013 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -16,8 +13,6 @@ # License for the specific language governing permissions and limitations # under the License. -import urlparse - def version_is_compatible(imp_version, version): """Determine whether versions are compatible. @@ -32,126 +27,3 @@ def version_is_compatible(imp_version, version): if int(version_parts[1]) > int(imp_version_parts[1]): # Minor return False return True - - -def parse_url(url, default_exchange=None): - """Parse an url. - - Assuming a URL takes the form of: - - transport://user:pass@host1:port[,hostN:portN]/exchange[?opt=val] - - then parse the URL and return a dictionary with the following structure: - - { - 'exchange': 'exchange' - 'transport': 'transport', - 'hosts': [{'username': 'username', - 'password': 'password' - 'host': 'host1:port1'}, - ...], - 'parameters': {'option': 'value'} - } - - Netloc is parsed following the sequence bellow: - - * It is first splitted by ',' in order to support multiple hosts - * The last parsed username and password will be propagated to the rest - of hotsts specified: - - user:passwd@host1:port1,host2:port2 - - [ - {"username": "user", "password": "passwd", "host": "host1:port1"}, - {"username": "user", "password": "passwd", "host": "host2:port2"} - ] - - * In order to avoid the above propagation, it is possible to alter the - order in which the hosts are specified or specify a set of fake credentials - using ",:@host2:port2" - - - user:passwd@host1:port1,:@host2:port2 - - [ - {"username": "user", "password": "passwd", "host": "host1:port1"}, - {"username": "", "password": "", "host": "host2:port2"} - ] - - :param url: The URL to parse - :type url: str - :param default_exchange: what to return if no exchange found in URL - :type default_exchange: str - :returns: A dictionary with the parsed data - """ - - # NOTE(flaper87): Not PY3K compliant - if not isinstance(url, basestring): - raise TypeError("Wrong URL type") - - url = urlparse.urlparse(url) - - parsed = dict(transport=url.scheme) - - # NOTE(flaper87): Set the exchange. - # if it is / or None then use the - # default one. - exchange = default_exchange - if url.path and url.path != "/": - exchange = url.path[1:].split("/")[0] - parsed["exchange"] = exchange - - # NOTE(flaper87): Parse netloc. - hosts = [] - username = password = '' - for host in url.netloc.split(","): - if not host: - continue - - if "@" in host: - creds, host = host.split("@") - username, password = creds.split(":") - - hosts.append({ - "host": host, - "username": username, - "password": password, - }) - - parsed["hosts"] = hosts - - parameters = {} - if url.query: - # NOTE(flaper87): This returns a dict with - # key -> [value], those values need to be - # normalized - parameters = urlparse.parse_qs(url.query) - parsed['parameters'] = parameters - - return parsed - - -def exchange_from_url(url, default_exchange=None): - """Parse an exchange name from a URL. - - Assuming a URL takes the form of: - - transport:///myexchange - - then parse the URL and return the exchange name. - - :param url: the URL to parse - :type url: str - :param default_exchange: what to return if no exchange found in URL - :type default_exchange: str - """ - if not url: - return default_exchange - - url = urlparse.urlparse(url) - if not url.path.startswith('/'): - return default_exchange - - parts = url.path[1:].split('/') - - return parts[0] if parts[0] else default_exchange