Simple metaquery for get samples and resources

Currently, monasca does not return metadata for get meters and statistics,
so metaquery for meters and statistics cannot be supported in ceilosca yet.

Change-Id: I2772e936a6b4aa928048c4fb916a036b9f3df61c
This commit is contained in:
yeungp 2015-08-11 20:52:25 +00:00 committed by Pauline Yeung
parent 652d414be2
commit 98729deed1
2 changed files with 84 additions and 17 deletions

View File

@ -46,11 +46,11 @@ AVAILABLE_CAPABILITIES = {
'meters': {'query': {'simple': True,
'metadata': False}},
'resources': {'query': {'simple': True,
'metadata': False}},
'metadata': True}},
'samples': {'pagination': False,
'groupby': False,
'query': {'simple': True,
'metadata': False,
'metadata': True,
'complex': False}},
'statistics': {'groupby': False,
'query': {'simple': True,
@ -89,6 +89,35 @@ class Connection(base.Connection):
def _convert_to_dict(stats, cols):
return {c: stats[i] for i, c in enumerate(cols)}
def _convert_metaquery(self, metaquery):
"""Strip "metadata." from key and convert value to string
:param metaquery: { 'metadata.KEY': VALUE, ... }
:returns: converted metaquery
"""
query = {}
for k, v in metaquery.items():
key = k.split('.')[1]
if isinstance(v, basestring):
query[key] = v
else:
query[key] = str(int(v))
return query
def _match_metaquery_to_value_meta(self, query, value_meta):
"""Check if metaquery matches value_meta
:param query: metaquery with converted format
:param value_meta: metadata from monasca
:returns: True for matched, False for not matched
"""
if (len(query) > 0 and
(len(value_meta) == 0 or
not set(query.items()).issubset(set(value_meta.items())))):
return False
else:
return True
def upgrade(self):
pass
@ -146,8 +175,9 @@ class Connection(base.Connection):
if pagination:
raise ceilometer.NotImplementedError('Pagination not implemented')
q = {}
if metaquery:
raise ceilometer.NotImplementedError('Metaquery not implemented')
q = self._convert_metaquery(metaquery)
if start_timestamp_op and start_timestamp_op != 'ge':
raise ceilometer.NotImplementedError(('Start time op %s '
@ -191,6 +221,9 @@ class Connection(base.Connection):
d = sample['dimensions']
m = self._convert_to_dict(
sample['measurements'][0], sample['columns'])
vm = m['value_meta']
if not self._match_metaquery_to_value_meta(q, vm):
continue
if d.get('resource_id'):
yield api_models.Resource(
resource_id=d.get('resource_id'),
@ -295,10 +328,9 @@ class Connection(base.Connection):
sample_filter.
end_timestamp_op)
q = {}
if sample_filter.metaquery:
raise ceilometer.NotImplementedError('metaquery not '
'implemented '
'in get_samples')
q = self._convert_metaquery(sample_filter.metaquery)
if sample_filter.message_id:
raise ceilometer.NotImplementedError('message_id not '
@ -345,7 +377,9 @@ class Connection(base.Connection):
for measurement in sample['measurements']:
meas_dict = self._convert_to_dict(measurement,
sample['columns'])
vm = meas_dict['value_meta']
if not self._match_metaquery_to_value_meta(q, vm):
continue
yield api_models.Sample(
source=d.get('source'),
counter_name=sample['name'],

View File

@ -30,9 +30,6 @@ class TestGetResources(base.BaseTestCase):
conn = impl_monasca.Connection("127.0.0.1:8080")
kwargs = dict(pagination=True)
self.assertRaises(ceilometer.NotImplementedError,
lambda: list(conn.get_resources(**kwargs)))
kwargs = dict(metaquery=True)
self.assertRaises(ceilometer.NotImplementedError,
lambda: list(conn.get_resources(**kwargs)))
kwargs = dict(start_timestamp_op='le')
@ -81,6 +78,28 @@ class TestGetResources(base.BaseTestCase):
start_time='1970-01-01T00:00:00Z'),
ml_mock.call_args_list[0][1])
@mock.patch("ceilometer.storage.impl_monasca.MonascaDataFilter")
def test_get_resources_simple_metaquery(self, mock_mdf):
with mock.patch("ceilometer.monasca_client.Client") as mock_client:
conn = impl_monasca.Connection("127.0.0.1:8080")
mnl_mock = mock_client().metrics_list
mnl_mock.return_value = [{'name': 'metric1',
'dimensions': {},
'value_meta': {'key': 'value1'}},
{'name': 'metric2',
'dimensions': {},
'value_meta': {'key': 'value2'}},
]
kwargs = dict(metaquery={'metadata.key': 'value1'})
list(conn.get_resources(**kwargs))
ml_mock = mock_client().measurements_list
self.assertEqual(2, ml_mock.call_count)
self.assertEqual(dict(dimensions={},
name='metric2',
limit=1,
start_time='1970-01-01T00:00:00Z'),
ml_mock.call_args_list[1][1])
class MeterTest(base.BaseTestCase):
@ -145,11 +164,6 @@ class TestGetSamples(base.BaseTestCase):
self.assertRaises(ceilometer.NotImplementedError,
lambda: list(conn.get_samples(sample_filter)))
sample_filter = storage.SampleFilter(
meter='specific meter', metaquery='specific metaquery')
self.assertRaises(ceilometer.NotImplementedError,
lambda: list(conn.get_samples(sample_filter)))
sample_filter = storage.SampleFilter(meter='specific meter',
message_id='specific message')
self.assertRaises(ceilometer.NotImplementedError,
@ -287,6 +301,25 @@ class TestGetSamples(base.BaseTestCase):
ml_mock.call_args[1])
self.assertEqual(1, ml_mock.call_count)
@mock.patch("ceilometer.storage.impl_monasca.MonascaDataFilter")
def test_get_samples_simple_metaquery(self, mdf_mock):
with mock.patch("ceilometer.monasca_client.Client") as mock_client:
conn = impl_monasca.Connection("127.0.0.1:8080")
ml_mock = mock_client().measurements_list
ml_mock.return_value = (
TestGetSamples.dummy_get_samples_mocked_return_value)
sample_filter = storage.SampleFilter(
meter='specific meter',
metaquery={'metadata.key': u'value'})
list(conn.get_samples(sample_filter))
self.assertEqual(True, ml_mock.called)
self.assertEqual(dict(
dimensions={},
start_time='1970-01-01T00:00:00Z',
merge_metrics=True, name='specific meter'),
ml_mock.call_args[1])
self.assertEqual(1, ml_mock.call_count)
@mock.patch("ceilometer.storage.impl_monasca.MonascaDataFilter")
def test_get_samples_results(self, mdf_mock):
with mock.patch("ceilometer.monasca_client.Client") as mock_client:
@ -508,7 +541,7 @@ class CapabilitiesTest(base.BaseTestCase):
'pagination': False,
'query':
{
'complex': False, 'metadata': False, 'simple': True
'complex': False, 'metadata': True, 'simple': True
}
},
'samples':
@ -518,7 +551,7 @@ class CapabilitiesTest(base.BaseTestCase):
'query':
{
'complex': False,
'metadata': False,
'metadata': True,
'simple': True
}
},