Delete its corresponding history data when deleting an alarm
The history data of an alarm will still be stored in storage after the alarm being deleted. that is easy to cause residue issue. taken from: I5f6d7a1998104335079b7988e3d0b929b8854b28 Change-Id: I4ceb3de37640de6ba1534e70735410333810a488 Closes-Bug: #1476883
This commit is contained in:
parent
1a6dc5f9ec
commit
e20c2fcf19
@ -72,7 +72,7 @@ class Connection(object):
|
||||
|
||||
@staticmethod
|
||||
def delete_alarm(alarm_id):
|
||||
"""Delete an alarm."""
|
||||
"""Delete an alarm and its history data."""
|
||||
raise ceilometer.NotImplementedError('Alarms not implemented')
|
||||
|
||||
@staticmethod
|
||||
|
@ -114,9 +114,14 @@ class Connection(hbase_base.Connection, base.Connection):
|
||||
create_alarm = update_alarm
|
||||
|
||||
def delete_alarm(self, alarm_id):
|
||||
"""Delete an alarm and its history data."""
|
||||
with self.conn_pool.connection() as conn:
|
||||
alarm_table = conn.table(self.ALARM_TABLE)
|
||||
alarm_table.delete(alarm_id)
|
||||
q = hbase_utils.make_query(alarm_id=alarm_id)
|
||||
alarm_history_table = conn.table(self.ALARM_HISTORY_TABLE)
|
||||
for alarm_id, ignored in alarm_history_table.scan(filter=q):
|
||||
alarm_history_table.delete(alarm_id)
|
||||
|
||||
def get_alarms(self, name=None, user=None, state=None, meter=None,
|
||||
project=None, enabled=None, alarm_id=None,
|
||||
|
@ -47,7 +47,7 @@ class Connection(base.Connection):
|
||||
return alarm
|
||||
|
||||
def delete_alarm(self, alarm_id):
|
||||
"""Delete an alarm."""
|
||||
"""Delete an alarm and its history data."""
|
||||
|
||||
def clear_expired_alarm_history_data(self, alarm_history_ttl):
|
||||
"""Clear expired alarm history data from the backend storage system.
|
||||
|
@ -216,7 +216,7 @@ class Connection(base.Connection):
|
||||
return self._row_to_alarm_model(alarm_row)
|
||||
|
||||
def delete_alarm(self, alarm_id):
|
||||
"""Delete an alarm
|
||||
"""Delete an alarm and its history data.
|
||||
|
||||
:param alarm_id: ID of the alarm to delete
|
||||
"""
|
||||
@ -224,6 +224,9 @@ class Connection(base.Connection):
|
||||
with session.begin():
|
||||
session.query(models.Alarm).filter(
|
||||
models.Alarm.alarm_id == alarm_id).delete()
|
||||
# FIXME(liusheng): we should use delete cascade
|
||||
session.query(models.AlarmChange).filter(
|
||||
models.AlarmChange.alarm_id == alarm_id).delete()
|
||||
|
||||
@staticmethod
|
||||
def _row_to_alarm_change_model(row):
|
||||
|
@ -109,7 +109,6 @@ class AlarmChange(base.Model):
|
||||
CREATION = 'creation'
|
||||
RULE_CHANGE = 'rule change'
|
||||
STATE_TRANSITION = 'state transition'
|
||||
DELETION = 'deletion'
|
||||
|
||||
def __init__(self,
|
||||
event_id,
|
||||
|
@ -77,8 +77,9 @@ class Connection(base.Connection):
|
||||
create_alarm = update_alarm
|
||||
|
||||
def delete_alarm(self, alarm_id):
|
||||
"""Delete an alarm."""
|
||||
"""Delete an alarm and its history data."""
|
||||
self.db.alarm.remove({'alarm_id': alarm_id})
|
||||
self.db.alarm_history.remove({'alarm_id': alarm_id})
|
||||
|
||||
def record_alarm_change(self, alarm_change):
|
||||
"""Record alarm change event."""
|
||||
|
@ -625,10 +625,6 @@ class AlarmController(rest.RestController):
|
||||
self.conn.delete_alarm(alarm.alarm_id)
|
||||
alarm_object = Alarm.from_db_model(alarm)
|
||||
alarm_object.delete_actions()
|
||||
change = alarm_object.as_dict(alarm_models.Alarm)
|
||||
self._record_change(change,
|
||||
timeutils.utcnow(),
|
||||
type=alarm_models.AlarmChange.DELETION)
|
||||
|
||||
@wsme_pecan.wsexpose([AlarmChange], [base.Query])
|
||||
def history(self, q=None):
|
||||
|
@ -2457,7 +2457,7 @@ class TestAlarms(v2.FunctionalTest,
|
||||
history = self._get_alarm_history(self._get_alarm('a'), auth)
|
||||
self.assertEqual([], history)
|
||||
|
||||
def test_get_recorded_alarm_history_preserved_after_deletion(self):
|
||||
def test_delete_alarm_history_after_deletion(self):
|
||||
alarm = self._get_alarm('a')
|
||||
history = self._get_alarm_history(alarm)
|
||||
self.assertEqual([], history)
|
||||
@ -2469,45 +2469,24 @@ class TestAlarms(v2.FunctionalTest,
|
||||
headers=self.auth_headers,
|
||||
status=204)
|
||||
history = self._get_alarm_history(alarm)
|
||||
self.assertEqual(2, len(history))
|
||||
self._assert_is_subset(dict(alarm_id=alarm['alarm_id'],
|
||||
on_behalf_of=alarm['project_id'],
|
||||
project_id=alarm['project_id'],
|
||||
type='deletion',
|
||||
user_id=alarm['user_id']),
|
||||
history[0])
|
||||
alarm['rule'] = alarm['threshold_rule']
|
||||
del alarm['threshold_rule']
|
||||
self._assert_in_json(alarm, history[0]['detail'])
|
||||
detail = '{"name": "renamed"}'
|
||||
self._assert_is_subset(dict(alarm_id=alarm['alarm_id'],
|
||||
detail=detail,
|
||||
on_behalf_of=alarm['project_id'],
|
||||
project_id=alarm['project_id'],
|
||||
type='rule change',
|
||||
user_id=alarm['user_id']),
|
||||
history[1])
|
||||
self.assertEqual(0, len(history))
|
||||
|
||||
def test_get_alarm_history_ordered_by_recentness(self):
|
||||
alarm = self._get_alarm('a')
|
||||
for i in moves.xrange(10):
|
||||
self._update_alarm(alarm, dict(name='%s' % i))
|
||||
alarm = self._get_alarm('a')
|
||||
self._delete_alarm(alarm)
|
||||
history = self._get_alarm_history(alarm)
|
||||
self.assertEqual(11, len(history), 'hist: %s' % history)
|
||||
self.assertEqual(10, len(history), 'hist: %s' % history)
|
||||
self._assert_is_subset(dict(alarm_id=alarm['alarm_id'],
|
||||
type='deletion'),
|
||||
type='rule change'),
|
||||
history[0])
|
||||
alarm['rule'] = alarm['threshold_rule']
|
||||
del alarm['threshold_rule']
|
||||
self._assert_in_json(alarm, history[0]['detail'])
|
||||
for i in moves.xrange(1, 10):
|
||||
for i in moves.xrange(1, 11):
|
||||
detail = '{"name": "%s"}' % (10 - i)
|
||||
self._assert_is_subset(dict(alarm_id=alarm['alarm_id'],
|
||||
detail=detail,
|
||||
type='rule change'),
|
||||
history[i])
|
||||
history[i - 1])
|
||||
|
||||
def test_get_alarm_history_constrained_by_timestamp(self):
|
||||
alarm = self._get_alarm('a')
|
||||
@ -2530,19 +2509,18 @@ class TestAlarms(v2.FunctionalTest,
|
||||
|
||||
def test_get_alarm_history_constrained_by_type(self):
|
||||
alarm = self._get_alarm('a')
|
||||
self._delete_alarm(alarm)
|
||||
query = dict(field='type', op='eq', value='deletion')
|
||||
self._update_alarm(alarm, dict(name='renamed2'))
|
||||
query = dict(field='type', op='eq', value='rule change')
|
||||
history = self._get_alarm_history(alarm, query=query)
|
||||
self.assertEqual(1, len(history))
|
||||
detail = '{"name": "renamed2"}'
|
||||
self._assert_is_subset(dict(alarm_id=alarm['alarm_id'],
|
||||
detail=detail,
|
||||
on_behalf_of=alarm['project_id'],
|
||||
project_id=alarm['project_id'],
|
||||
type='deletion',
|
||||
type='rule change',
|
||||
user_id=alarm['user_id']),
|
||||
history[0])
|
||||
alarm['rule'] = alarm['threshold_rule']
|
||||
del alarm['threshold_rule']
|
||||
self._assert_in_json(alarm, history[0]['detail'])
|
||||
|
||||
def test_get_alarm_history_constrained_by_alarm_id_failed(self):
|
||||
alarm = self._get_alarm('b')
|
||||
@ -2627,26 +2605,18 @@ class TestAlarms(v2.FunctionalTest,
|
||||
PayloadMatcher(), mock.ANY)
|
||||
|
||||
def test_alarm_sends_notification(self):
|
||||
# Hit the AlarmController (with alarm_id supplied) ...
|
||||
data = self.get_json('/alarms')
|
||||
del_alarm_name = "name1"
|
||||
for d in data:
|
||||
if d['name'] == del_alarm_name:
|
||||
del_alarm_id = d['alarm_id']
|
||||
|
||||
alarm = self._get_alarm('a')
|
||||
with mock.patch.object(messaging, 'get_notifier') as get_notifier:
|
||||
notifier = get_notifier.return_value
|
||||
|
||||
self.delete('/alarms/%s' % del_alarm_id,
|
||||
headers=self.auth_headers, status=204)
|
||||
self._update_alarm(alarm, dict(name='new_name'))
|
||||
get_notifier.assert_called_once_with(mock.ANY,
|
||||
publisher_id='ceilometer.api')
|
||||
calls = notifier.info.call_args_list
|
||||
self.assertEqual(1, len(calls))
|
||||
args, _ = calls[0]
|
||||
context, event_type, payload = args
|
||||
self.assertEqual('alarm.deletion', event_type)
|
||||
self.assertEqual(del_alarm_name, payload['detail']['name'])
|
||||
self.assertEqual('alarm.rule_change', event_type)
|
||||
self.assertEqual('new_name', payload['detail']['name'])
|
||||
self.assertTrue(set(['alarm_id', 'detail', 'event_id', 'on_behalf_of',
|
||||
'project_id', 'timestamp', 'type',
|
||||
'user_id']).issubset(payload.keys()))
|
||||
|
@ -2932,6 +2932,17 @@ class AlarmHistoryTest(AlarmTestBase,
|
||||
utcnow = datetime.datetime(2014, 4, 7, 7, 45)
|
||||
self._clear_alarm_history(utcnow, 3 * 60, 0)
|
||||
|
||||
def test_delete_history_when_delete_alarm(self):
|
||||
alarms = list(self.alarm_conn.get_alarms())
|
||||
self.assertEqual(3, len(alarms))
|
||||
history = list(self.alarm_conn.query_alarm_history())
|
||||
self.assertEqual(3, len(history))
|
||||
for alarm in alarms:
|
||||
self.alarm_conn.delete_alarm(alarm.alarm_id)
|
||||
self.assertEqual(3, len(alarms))
|
||||
history = list(self.alarm_conn.query_alarm_history())
|
||||
self.assertEqual(0, len(history))
|
||||
|
||||
|
||||
class ComplexAlarmQueryTest(AlarmTestBase,
|
||||
tests_db.MixinTestsWithBackendScenarios):
|
||||
@ -3060,24 +3071,9 @@ class ComplexAlarmHistoryQueryTest(AlarmTestBase,
|
||||
|
||||
self.alarm_conn.record_alarm_change(alarm_change=alarm_change3)
|
||||
|
||||
if alarm.name in ["red-alert", "yellow-alert"]:
|
||||
alarm_change4 = dict(event_id=(
|
||||
"16fd2706-8baf-433b-82eb-8c7fada847f%s"
|
||||
% i),
|
||||
alarm_id=alarm.alarm_id,
|
||||
type=alarm_models.AlarmChange.DELETION,
|
||||
detail="detail %s" % (i + 2),
|
||||
user_id=alarm.user_id,
|
||||
project_id=alarm.project_id,
|
||||
on_behalf_of=alarm.project_id,
|
||||
timestamp=datetime.datetime(2012, 9, 27,
|
||||
10 + i,
|
||||
30 + i))
|
||||
self.alarm_conn.record_alarm_change(alarm_change=alarm_change4)
|
||||
|
||||
def test_alarm_history_with_no_filter(self):
|
||||
history = list(self.alarm_conn.query_alarm_history())
|
||||
self.assertEqual(11, len(history))
|
||||
self.assertEqual(9, len(history))
|
||||
|
||||
def test_alarm_history_with_no_filter_and_limit(self):
|
||||
history = list(self.alarm_conn.query_alarm_history(limit=3))
|
||||
@ -3125,11 +3121,10 @@ class ComplexAlarmHistoryQueryTest(AlarmTestBase,
|
||||
filter_expr = {"=": {"alarm_id": "r3d"}}
|
||||
history = list(self.alarm_conn.query_alarm_history(
|
||||
filter_expr=filter_expr, orderby=[{"timestamp": "asc"}]))
|
||||
self.assertEqual(4, len(history))
|
||||
self.assertEqual(3, len(history))
|
||||
self.assertEqual([alarm_models.AlarmChange.CREATION,
|
||||
alarm_models.AlarmChange.RULE_CHANGE,
|
||||
alarm_models.AlarmChange.STATE_TRANSITION,
|
||||
alarm_models.AlarmChange.DELETION],
|
||||
alarm_models.AlarmChange.STATE_TRANSITION],
|
||||
[h.type for h in history])
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user