From 3ebbdec7eeb29258ae6a535562073b48d5b051d0 Mon Sep 17 00:00:00 2001 From: Clark Boylan Date: Wed, 20 Aug 2014 14:18:44 -0700 Subject: [PATCH] Handle sqlalchemy connection strings with drivers SqlAlchemy connection strings may specify a driver using the +foo suffix syntax in the url scheme. Ceilometer should accomodate this type of schema when looking up sqlalchemy drivers with the stevedore driver manager. Fix this by splitting connection string schemes on '+' and retrieving only the first element in the resulting list. Doing the entrypoint lookup on this element will preserve the existing behavior in loading sqlalchemy drivers and should be a noop for other backend types. Change-Id: Ieec5a4c47e8498a533d4e6954682a9bbe10bd4d9 Fixes-bug: 1359049 --- ceilometer/storage/__init__.py | 5 ++++- ceilometer/tests/storage/test_get_connection.py | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ceilometer/storage/__init__.py b/ceilometer/storage/__init__.py index 1d12eda68c..1766ea1048 100644 --- a/ceilometer/storage/__init__.py +++ b/ceilometer/storage/__init__.py @@ -84,7 +84,10 @@ def get_connection_from_config(conf, purpose=None): def get_connection(url, namespace): """Return an open connection to the database.""" - engine_name = urlparse.urlparse(url).scheme + connection_scheme = urlparse.urlparse(url).scheme + # SqlAlchemy connections specify may specify a 'dialect' or + # 'dialect+driver'. Handle the case where driver is specified. + engine_name = connection_scheme.split('+')[0] LOG.debug(_('looking for %(name)r driver in %(namespace)r') % ( {'name': engine_name, 'namespace': namespace})) mgr = driver.DriverManager(namespace, engine_name) diff --git a/ceilometer/tests/storage/test_get_connection.py b/ceilometer/tests/storage/test_get_connection.py index 006fb1b266..01248b38e7 100644 --- a/ceilometer/tests/storage/test_get_connection.py +++ b/ceilometer/tests/storage/test_get_connection.py @@ -23,6 +23,7 @@ from ceilometer.openstack.common.fixture import config from ceilometer.openstack.common import test from ceilometer import storage from ceilometer.storage import impl_log +from ceilometer.storage import impl_sqlalchemy import six @@ -66,3 +67,13 @@ class ConnectionConfigTest(test.BaseTestCase): self.assertIsInstance(conn, impl_log.Connection) conn = storage.get_connection_from_config(self.CONF, 'alarm') self.assertIsInstance(conn, impl_sqlalchemy_alarm.Connection) + + def test_sqlalchemy_driver(self): + self.CONF.set_override("connection", "sqlite+pysqlite://", + group="database") + conn = storage.get_connection_from_config(self.CONF) + self.assertIsInstance(conn, impl_sqlalchemy.Connection) + conn = storage.get_connection_from_config(self.CONF, 'metering') + self.assertIsInstance(conn, impl_sqlalchemy.Connection) + conn = storage.get_connection_from_config(self.CONF, 'alarm') + self.assertIsInstance(conn, impl_sqlalchemy_alarm.Connection)