diff --git a/ceilometer/storage/impl_mongodb.py b/ceilometer/storage/impl_mongodb.py index c690d7479..7dd5d3606 100644 --- a/ceilometer/storage/impl_mongodb.py +++ b/ceilometer/storage/impl_mongodb.py @@ -616,6 +616,26 @@ class Connection(base.Connection): for r in results['results']), key=operator.attrgetter('period_start')) + @staticmethod + def _decode_matching_metadata(matching_metadata): + if isinstance(matching_metadata, dict): + #note(sileht): keep compatibility with old db format + return matching_metadata + else: + new_matching_metadata = {} + for elem in matching_metadata: + new_matching_metadata[elem['key']] = elem['value'] + return new_matching_metadata + + @staticmethod + def _encode_matching_metadata(matching_metadata): + if matching_metadata: + new_matching_metadata = [] + for k, v in matching_metadata.iteritems(): + new_matching_metadata.append({'key': k, 'value': v}) + return new_matching_metadata + return matching_metadata + def get_alarms(self, name=None, user=None, project=None, enabled=True, alarm_id=None): """Yields a lists of alarms that match filters @@ -636,6 +656,8 @@ class Connection(base.Connection): a = {} a.update(alarm) del a['_id'] + a['matching_metadata'] = \ + self._decode_matching_metadata(a['matching_metadata']) yield models.Alarm(**a) def update_alarm(self, alarm): @@ -645,6 +667,9 @@ class Connection(base.Connection): # This is an insert, generate an id alarm.alarm_id = str(uuid.uuid1()) data = alarm.as_dict() + data['matching_metadata'] = \ + self._encode_matching_metadata(data['matching_metadata']) + self.db.alarm.update( {'alarm_id': alarm.alarm_id}, {'$set': data}, @@ -652,6 +677,8 @@ class Connection(base.Connection): stored_alarm = self.db.alarm.find({'alarm_id': alarm.alarm_id})[0] del stored_alarm['_id'] + stored_alarm['matching_metadata'] = \ + self._decode_matching_metadata(stored_alarm['matching_metadata']) return models.Alarm(**stored_alarm) def delete_alarm(self, alarm_id): diff --git a/tests/storage/base.py b/tests/storage/base.py index 096119e01..c870cfe37 100644 --- a/tests/storage/base.py +++ b/tests/storage/base.py @@ -801,16 +801,21 @@ class AlarmTest(DBTestBase): 'me', 'and-da-boys', evaluation_periods=1, period=60, - alarm_actions=['http://nowhere/alarms']), + alarm_actions=['http://nowhere/alarms'], + matching_metadata={'key': 'value'}), models.Alarm('orange-alert', 'test.fourty', 'gt', 75, 'avg', 'me', 'and-da-boys', period=60, - alarm_actions=['http://nowhere/alarms']), + alarm_actions=['http://nowhere/alarms'], + matching_metadata={'key2': 'value2'}), models.Alarm('yellow-alert', 'test.five', 'lt', 10, 'min', 'me', 'and-da-boys', - alarm_actions=['http://nowhere/alarms'])] + alarm_actions=['http://nowhere/alarms'], + matching_metadata= + {'key2': 'value2', + 'user_metadata.key3': 'value3'})] for a in alarms: self.conn.update_alarm(a) @@ -832,15 +837,23 @@ class AlarmTest(DBTestBase): self.assertEquals(yellow.state, models.Alarm.ALARM_INSUFFICIENT_DATA) self.assertEquals(yellow.ok_actions, []) self.assertEquals(yellow.insufficient_data_actions, []) + self.assertEquals(yellow.matching_metadata, + {'key2': 'value2', + 'user_metadata.key3': 'value3'}) def test_update(self): self.add_some_alarms() orange = list(self.conn.get_alarms(name='orange-alert'))[0] orange.enabled = False orange.state = models.Alarm.ALARM_INSUFFICIENT_DATA + orange.matching_metadata = {'new': 'value', + 'user_metadata.new2': 'value4'} updated = self.conn.update_alarm(orange) self.assertEquals(updated.enabled, False) self.assertEquals(updated.state, models.Alarm.ALARM_INSUFFICIENT_DATA) + self.assertEquals(updated.matching_metadata, + {'new': 'value', + 'user_metadata.new2': 'value4'}) def test_update_llu(self): llu = models.Alarm('llu', diff --git a/tests/storage/test_impl_mongodb.py b/tests/storage/test_impl_mongodb.py index bff915064..6d73b168d 100644 --- a/tests/storage/test_impl_mongodb.py +++ b/tests/storage/test_impl_mongodb.py @@ -26,6 +26,8 @@ import copy import datetime +import uuid + from oslo.config import cfg from tests.storage import base @@ -33,6 +35,7 @@ from tests.storage import base from ceilometer.publisher import rpc from ceilometer import counter from ceilometer.storage import impl_mongodb +from ceilometer.storage import models class MongoDBEngineTestBase(base.DBTestBase): @@ -143,7 +146,25 @@ class StatisticsTest(base.StatisticsTest, MongoDBEngineTestBase): class AlarmTest(base.AlarmTest, MongoDBEngineTestBase): - pass + def prepare_old_matching_metadata_alarm(self): + alarm = models.Alarm('old-alert', + 'test.one', 'eq', 36, 'count', + 'me', 'and-da-boys', + evaluation_periods=1, + period=60, + alarm_actions=['http://nowhere/alarms'], + matching_metadata={'key': 'value'}) + alarm.alarm_id = str(uuid.uuid1()) + data = alarm.as_dict() + self.conn.db.alarm.update( + {'alarm_id': alarm.alarm_id}, + {'$set': data}, + upsert=True) + + def test_alarm_get_old_matching_metadata_format(self): + self.prepare_old_matching_metadata_alarm() + old = list(self.conn.get_alarms(name='old-alert'))[0] + self.assertEquals(old.matching_metadata, {'key': 'value'}) class CompatibilityTest(MongoDBEngineTestBase):