Fix the dict type metadata missing issue

Based on current implement, the metadata with dict type will be
missed. But some metadata are using dict type, such as the extra
properties of Glance images.

Fix bug 1203699

Change-Id: Ie13e4e5231c789e0efcadace11347a15741472a1
This commit is contained in:
Fei Long Wang 2013-07-25 15:23:45 +08:00
parent ac000155a0
commit 149e4d6410
6 changed files with 30 additions and 14 deletions

View File

@ -45,6 +45,7 @@ from ceilometer.openstack.common import log
from ceilometer.openstack.common import timeutils
from ceilometer import sample
from ceilometer import storage
from ceilometer import utils
from ceilometer.api import acl
@ -270,8 +271,9 @@ def _flatten_metadata(metadata):
"""
if metadata:
return dict((k, unicode(v))
for k, v in metadata.iteritems()
if type(v) not in set([list, dict, set]))
for k, v in utils.recursive_keypairs(metadata,
separator='.')
if type(v) not in set([list, set]))
return {}

View File

@ -27,13 +27,13 @@ import decimal
from ceilometer.openstack.common import timeutils
def recursive_keypairs(d):
def recursive_keypairs(d, separator=':'):
"""Generator that produces sequence of keypairs for nested dictionaries.
"""
for name, value in sorted(d.iteritems()):
if isinstance(value, dict):
for subname, subvalue in recursive_keypairs(value):
yield ('%s:%s' % (name, subname), subvalue)
yield ('%s%s%s' % (name, separator, subname), subvalue)
elif isinstance(value, (tuple, list)):
# When doing a pair of JSON encode/decode operations to the tuple,
# the tuple would become list. So we have to generate the value as

View File

@ -52,7 +52,7 @@ class TestListEvents(FunctionalTest,
timestamp=datetime.datetime(2012, 7, 2, 10, 40),
resource_metadata={'display_name': 'test-server',
'tag': 'self.counter',
'ignored_dict': {'key': 'value'},
'dict_properties': {'key': 'value'},
'ignored_list': ['not-returned'],
},
source='test_source',
@ -169,6 +169,7 @@ class TestListEvents(FunctionalTest,
self.assert_('resource_metadata' in sample)
self.assertEqual(
list(sorted(sample['resource_metadata'].iteritems())),
[('display_name', 'test-server'),
[('dict_properties.key', 'value'),
('display_name', 'test-server'),
('tag', 'self.counter'),
])

View File

@ -143,10 +143,8 @@ class TestListMeters(FunctionalTest,
self.assertEquals('resource-id4', data[0]['resource_id'])
metadata = data[0]['resource_metadata']
self.assertIsNotNone(metadata)
# FIXME (flwang): Based on current implement, the metadata of
# dictionary type can't be shown in the output. See bug 1203699.
# Will add more asserts in the fix of 1203699.
self.assertEqual('self.counter4', metadata['tag'])
self.assertEqual('prop_value', metadata['properties.prop_1'])
def test_list_meters_metadata_query(self):
data = self.get_json('/meters/meter.test',

View File

@ -411,7 +411,7 @@ class TestListResources(FunctionalTest,
timestamp=datetime.datetime(2012, 7, 2, 10, 40),
resource_metadata={'display_name': 'test-server',
'tag': 'self.counter',
'ignored_dict': {'key': 'value'},
'dict_properties': {'key': 'value'},
'ignored_list': ['not-returned'],
},
source='test',
@ -425,10 +425,11 @@ class TestListResources(FunctionalTest,
data = self.get_json('/resources')
metadata = data[0]['metadata']
self.assertEqual(
list(sorted(metadata.iteritems())),
[('display_name', 'test-server'),
('tag', 'self.counter'),
])
[(u'dict_properties.key', u'value'),
(u'display_name', u'test-server'),
(u'tag', u'self.counter')
],
list(sorted(metadata.iteritems())))
def test_resource_meter_links(self):
counter1 = sample.Sample(

View File

@ -53,3 +53,17 @@ class TestUtils(tests_base.TestCase):
('b', 'B'),
('nested:a', 'A'),
('nested:b', 'B')])
def test_recursive_keypairs_with_separator(self):
data = {'a': 'A',
'b': 'B',
'nested': {'a': 'A',
'b': 'B',
},
}
separator = '.'
pairs = list(utils.recursive_keypairs(data, separator))
self.assertEqual(pairs, [('a', 'A'),
('b', 'B'),
('nested.a', 'A'),
('nested.b', 'B')])