Introduce safer access to resource meters
Storing of meters in the wrapper object attributes is bad. It can lead to name conflicts, which can theoretically result in weird bugs. Change-Id: I7b1a248be52721b0401fba7bf976b9c4e63f71ba Implements: blueprint ceilometer-api-enhancements
This commit is contained in:
@@ -127,6 +127,9 @@ class Resource(base.APIResourceWrapper):
|
||||
self.user_id,
|
||||
self.resource_id)
|
||||
|
||||
# Meters with statistics data
|
||||
self._meters = {}
|
||||
|
||||
# TODO(lsmola) make parallel obtaining of tenant and user
|
||||
# make the threading here, thread join into resource_list
|
||||
if ceilometer_usage and self.project_id:
|
||||
@@ -169,6 +172,16 @@ class Resource(base.APIResourceWrapper):
|
||||
def query(self):
|
||||
return self._query
|
||||
|
||||
@property
|
||||
def meters(self):
|
||||
return self._meters
|
||||
|
||||
def get_meter(self, meter_name):
|
||||
return self._meters.get(meter_name, None)
|
||||
|
||||
def set_meter(self, meter_name, value):
|
||||
self._meters[meter_name] = value
|
||||
|
||||
|
||||
class ResourceAggregate(Resource):
|
||||
"""Represents aggregate of more resources together.
|
||||
@@ -195,6 +208,9 @@ class ResourceAggregate(Resource):
|
||||
self.user_id = None
|
||||
self.resource_id = None
|
||||
|
||||
# Meters with statistics data
|
||||
self._meters = {}
|
||||
|
||||
if query:
|
||||
self._query = query
|
||||
else:
|
||||
@@ -563,13 +579,14 @@ class CeilometerUsage(object):
|
||||
if statistics:
|
||||
if stats_attr:
|
||||
# I want to load only a specific attribute
|
||||
setattr(resource, meter,
|
||||
getattr(statistics[0], stats_attr, None))
|
||||
resource.set_meter(
|
||||
meter,
|
||||
getattr(statistics[0], stats_attr, None))
|
||||
else:
|
||||
# I want a dictionary of all statistics
|
||||
setattr(resource, meter, statistics)
|
||||
resource.set_meter(meter, statistics)
|
||||
else:
|
||||
setattr(resource, meter, None)
|
||||
resource.set_meter(meter, None)
|
||||
|
||||
return resource
|
||||
|
||||
|
@@ -51,11 +51,11 @@ class SamplesView(generic.TemplateView):
|
||||
"""Construct datapoint series for a meter from resource aggregates."""
|
||||
series = []
|
||||
for resource in aggregates:
|
||||
if getattr(resource, meter_name):
|
||||
if resource.get_meter(meter_name):
|
||||
point = {'unit': unit,
|
||||
'name': getattr(resource, resource_name),
|
||||
'data': []}
|
||||
for statistic in getattr(resource, meter_name):
|
||||
for statistic in resource.get_meter(meter_name):
|
||||
date = statistic.duration_end[:19]
|
||||
value = float(getattr(statistic, stats_name))
|
||||
point['data'].append({'x': date, 'y': value})
|
||||
@@ -334,7 +334,7 @@ def load_report_data(request):
|
||||
meter.name,
|
||||
3600 * 24)
|
||||
for re in res:
|
||||
values = getattr(re, meter.name.replace(".", "_"))
|
||||
values = re.get_meter(meter.name.replace(".", "_"))
|
||||
if values:
|
||||
for value in values:
|
||||
row = {"name": 'none',
|
||||
|
@@ -161,8 +161,7 @@ class CeilometerApiTests(test.APITestCase):
|
||||
"get_tenant")})
|
||||
def test_global_data_get(self):
|
||||
class TempUsage(api.base.APIResourceWrapper):
|
||||
_attrs = ["id", "tenant", "user", "resource", "fake_meter_1",
|
||||
"fake_meter_2"]
|
||||
_attrs = ["id", "tenant", "user", "resource", "get_meter"]
|
||||
|
||||
meters = ["fake_meter_1",
|
||||
"fake_meter_2"]
|
||||
@@ -207,9 +206,9 @@ class CeilometerApiTests(test.APITestCase):
|
||||
self.assertEqual(first.user.name, 'user')
|
||||
self.assertEqual(first.tenant.name, 'test_tenant')
|
||||
self.assertEqual(first.resource, 'fake_resource_id')
|
||||
self.assertEqual(first.fake_meter_1, 9)
|
||||
self.assertEqual(first.fake_meter_2, 9)
|
||||
|
||||
self.assertEqual(first.get_meter('fake_meter_1'), 9)
|
||||
self.assertEqual(first.get_meter('fake_meter_2'), 9)
|
||||
self.assertEqual(len(first.meters), 2)
|
||||
# check that only one resource is returned
|
||||
self.assertEqual(len(data), 1)
|
||||
|
||||
@@ -262,8 +261,7 @@ class CeilometerApiTests(test.APITestCase):
|
||||
"get_tenant")})
|
||||
def test_global_data_get_all_statistic_data(self):
|
||||
class TempUsage(api.base.APIResourceWrapper):
|
||||
_attrs = ["id", "tenant", "user", "resource", "fake_meter_1",
|
||||
"fake_meter_2"]
|
||||
_attrs = ["id", "tenant", "user", "resource", "get_meter", ]
|
||||
|
||||
meters = ["fake_meter_1",
|
||||
"fake_meter_2"]
|
||||
@@ -308,7 +306,9 @@ class CeilometerApiTests(test.APITestCase):
|
||||
|
||||
statistic_obj = api.ceilometer.Statistic(statistics[0])
|
||||
# check that it returns whole statistic object
|
||||
self.assertEqual(vars(first.fake_meter_1[0]), vars(statistic_obj))
|
||||
self.assertEqual(vars(first.fake_meter_2[0]), vars(statistic_obj))
|
||||
self.assertEqual(vars(first.get_meter('fake_meter_1')[0]),
|
||||
vars(statistic_obj))
|
||||
self.assertEqual(vars(first.get_meter('fake_meter_2')[0]),
|
||||
vars(statistic_obj))
|
||||
|
||||
self.assertEqual(len(data), len(resources))
|
||||
|
Reference in New Issue
Block a user