diff --git a/ceilometer/storage/__init__.py b/ceilometer/storage/__init__.py index de2713be9..e7197cee8 100644 --- a/ceilometer/storage/__init__.py +++ b/ceilometer/storage/__init__.py @@ -63,6 +63,11 @@ OPTS = [ help='The name of the replica set which is used to connect to ' 'MongoDB database. If it is set, MongoReplicaSetClient ' 'will be used instead of MongoClient.'), + cfg.IntOpt('db2nosql_resource_id_maxlen', + default=512, + help="The max length of resources id in DB2 nosql, " + "the value should be larger than len(hostname) * 2 " + "as compute node's resource id is _."), ] cfg.CONF.register_opts(OPTS, group='database') diff --git a/ceilometer/storage/impl_db2.py b/ceilometer/storage/impl_db2.py index 955db0e52..4eac478fb 100644 --- a/ceilometer/storage/impl_db2.py +++ b/ceilometer/storage/impl_db2.py @@ -28,6 +28,7 @@ import sys import bson.code import bson.objectid +from oslo.config import cfg from oslo.utils import timeutils import pymongo import six @@ -159,7 +160,14 @@ class Connection(pymongo_base.Connection): # queries, so the database won't take advantage of an index # including both. if self.db.resource.index_information() == {}: - resource_id = str(bson.objectid.ObjectId()) + # Initializing a longer resource id to workaround DB2 nosql issue. + # Longer resource id is required by compute node's resource as + # their id is '_'. DB2 creates a VARCHAR(70) + # for resource id when its length < 70. But DB2 can create a + # VARCHAR(n) for the resource id which has n(n>70) characters. + # Users can adjust 'db2nosql_resource_id_maxlen'(default is 512) + # for their ENV. + resource_id = 'x' * cfg.CONF.database.db2nosql_resource_id_maxlen self.db.resource.insert({'_id': resource_id, 'no_key': resource_id}) meter_id = str(bson.objectid.ObjectId()) diff --git a/ceilometer/tests/storage/test_impl_db2.py b/ceilometer/tests/storage/test_impl_db2.py index cf59873eb..549a2f5a0 100644 --- a/ceilometer/tests/storage/test_impl_db2.py +++ b/ceilometer/tests/storage/test_impl_db2.py @@ -26,8 +26,12 @@ from ceilometer.alarm.storage import impl_db2 as impl_db2_alarm from ceilometer.event.storage import impl_db2 as impl_db2_event from ceilometer.storage import impl_db2 +from ceilometer.storage.mongo import utils as pymongo_utils from ceilometer.tests import base as test_base +import mock +from oslo.config import cfg + class CapabilitiesTest(test_base.BaseTestCase): # Check the returned capabilities list, which is specific to each DB @@ -92,3 +96,20 @@ class CapabilitiesTest(test_base.BaseTestCase): } actual_capabilities = impl_db2.Connection.get_storage_capabilities() self.assertEqual(expected_capabilities, actual_capabilities) + + +class ConnectionTest(test_base.BaseTestCase): + @mock.patch.object(pymongo_utils.ConnectionPool, 'connect') + def test_upgrade(self, mongo_connect): + conn_mock = mock.MagicMock() + conn_mock.server_info.return_value = {} + conn_mock.ceilodb2.resource.index_information.return_value = {} + mongo_connect.return_value = conn_mock + cfg.CONF.set_override('db2nosql_resource_id_maxlen', + 256, + group='database') + impl_db2.Connection('db2://user:pwd@localhost:27017/ceilodb2') + resource_id = 'x' * 256 + conn_mock.ceilodb2.resource.insert.assert_called_with( + {'_id': resource_id, + 'no_key': resource_id})