Add support for limiting the number of samples returned

Blueprint: api-limit

Change-Id: Id053eb60674fea58b3d83b460fd0344dbc050cbf
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2013-05-31 14:00:47 +02:00
parent 0e10d2ddb7
commit 426cd49d86
6 changed files with 57 additions and 11 deletions

View File

@ -126,8 +126,11 @@ class Connection(object):
"""
@abc.abstractmethod
def get_samples(self, sample_filter):
"""Return an iterable of model.Sample instances
def get_samples(self, sample_filter, limit=None):
"""Return an iterable of model.Sample instances.
:param sample_filter: Filter.
:param limit: Maximum number of results to return.
"""
@abc.abstractmethod

View File

@ -393,8 +393,11 @@ class Connection(base.Connection):
user_id=data['f:user_id'],
)
def get_samples(self, sample_filter):
"""Return an iterable of models.Sample instances
def get_samples(self, sample_filter, limit=None):
"""Return an iterable of models.Sample instances.
:param sample_filter: Filter.
:param limit: Maximum number of results to return.
"""
def make_sample(data):
""" transform HBase fields to Sample model
@ -415,6 +418,9 @@ class Connection(base.Connection):
# properly.
# handle metaquery
metaquery = sample_filter.metaquery
# TODO(jd) implements using HBase capabilities
if limit == 0:
break
if len(metaquery) > 0:
# metaquery checks resource table
resource = self.resource.row(meter['f:resource_id'])
@ -423,8 +429,12 @@ class Connection(base.Connection):
if resource['f:r_' + k.split('.', 1)[1]] != v:
break # if one metaquery doesn't match, break
else:
if limit:
limit -= 1
yield make_sample(meter)
else:
if limit:
limit -= 1
yield make_sample(meter)
def _update_meter_stats(self, stat, meter):

View File

@ -100,7 +100,7 @@ class Connection(base.Connection):
return []
def get_meters(self, user=None, project=None, resource=None, source=None,
metaquery={}):
limit=None, metaquery={}):
"""Return an iterable of dictionaries containing meter information.
{ 'name': name of the meter,
@ -114,6 +114,7 @@ class Connection(base.Connection):
:param project: Optional ID for project that owns the resource.
:param resource: Optional resource filter.
:param source: Optional source filter.
:param limit: Maximum number of results to return.
:param metaquery: Optional dict with metadata to match on.
"""
return []

View File

@ -440,12 +440,16 @@ class Connection(base.Connection):
user_id=r['user_id'],
)
def get_samples(self, sample_filter):
"""Return an iterable of samples as created by
:func:`ceilometer.meter.meter_message_from_counter`.
def get_samples(self, sample_filter, limit=None):
"""Return an iterable of model.Sample instances.
:param sample_filter: Filter.
:param limit: Maximum number of results to return.
"""
if limit == 0:
return
q = make_query_from_filter(sample_filter, require_meter=False)
samples = self.db.meter.find(q)
samples = self.db.meter.find(q).limit(limit or 0)
for s in samples:
# Remove the ObjectId generated by the database when
# the sample was inserted. It is an implementation

View File

@ -311,12 +311,20 @@ class Connection(base.Connection):
user_id=resource.user_id,
)
def get_samples(self, sample_filter):
"""Return an iterable of api_models.Samples
def get_samples(self, sample_filter, limit=None):
"""Return an iterable of api_models.Samples.
:param sample_filter: Filter.
:param limit: Maximum number of results to return.
"""
if limit == 0:
return
query = self.session.query(Meter)
query = make_query_from_filter(query, sample_filter,
require_meter=False)
if limit:
query = query.limit(limit)
samples = query.all()
for s in samples:

View File

@ -271,6 +271,16 @@ class MeterTest(DBTestBase):
class RawSampleTest(DBTestBase):
def test_get_samples_limit_zero(self):
f = storage.SampleFilter()
results = list(self.conn.get_samples(f, limit=0))
self.assertEqual(len(results), 0)
def test_get_samples_limit(self):
f = storage.SampleFilter()
results = list(self.conn.get_samples(f, limit=3))
self.assertEqual(len(results), 3)
def test_get_samples_by_user(self):
f = storage.SampleFilter(user='user-id')
results = list(self.conn.get_samples(f))
@ -278,6 +288,16 @@ class RawSampleTest(DBTestBase):
for meter in results:
assert meter.as_dict() in [self.msg1, self.msg2]
def test_get_samples_by_user_limit(self):
f = storage.SampleFilter(user='user-id')
results = list(self.conn.get_samples(f, limit=1))
self.assertEqual(len(results), 1)
def test_get_samples_by_user_limit_bigger(self):
f = storage.SampleFilter(user='user-id')
results = list(self.conn.get_samples(f, limit=42))
self.assertEqual(len(results), 2)
def test_get_samples_by_project(self):
f = storage.SampleFilter(project='project-id')
results = list(self.conn.get_samples(f))