Enable filter alarms by their type

Since type is a very important attribute for alarm object, it will be much
convenient to get alarms by certain type. This patch adds the 'alarm_type'
parameter to get_alarms interface to implement it.

End user can filter alarms by using 'type' filter.

NOTE: this patch changes the parameter 'type' to 'alarm_type' in
get_alarm_changes interface of storage module, to keep consistent with
get_alarm interface.

Change-Id: Ib81375028957490f3a114de7627bc4bcb20f3d77
This commit is contained in:
ZhiQiang Fan 2014-05-15 13:01:11 +08:00 committed by ZhiQiang Fan
parent 6eac318612
commit 36e5cca3d0
8 changed files with 68 additions and 23 deletions

View File

@ -44,8 +44,20 @@ class Connection(object):
@staticmethod
def get_alarms(name=None, user=None, state=None, meter=None,
project=None, enabled=None, alarm_id=None, pagination=None):
"""Yields a lists of alarms that match filters."""
project=None, enabled=None, alarm_id=None, pagination=None,
alarm_type=None):
"""Yields a lists of alarms that match filters.
:param name: Optional name for alarm.
:param user: Optional ID for user that owns the resource.
:param state: Optional string for alarm state.
:param meter: Optional string for alarms associated with meter.
:param project: Optional ID for project that owns the resource.
:param enabled: Optional boolean to list disable alarm.
:param alarm_id: Optional alarm_id to return one alarm.
:param pagination: Optional pagination query.
:param alarm_type: Optional alarm type.
"""
raise ceilometer.NotImplementedError('Alarms not implemented')
@staticmethod
@ -68,7 +80,7 @@ class Connection(object):
@staticmethod
def get_alarm_changes(alarm_id, on_behalf_of,
user=None, project=None, type=None,
user=None, project=None, alarm_type=None,
start_timestamp=None, start_timestamp_op=None,
end_timestamp=None, end_timestamp_op=None):
"""Yields list of AlarmChanges describing alarm history
@ -88,7 +100,7 @@ class Connection(object):
administrative user, indicating all projects)
:param user: Optional ID of user to return changes for
:param project: Optional ID of project to return changes for
:project type: Optional change type
:param alarm_type: Optional change type
:param start_timestamp: Optional modified timestamp start range
:param start_timestamp_op: Optional timestamp start range operation
:param end_timestamp: Optional modified timestamp end range

View File

@ -118,7 +118,8 @@ class Connection(hbase_base.Connection, base.Connection):
alarm_table.delete(alarm_id)
def get_alarms(self, name=None, user=None, state=None, meter=None,
project=None, enabled=None, alarm_id=None, pagination=None):
project=None, enabled=None, alarm_id=None, pagination=None,
alarm_type=None):
if pagination:
raise ceilometer.NotImplementedError('Pagination not implemented')
@ -128,7 +129,8 @@ class Connection(hbase_base.Connection, base.Connection):
q = hbase_utils.make_query(alarm_id=alarm_id, name=name,
enabled=enabled, user_id=user,
project_id=project, state=state)
project_id=project, state=state,
type=alarm_type)
with self.conn_pool.connection() as conn:
alarm_table = conn.table(self.ALARM_TABLE)
@ -138,11 +140,11 @@ class Connection(hbase_base.Connection, base.Connection):
yield models.Alarm(**stored_alarm)
def get_alarm_changes(self, alarm_id, on_behalf_of,
user=None, project=None, type=None,
user=None, project=None, alarm_type=None,
start_timestamp=None, start_timestamp_op=None,
end_timestamp=None, end_timestamp_op=None):
q = hbase_utils.make_query(alarm_id=alarm_id,
on_behalf_of=on_behalf_of, type=type,
on_behalf_of=on_behalf_of, type=alarm_type,
user_id=user, project_id=project)
start_row, end_row = hbase_utils.make_timestamp_query(
hbase_utils.make_general_rowkey_scan,

View File

@ -33,7 +33,8 @@ class Connection(base.Connection):
pass
def get_alarms(self, name=None, user=None, state=None, meter=None,
project=None, enabled=None, alarm_id=None, pagination=None):
project=None, enabled=None, alarm_id=None, pagination=None,
alarm_type=None):
"""Yields a lists of alarms that match filters."""
return []

View File

@ -142,9 +142,11 @@ class Connection(base.Connection):
return (self._row_to_alarm_model(x) for x in query.all())
def get_alarms(self, name=None, user=None, state=None, meter=None,
project=None, enabled=None, alarm_id=None, pagination=None):
"""Yields a lists of alarms that match filters
project=None, enabled=None, alarm_id=None, pagination=None,
alarm_type=None):
"""Yields a lists of alarms that match filters.
:param name: Optional name for alarm.
:param user: Optional ID for user that owns the resource.
:param state: Optional string for alarm state.
:param meter: Optional string for alarms associated with meter.
@ -152,6 +154,7 @@ class Connection(base.Connection):
:param enabled: Optional boolean to list disable alarm.
:param alarm_id: Optional alarm_id to return one alarm.
:param pagination: Optional pagination query.
:param alarm_type: Optional alarm type.
"""
if pagination:
@ -171,6 +174,8 @@ class Connection(base.Connection):
query = query.filter(models.Alarm.alarm_id == alarm_id)
if state is not None:
query = query.filter(models.Alarm.state == state)
if alarm_type is not None:
query = query.filter(models.Alarm.type == alarm_type)
alarms = self._retrieve_alarms(query)
@ -243,7 +248,7 @@ class Connection(base.Connection):
models.AlarmChange)
def get_alarm_changes(self, alarm_id, on_behalf_of,
user=None, project=None, type=None,
user=None, project=None, alarm_type=None,
start_timestamp=None, start_timestamp_op=None,
end_timestamp=None, end_timestamp_op=None):
"""Yields list of AlarmChanges describing alarm history
@ -263,7 +268,7 @@ class Connection(base.Connection):
administrative user, indicating all projects)
:param user: Optional ID of user to return changes for
:param project: Optional ID of project to return changes for
:project type: Optional change type
:param alarm_type: Optional change type
:param start_timestamp: Optional modified timestamp start range
:param start_timestamp_op: Optional timestamp start range operation
:param end_timestamp: Optional modified timestamp end range
@ -280,8 +285,8 @@ class Connection(base.Connection):
query = query.filter(models.AlarmChange.user_id == user)
if project is not None:
query = query.filter(models.AlarmChange.project_id == project)
if type is not None:
query = query.filter(models.AlarmChange.type == type)
if alarm_type is not None:
query = query.filter(models.AlarmChange.type == alarm_type)
if start_timestamp:
if start_timestamp_op == 'gt':
query = query.filter(

View File

@ -80,10 +80,11 @@ class Connection(base.Connection):
self.db.alarm_history.insert(alarm_change.copy())
def get_alarms(self, name=None, user=None, state=None, meter=None,
project=None, enabled=None, alarm_id=None, pagination=None):
"""Yields a lists of alarms that match filters
project=None, enabled=None, alarm_id=None, pagination=None,
alarm_type=None):
"""Yields a lists of alarms that match filters.
:param name: The Alarm name.
:param name: Optional name for alarm.
:param user: Optional ID for user that owns the resource.
:param state: Optional string for alarm state.
:param meter: Optional string for alarms associated with meter.
@ -91,6 +92,7 @@ class Connection(base.Connection):
:param enabled: Optional boolean to list disable alarm.
:param alarm_id: Optional alarm_id to return one alarm.
:param pagination: Optional pagination query.
:param alarm_type: Optional alarm type.
"""
if pagination:
raise ceilometer.NotImplementedError('Pagination not implemented')
@ -110,11 +112,13 @@ class Connection(base.Connection):
q['state'] = state
if meter is not None:
q['rule.meter_name'] = meter
if alarm_type is not None:
q['type'] = alarm_type
return self._retrieve_alarms(q, [], None)
def get_alarm_changes(self, alarm_id, on_behalf_of,
user=None, project=None, type=None,
user=None, project=None, alarm_type=None,
start_timestamp=None, start_timestamp_op=None,
end_timestamp=None, end_timestamp_op=None):
"""Yields list of AlarmChanges describing alarm history
@ -134,7 +138,7 @@ class Connection(base.Connection):
administrative user, indicating all projects)
:param user: Optional ID of user to return changes for
:param project: Optional ID of project to return changes for
:project type: Optional change type
:param alarm_type: Optional change type
:param start_timestamp: Optional modified timestamp start range
:param start_timestamp_op: Optional timestamp start range operation
:param end_timestamp: Optional modified timestamp end range
@ -147,8 +151,8 @@ class Connection(base.Connection):
q['user_id'] = user
if project is not None:
q['project_id'] = project
if type is not None:
q['type'] = type
if alarm_type is not None:
q['type'] = alarm_type
if start_timestamp or end_timestamp:
ts_range = pymongo_utils.make_timestamp_range(start_timestamp,
end_timestamp,

View File

@ -420,6 +420,10 @@ def _validate_query(query, db_func, internal_keys=None,
_verify_query_segregation(query)
valid_keys = inspect.getargspec(db_func)[0]
if 'alarm_type' in valid_keys:
valid_keys.remove('alarm_type')
valid_keys.append('type')
internal_keys.append('self')
valid_keys = set(valid_keys) - set(internal_keys)
translation = {'user_id': 'user',
@ -515,7 +519,8 @@ def _query_to_kwargs(query, db_func, internal_keys=None,
valid_keys = set(inspect.getargspec(db_func)[0]) - set(internal_keys)
translation = {'user_id': 'user',
'project_id': 'project',
'resource_id': 'resource'}
'resource_id': 'resource',
'type': 'alarm_type'}
stamp = {}
metaquery = {}
kwargs = {}

View File

@ -231,6 +231,15 @@ class TestAlarms(v2.FunctionalTest,
self.assertEqual(1, len(resp))
self.assertEqual('ok', resp[0]['state'])
def test_list_alarms_by_type(self):
alarms = self.get_json('/alarms',
q=[{'field': 'type',
'op': 'eq',
'value': 'threshold'}])
self.assertEqual(3, len(alarms))
self.assertEqual(set(['threshold']),
set(alarm['type'] for alarm in alarms))
def test_get_not_existing_alarm(self):
resp = self.get_json('/alarms/alarm-id-3', expect_errors=True)
self.assertEqual(404, resp.status_code)

View File

@ -2418,6 +2418,13 @@ class AlarmTest(AlarmTestBase,
alarms = list(self.alarm_conn.get_alarms(enabled=False))
self.assertEqual(len(alarms), 1)
def test_list_by_type(self):
self.add_some_alarms()
alarms = list(self.alarm_conn.get_alarms(alarm_type='threshold'))
self.assertEqual(3, len(alarms))
alarms = list(self.alarm_conn.get_alarms(alarm_type='combination'))
self.assertEqual(0, len(alarms))
def test_add(self):
self.add_some_alarms()
alarms = list(self.alarm_conn.get_alarms())