Merge "Implement the /v2/samples/<sample-id> API"

This commit is contained in:
Jenkins 2014-01-22 08:30:00 +00:00 committed by Gerrit Code Review
commit 3208e3250d
7 changed files with 63 additions and 3 deletions

View File

@ -973,6 +973,20 @@ class SamplesController(rest.RestController):
return map(Sample.from_db_model,
pecan.request.storage_conn.get_samples(f, limit=limit))
@wsme_pecan.wsexpose(Sample, wtypes.text)
def get_one(self, sample_id):
"""Return a sample
:param sample_id: the id of the sample
"""
f = storage.SampleFilter(message_id=sample_id)
samples = list(pecan.request.storage_conn.get_samples(f))
if len(samples) < 1:
raise EntityNotFound(_('Sample'), sample_id)
return Sample.from_db_model(samples[0])
class Resource(_Base):
"""An externally defined object for which samples have been received.

View File

@ -95,13 +95,15 @@ class SampleFilter(object):
:param resource: Optional filter for resource id.
:param meter: Optional filter for meter type using the meter name.
:param source: Optional source filter.
:param message_id: Optional sample_id filter.
:param metaquery: Optional filter on the metadata
"""
def __init__(self, user=None, project=None,
start=None, start_timestamp_op=None,
end=None, end_timestamp_op=None,
resource=None, meter=None,
source=None, metaquery={}):
source=None, message_id=None,
metaquery={}):
self.user = user
self.project = project
self.start = utils.sanitize_timestamp(start)
@ -112,6 +114,7 @@ class SampleFilter(object):
self.meter = meter
self.source = source
self.metaquery = metaquery
self.message_id = message_id
class EventFilter(object):

View File

@ -128,6 +128,8 @@ def make_query_from_filter(sample_filter, require_meter=True):
q['resource_id'] = sample_filter.resource
if sample_filter.source:
q['source'] = sample_filter.source
if sample_filter.message_id:
q['message_id'] = sample_filter.message_id
# so the samples call metadata resource_metadata, so we convert
# to that.

View File

@ -241,6 +241,7 @@ class Connection(base.Connection):
# TODO(shengjie) extra dimensions need to be added as CQ
'f:user_id': data['user_id'],
'f:project_id': data['project_id'],
'f:message_id': data['message_id'],
'f:resource_id': data['resource_id'],
'f:source': data['source'],
# add in reversed_ts here for time range scan
@ -707,7 +708,8 @@ def reverse_timestamp(dt):
def make_query(user=None, project=None, meter=None,
resource=None, source=None, start=None, start_op=None,
end=None, end_op=None, require_meter=True, query_only=False):
end=None, end_op=None, message_id=None, require_meter=True,
query_only=False):
"""Return a filter query string based on the selected parameters.
:param user: Optional user-id
@ -719,6 +721,7 @@ def make_query(user=None, project=None, meter=None,
:param start_op: Optional start timestamp operator, like gt, ge
:param end: Optional end timestamp
:param end_op: Optional end timestamp operator, like lt, le
:param message_id: Optional message_id
:param require_meter: If true and the filter does not have a meter,
raise an error.
:param query_only: If true only returns the filter query,
@ -735,6 +738,9 @@ def make_query(user=None, project=None, meter=None,
if resource:
q.append("SingleColumnValueFilter ('f', 'resource_id', =, 'binary:%s')"
% resource)
if message_id:
q.append("SingleColumnValueFilter ('f', 'message_id', =, 'binary:%s')"
% message_id)
if source:
q.append("SingleColumnValueFilter "
"('f', 'source', =, 'binary:%s')" % source)
@ -792,6 +798,7 @@ def make_query_from_filter(sample_filter, require_meter=True):
sample_filter.start_timestamp_op,
sample_filter.end,
sample_filter.end_timestamp_op,
sample_filter.message_id,
require_meter)

View File

@ -131,6 +131,8 @@ def make_query_from_filter(sample_filter, require_meter=True):
q['resource_id'] = sample_filter.resource
if sample_filter.source:
q['source'] = sample_filter.source
if sample_filter.message_id:
q['message_id'] = sample_filter.message_id
# so the samples call metadata resource_metadata, so we convert
# to that.

View File

@ -159,6 +159,8 @@ def make_query_from_filter(session, query, sample_filter, require_meter=True):
query = query.filter_by(project_id=sample_filter.project)
if sample_filter.resource:
query = query.filter_by(resource_id=sample_filter.resource)
if sample_filter.message_id:
query = query.filter_by(message_id=sample_filter.message_id)
if sample_filter.metaquery:
query = apply_metaquery_filter(session, query,

View File

@ -21,6 +21,7 @@
import base64
import datetime
import json as jsonutils
import logging
import testscenarios
@ -47,6 +48,7 @@ class TestListMeters(FunctionalTest,
def setUp(self):
super(TestListMeters, self).setUp()
self.messages = []
for cnt in [
sample.Sample(
'meter.test',
@ -131,6 +133,7 @@ class TestListMeters(FunctionalTest,
msg = utils.meter_message_from_counter(
cnt,
self.CONF.publisher.metering_secret)
self.messages.append(msg)
self.conn.record_metering_data(msg)
def test_list_meters(self):
@ -164,6 +167,33 @@ class TestListMeters(FunctionalTest,
self.assertEqual('self.sample4', metadata['tag'])
self.assertEqual('prop_value', metadata['properties.prop_1'])
def test_get_one_sample(self):
sample_id = self.messages[1]['message_id']
data = self.get_json('/samples/%s' % sample_id)
self.assertIn('id', data)
self.assertEqual(data, {
u'id': sample_id,
u'metadata': {u'display_name': u'test-server',
u'is_public': u'False',
u'size': u'0',
u'tag': u'self.sample1',
u'util': u'0.47'},
u'meter': u'meter.test',
u'project_id': u'project-id',
u'resource_id': u'resource-id',
u'timestamp': u'2012-07-02T11:40:00',
u'type': u'cumulative',
u'unit': u'',
u'user_id': u'user-id',
u'volume': 3.0})
def test_get_not_existing_sample(self):
resp = self.get_json('/samples/not_exists', expect_errors=True)
self.assertEqual(resp.status_code, 404)
self.assertEqual(jsonutils.loads(resp.body)['error_message']
['faultstring'],
"Sample not_exists Not Found")
def test_list_samples_with_dict_metadata(self):
data = self.get_json('/samples',
q=[{'field':
@ -171,7 +201,7 @@ class TestListMeters(FunctionalTest,
'op': 'eq',
'value': 'sub_prop_value',
}])
self.assertTrue('id' in data[0])
self.assertIn('id', data[0])
del data[0]['id'] # Randomly generated
self.assertEqual(data, [{
u'user_id': u'user-id4',