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 import models as api_models
from ceilometer.storage.sqlalchemy import migration from ceilometer.storage.sqlalchemy import migration
from ceilometer.storage.sqlalchemy.models import Alarm 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 Base
from ceilometer.storage.sqlalchemy.models import Event from ceilometer.storage.sqlalchemy.models import Event
from ceilometer.storage.sqlalchemy.models import Meter 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.query(Alarm).filter(Alarm.id == alarm_id).delete()
session.flush() 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, def get_alarm_changes(self, alarm_id, on_behalf_of,
user=None, project=None, type=None, user=None, project=None, type=None,
start_timestamp=None, start_timestamp_op=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: Optional modified timestamp end range
:param end_timestamp_op: Optional timestamp end range operation :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): def record_alarm_change(self, alarm_change):
"""Record alarm change event. """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 @staticmethod
def _get_unique(session, key): 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) 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): class UniqueName(Base):
"""Key names should only be stored once. """Key names should only be stored once.
""" """

View File

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