Merge "Alarm history storage implementation for sqlalchemy"

This commit is contained in:
Jenkins 2013-09-12 17:10:53 +00:00 committed by Gerrit Code Review
commit 7884ecddd3
4 changed files with 135 additions and 2 deletions

View File

@ -35,6 +35,7 @@ from ceilometer.storage import base
from ceilometer.storage import models as api_models
from ceilometer.storage.sqlalchemy import migration
from ceilometer.storage.sqlalchemy.models import Alarm
from ceilometer.storage.sqlalchemy.models import AlarmChange
from ceilometer.storage.sqlalchemy.models import Base
from ceilometer.storage.sqlalchemy.models import Event
from ceilometer.storage.sqlalchemy.models import Meter
@ -668,6 +669,17 @@ class Connection(base.Connection):
session.query(Alarm).filter(Alarm.id == alarm_id).delete()
session.flush()
@staticmethod
def _row_to_alarm_change_model(row):
return api_models.AlarmChange(event_id=row.event_id,
alarm_id=row.alarm_id,
type=row.type,
detail=row.detail,
user_id=row.user_id,
project_id=row.project_id,
on_behalf_of=row.on_behalf_of,
timestamp=row.timestamp)
def get_alarm_changes(self, alarm_id, on_behalf_of,
user=None, project=None, type=None,
start_timestamp=None, start_timestamp_op=None,
@ -695,12 +707,44 @@ class Connection(base.Connection):
:param end_timestamp: Optional modified timestamp end range
:param end_timestamp_op: Optional timestamp end range operation
"""
raise NotImplementedError('Alarm history not implemented')
session = sqlalchemy_session.get_session()
query = session.query(AlarmChange)
query = query.filter(AlarmChange.alarm_id == alarm_id)
if on_behalf_of is not None:
query = query.filter(AlarmChange.on_behalf_of == on_behalf_of)
if user is not None:
query = query.filter(AlarmChange.user_id == user)
if project is not None:
query = query.filter(AlarmChange.project_id == project)
if type is not None:
query = query.filter(AlarmChange.type == type)
if start_timestamp:
if start_timestamp_op == 'gt':
query = query.filter(AlarmChange.timestamp > start_timestamp)
else:
query = query.filter(AlarmChange.timestamp >= start_timestamp)
if end_timestamp:
if end_timestamp_op == 'le':
query = query.filter(AlarmChange.timestamp <= end_timestamp)
else:
query = query.filter(AlarmChange.timestamp < end_timestamp)
query = query.order_by(desc(AlarmChange.timestamp))
return (self._row_to_alarm_change_model(x) for x in query.all())
def record_alarm_change(self, alarm_change):
"""Record alarm change event.
"""
raise NotImplementedError('Alarm history not implemented')
session = sqlalchemy_session.get_session()
with session.begin():
session.merge(User(id=alarm_change['user_id']))
session.merge(Project(id=alarm_change['project_id']))
session.merge(Project(id=alarm_change['on_behalf_of']))
alarm_change_row = AlarmChange(event_id=alarm_change['event_id'])
alarm_change_row.update(alarm_change)
session.add(alarm_change_row)
session.flush()
@staticmethod
def _get_unique(session, key):

View File

@ -0,0 +1,72 @@
# -*- encoding: utf-8 -*-
#
# Copyright © 2013 Red Hat, Inc.
#
# Author: Eoghan Glynn <eglynn@redhat.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from migrate import ForeignKeyConstraint
from sqlalchemy import MetaData, Table, Column, Index
from sqlalchemy import String, DateTime
meta = MetaData()
def upgrade(migrate_engine):
meta.bind = migrate_engine
project = Table('project', meta, autoload=True)
user = Table('user', meta, autoload=True)
alarm_history = Table(
'alarm_history', meta,
Column('event_id', String(255), primary_key=True, index=True),
Column('alarm_id', String(255)),
Column('on_behalf_of', String(255)),
Column('project_id', String(255)),
Column('user_id', String(255)),
Column('type', String(20)),
Column('detail', String(255)),
Column('timestamp', DateTime(timezone=False)),
mysql_engine='InnoDB')
alarm_history.create()
if migrate_engine.name in ['mysql', 'postgresql']:
indices = [Index('ix_alarm_history_alarm_id',
alarm_history.c.alarm_id),
Index('ix_alarm_history_on_behalf_of',
alarm_history.c.on_behalf_of),
Index('ix_alarm_history_project_id',
alarm_history.c.project_id),
Index('ix_alarm_history_on_user_id',
alarm_history.c.user_id)]
for index in indices:
index.create(migrate_engine)
fkeys = [ForeignKeyConstraint(columns=[alarm_history.c.on_behalf_of],
refcolumns=[project.c.id]),
ForeignKeyConstraint(columns=[alarm_history.c.project_id],
refcolumns=[project.c.id]),
ForeignKeyConstraint(columns=[alarm_history.c.user_id],
refcolumns=[user.c.id])]
for fkey in fkeys:
fkey.create(engine=migrate_engine)
def downgrade(migrate_engine):
meta.bind = migrate_engine
alarm_history = Table('alarm_history', meta, autoload=True)
alarm_history.drop()

View File

@ -204,6 +204,22 @@ class Alarm(Base):
matching_metadata = Column(JSONEncodedDict)
class AlarmChange(Base):
"""Define AlarmChange data."""
__tablename__ = 'alarm_history'
__table_args__ = (
Index('ix_alarm_history_alarm_id', 'alarm_id'),
)
event_id = Column(String(255), primary_key=True)
alarm_id = Column(String(255))
on_behalf_of = Column(String(255), ForeignKey('project.id'))
project_id = Column(String(255), ForeignKey('project.id'))
user_id = Column(String(255), ForeignKey('user.id'))
type = Column(String(20))
detail = Column(String(255))
timestamp = Column(DateTime, default=timeutils.utcnow)
class UniqueName(Base):
"""Key names should only be stored once.
"""

View File

@ -179,6 +179,7 @@ class TestAlarms(FunctionalTest,
self.assertEqual(3, len(data))
self.delete('/alarms/%s' % data[0]['alarm_id'],
headers=self.auth_headers,
status=200)
alarms = list(self.conn.get_alarms())
self.assertEqual(2, len(alarms))