diff --git a/ceilometer/api/app.py b/ceilometer/api/app.py index 49ceacfb0..4aa6fbf6c 100644 --- a/ceilometer/api/app.py +++ b/ceilometer/api/app.py @@ -58,7 +58,7 @@ def setup_app(pecan_config=None, extra_hooks=None): # FIXME: Replace DBHook with a hooks.TransactionHook app_hooks = [hooks.ConfigHook(), hooks.DBHook( - storage.get_connection(cfg.CONF), + storage.get_connection_from_config(cfg.CONF), ), hooks.PipelineHook(), hooks.TranslationHook()] diff --git a/ceilometer/api/v1/app.py b/ceilometer/api/v1/app.py index 9c496d937..c76cd444e 100644 --- a/ceilometer/api/v1/app.py +++ b/ceilometer/api/v1/app.py @@ -53,7 +53,7 @@ def make_app(conf, attach_storage=True, @app.before_request def attach_storage(): flask.request.storage_conn = \ - storage.get_connection(conf) + storage.get_connection_from_config(conf) return app diff --git a/ceilometer/cli.py b/ceilometer/cli.py index 2a24441a2..b4934d883 100644 --- a/ceilometer/cli.py +++ b/ceilometer/cli.py @@ -108,14 +108,14 @@ def collector_service(): def storage_dbsync(): service.prepare_service() - storage.get_connection(cfg.CONF).upgrade() + storage.get_connection_from_config(cfg.CONF).upgrade() def storage_expirer(): service.prepare_service() if cfg.CONF.database.time_to_live > 0: LOG.debug(_("Clearing expired metering data")) - storage_conn = storage.get_connection(cfg.CONF) + storage_conn = storage.get_connection_from_config(cfg.CONF) storage_conn.clear_expired_metering_data( cfg.CONF.database.time_to_live) else: diff --git a/ceilometer/dispatcher/database.py b/ceilometer/dispatcher/database.py index 76fe5c4cb..45382bf35 100644 --- a/ceilometer/dispatcher/database.py +++ b/ceilometer/dispatcher/database.py @@ -39,7 +39,7 @@ class DatabaseDispatcher(dispatcher.Base): ''' def __init__(self, conf): super(DatabaseDispatcher, self).__init__(conf) - self.storage_conn = storage.get_connection(conf) + self.storage_conn = storage.get_connection_from_config(conf) def record_metering_data(self, data): # We may have receive only one counter on the wire diff --git a/ceilometer/storage/__init__.py b/ceilometer/storage/__init__.py index afb12370e..c04eeab75 100644 --- a/ceilometer/storage/__init__.py +++ b/ceilometer/storage/__init__.py @@ -67,24 +67,24 @@ class StorageBadAggregate(Exception): code = 400 -def _get_engine(conf): - """Load the configured engine and return an instance.""" +def get_connection_from_config(conf): if conf.database_connection: conf.set_override('connection', conf.database_connection, group='database') - engine_name = urlparse.urlparse(conf.database.connection).scheme + return get_connection(conf.database.connection) + + +def get_connection(url): + """Return an open connection to the database.""" + engine_name = urlparse.urlparse(url).scheme LOG.debug(_('looking for %(name)r driver in %(namespace)r') % ( {'name': engine_name, 'namespace': STORAGE_ENGINE_NAMESPACE})) mgr = driver.DriverManager(STORAGE_ENGINE_NAMESPACE, engine_name, invoke_on_load=True) - return mgr.driver - -def get_connection(conf): - """Return an open connection to the database.""" - return _get_engine(conf).get_connection(conf) + return mgr.driver.get_connection(url) class SampleFilter(object): diff --git a/ceilometer/storage/base.py b/ceilometer/storage/base.py index dd5382af2..0789d53d7 100644 --- a/ceilometer/storage/base.py +++ b/ceilometer/storage/base.py @@ -111,8 +111,8 @@ class StorageEngine(object): """Base class for storage engines.""" @abc.abstractmethod - def get_connection(self, conf): - """Return a Connection instance based on the configuration settings.""" + def get_connection(self, url): + """Return a Connection instance based on the url.""" class Connection(object): @@ -156,7 +156,7 @@ class Connection(object): 'events': {'query': {'simple': False}}, } - def __init__(self, conf): + def __init__(self, url): """Constructor.""" pass diff --git a/ceilometer/storage/impl_db2.py b/ceilometer/storage/impl_db2.py index a14ab88fc..3d6f15e6e 100644 --- a/ceilometer/storage/impl_db2.py +++ b/ceilometer/storage/impl_db2.py @@ -69,10 +69,10 @@ class DB2Storage(base.StorageEngine): } """ - def get_connection(self, conf): - """Return a Connection instance based on the configuration settings. + def get_connection(self, url): + """Return a Connection instance based on the url. """ - return Connection(conf) + return Connection(url) AVAILABLE_CAPABILITIES = { @@ -114,8 +114,7 @@ class Connection(pymongo_base.Connection): SECONDS_IN_A_DAY = 86400 - def __init__(self, conf): - url = conf.database.connection + def __init__(self, url): # Since we are using pymongo, even though we are connecting to DB2 # we still have to make sure that the scheme which used to distinguish diff --git a/ceilometer/storage/impl_hbase.py b/ceilometer/storage/impl_hbase.py index da579fb1a..e42a8427b 100644 --- a/ceilometer/storage/impl_hbase.py +++ b/ceilometer/storage/impl_hbase.py @@ -88,10 +88,10 @@ class HBaseStorage(base.StorageEngine): """ @staticmethod - def get_connection(conf): + def get_connection(url): """Return a Connection instance based on the configuration settings. """ - return Connection(conf) + return Connection(url) AVAILABLE_CAPABILITIES = { @@ -122,9 +122,9 @@ class Connection(base.Connection): ALARM_TABLE = "alarm" ALARM_HISTORY_TABLE = "alarm_h" - def __init__(self, conf): + def __init__(self, url): """Hbase Connection Initialization.""" - opts = self._parse_connection_url(conf.database.connection) + opts = self._parse_connection_url(url) if opts['host'] == '__test__': url = os.environ.get('CEILOMETER_TEST_HBASE_URL') diff --git a/ceilometer/storage/impl_log.py b/ceilometer/storage/impl_log.py index ea621ae30..ecf6c3dda 100644 --- a/ceilometer/storage/impl_log.py +++ b/ceilometer/storage/impl_log.py @@ -29,10 +29,10 @@ class LogStorage(base.StorageEngine): """Log the data """ - def get_connection(self, conf): - """Return a Connection instance based on the configuration settings. + def get_connection(self, url): + """Return a Connection instance based on the url. """ - return Connection(conf) + return Connection(url) class Connection(base.Connection): diff --git a/ceilometer/storage/impl_mongodb.py b/ceilometer/storage/impl_mongodb.py index 83a1eb035..f6db44571 100644 --- a/ceilometer/storage/impl_mongodb.py +++ b/ceilometer/storage/impl_mongodb.py @@ -76,10 +76,10 @@ class MongoDBStorage(base.StorageEngine): } """ - def get_connection(self, conf): - """Return a Connection instance based on the configuration settings. + def get_connection(self, url): + """Return a Connection instance based on the url. """ - return Connection(conf) + return Connection(url) AVAILABLE_CAPABILITIES = { @@ -409,8 +409,7 @@ class Connection(pymongo_base.Connection): _APOCALYPSE = datetime.datetime(year=datetime.MAXYEAR, month=12, day=31, hour=23, minute=59, second=59) - def __init__(self, conf): - url = conf.database.connection + def __init__(self, url): # NOTE(jd) Use our own connection pooling on top of the Pymongo one. # We need that otherwise we overflow the MongoDB instance with new diff --git a/ceilometer/storage/impl_sqlalchemy.py b/ceilometer/storage/impl_sqlalchemy.py index ac4cfb9b4..e1f47a280 100644 --- a/ceilometer/storage/impl_sqlalchemy.py +++ b/ceilometer/storage/impl_sqlalchemy.py @@ -97,10 +97,10 @@ class SQLAlchemyStorage(base.StorageEngine): """ @staticmethod - def get_connection(conf): - """Return a Connection instance based on the configuration settings. + def get_connection(url): + """Return a Connection instance based on the url. """ - return Connection(conf) + return Connection(url) META_TYPE_MAP = {bool: models.MetaBool, @@ -242,9 +242,11 @@ class Connection(base.Connection): CAPABILITIES = utils.update_nested(base.Connection.CAPABILITIES, AVAILABLE_CAPABILITIES) - def __init__(self, conf): + def __init__(self, url): self._engine_facade = sqlalchemy_session.EngineFacade.from_config( - conf.database.connection, cfg.CONF) + url, + cfg.CONF # TODO(Alexei_987) Remove access to global CONF object + ) def upgrade(self): path = os.path.join(os.path.abspath(os.path.dirname(__file__)), diff --git a/ceilometer/tests/db.py b/ceilometer/tests/db.py index d0a8b2c0a..7e1e36ee0 100644 --- a/ceilometer/tests/db.py +++ b/ceilometer/tests/db.py @@ -40,15 +40,13 @@ class TestBase(testscenarios.testcase.WithScenarios, test_base.BaseTestCase): self.useFixture(self.db_manager) self.CONF = self.useFixture(config.Config()).conf - self.CONF.set_override('connection', self.db_manager.connection, - group='database') with warnings.catch_warnings(): warnings.filterwarnings( action='ignore', message='.*you must provide a username and password.*') try: - self.conn = storage.get_connection(self.CONF) + self.conn = storage.get_connection(self.db_manager.connection) except storage.StorageBadVersion as e: self.skipTest(six.text_type(e)) self.conn.upgrade() diff --git a/ceilometer/tests/storage/test_get_connection.py b/ceilometer/tests/storage/test_get_connection.py index 83e78cbe6..7cd4bde67 100644 --- a/ceilometer/tests/storage/test_get_connection.py +++ b/ceilometer/tests/storage/test_get_connection.py @@ -18,8 +18,6 @@ """Tests for ceilometer/storage/ """ -import mock - from ceilometer.openstack.common import test from ceilometer import storage from ceilometer.storage import impl_log @@ -28,15 +26,11 @@ from ceilometer.storage import impl_log class EngineTest(test.BaseTestCase): def test_get_connection(self): - conf = mock.Mock() - conf.database.connection = 'log://localhost' - engine = storage.get_connection(conf) + engine = storage.get_connection('log://localhost') self.assertIsInstance(engine, impl_log.Connection) def test_get_connection_no_such_engine(self): - conf = mock.Mock() - conf.database.connection = 'no-such-engine://localhost' try: - storage.get_connection(conf) + storage.get_connection('no-such-engine://localhost') except RuntimeError as err: self.assertIn('no-such-engine', unicode(err)) diff --git a/ceilometer/tests/storage/test_impl_hbase.py b/ceilometer/tests/storage/test_impl_hbase.py index 12113b195..35aba93e9 100644 --- a/ceilometer/tests/storage/test_impl_hbase.py +++ b/ceilometer/tests/storage/test_impl_hbase.py @@ -38,8 +38,7 @@ class HBaseEngineTestBase(tests_db.TestBase): class ConnectionTest(HBaseEngineTestBase): def test_hbase_connection(self): - self.CONF.database.connection = self.db_manager.connection - conn = hbase.Connection(self.CONF) + conn = hbase.Connection(self.db_manager.connection) self.assertIsInstance(conn.conn_pool.connection(), hbase.MConnection) class TestConn(object): @@ -52,10 +51,9 @@ class ConnectionTest(HBaseEngineTestBase): def get_connection_pool(conf): return TestConn(conf['host'], conf['port']) - self.CONF.database.connection = 'hbase://test_hbase:9090' with patch.object(hbase.Connection, '_get_connection_pool', side_effect=get_connection_pool): - conn = hbase.Connection(self.CONF) + conn = hbase.Connection('hbase://test_hbase:9090') self.assertIsInstance(conn.conn_pool, TestConn) diff --git a/ceilometer/tests/storage/test_impl_mongodb.py b/ceilometer/tests/storage/test_impl_mongodb.py index a7be1ac35..a9e6ddc8e 100644 --- a/ceilometer/tests/storage/test_impl_mongodb.py +++ b/ceilometer/tests/storage/test_impl_mongodb.py @@ -37,15 +37,12 @@ class MongoDBEngineTestBase(tests_db.TestBase): class MongoDBConnection(MongoDBEngineTestBase): def test_connection_pooling(self): - self.assertEqual(self.conn.conn, - impl_mongodb.Connection(self.CONF).conn) + test_conn = impl_mongodb.Connection(self.db_manager.connection) + self.assertEqual(self.conn.conn, test_conn.conn) def test_replica_set(self): - self.CONF.set_override( - 'connection', - self.db_manager.connection + '?replicaSet=foobar', - group='database') - conn = impl_mongodb.Connection(self.CONF) + url = self.db_manager.connection + '?replicaSet=foobar' + conn = impl_mongodb.Connection(url) self.assertTrue(conn.conn) def test_recurse_sort_keys(self): diff --git a/ceilometer/tests/storage/test_storage_scenarios.py b/ceilometer/tests/storage/test_storage_scenarios.py index 6473e5213..8ba878622 100644 --- a/ceilometer/tests/storage/test_storage_scenarios.py +++ b/ceilometer/tests/storage/test_storage_scenarios.py @@ -29,6 +29,7 @@ from ceilometer.publisher import utils from ceilometer import sample from ceilometer import storage from ceilometer.storage import base +from ceilometer.storage import impl_mongodb as mongodb from ceilometer.storage import models from ceilometer.tests import db as tests_db @@ -655,7 +656,7 @@ class RawSampleTest(DBTestBase, def test_clear_metering_data(self): # NOTE(jd) Override this test in MongoDB because our code doesn't clear # the collections, this is handled by MongoDB TTL feature. - if self.CONF.database.connection.startswith('mongodb://'): + if isinstance(self.conn, mongodb.Connection): return self.mock_utcnow.return_value = datetime.datetime(2012, 7, 2, 10, 45) @@ -673,7 +674,7 @@ class RawSampleTest(DBTestBase, def test_clear_metering_data_no_data_to_remove(self): # NOTE(jd) Override this test in MongoDB because our code doesn't clear # the collections, this is handled by MongoDB TTL feature. - if self.CONF.database.connection.startswith('mongodb://'): + if isinstance(self.conn, mongodb.Connection): return self.mock_utcnow.return_value = datetime.datetime(2010, 7, 2, 10, 45) @@ -691,7 +692,7 @@ class RawSampleTest(DBTestBase, def test_clear_metering_data_with_alarms(self): # NOTE(jd) Override this test in MongoDB because our code doesn't clear # the collections, this is handled by MongoDB TTL feature. - if self.CONF.database.connection.startswith('mongodb://'): + if isinstance(self.conn, mongodb.Connection): return alarm = models.Alarm(alarm_id='r3d',