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:
parent
652d414be2
commit
98729deed1
|
@ -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'],
|
||||
|
|
|
@ -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
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue