Source code for ceilometer.storage.sqlalchemy.models

# -*- encoding: utf-8 -*-
#
# Author: John Tran <jhtran@att.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.

"""
SQLAlchemy models for Ceilometer data.
"""

import json
import urlparse

from oslo.config import cfg
from sqlalchemy import Column, Integer, String, Table, ForeignKey, DateTime, \
    Float
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy.types import TypeDecorator, VARCHAR

from ceilometer.openstack.common import timeutils

sql_opts = [
    cfg.StrOpt('mysql_engine',
               default='InnoDB',
               help='MySQL engine')
]

cfg.CONF.register_opts(sql_opts)


def table_args():
    engine_name = urlparse.urlparse(cfg.CONF.database_connection).scheme
    if engine_name == 'mysql':
        return {'mysql_engine': cfg.CONF.mysql_engine,
                'mysql_charset': "utf8"}
    return None


[docs]class JSONEncodedDict(TypeDecorator): "Represents an immutable structure as a json-encoded string." impl = VARCHAR
[docs] def process_bind_param(self, value, dialect): if value is not None: value = json.dumps(value) return value
[docs] def process_result_value(self, value, dialect): if value is not None: value = json.loads(value) return value
[docs]class CeilometerBase(object): """Base class for Ceilometer Models.""" __table_args__ = table_args() __table_initialized__ = False def __setitem__(self, key, value): setattr(self, key, value) def __getitem__(self, key): return getattr(self, key)
Base = declarative_base(cls=CeilometerBase) sourceassoc = Table('sourceassoc', Base.metadata, Column('meter_id', Integer, ForeignKey("meter.id")), Column('project_id', String(255), ForeignKey("project.id")), Column('resource_id', String(255), ForeignKey("resource.id")), Column('user_id', String(255), ForeignKey("user.id")), Column('source_id', String(255), ForeignKey("source.id")))
[docs]class Source(Base): __tablename__ = 'source' id = Column(String(255), primary_key=True)
[docs]class Meter(Base): """Metering data.""" __tablename__ = 'meter' id = Column(Integer, primary_key=True) counter_name = Column(String(255)) sources = relationship("Source", secondary=lambda: sourceassoc) user_id = Column(String(255), ForeignKey('user.id')) project_id = Column(String(255), ForeignKey('project.id')) resource_id = Column(String(255), ForeignKey('resource.id')) resource_metadata = Column(JSONEncodedDict) counter_type = Column(String(255)) counter_unit = Column(String(255)) counter_volume = Column(Float(53)) timestamp = Column(DateTime, default=timeutils.utcnow) message_signature = Column(String) message_id = Column(String)
[docs]class User(Base): __tablename__ = 'user' id = Column(String(255), primary_key=True) sources = relationship("Source", secondary=lambda: sourceassoc) resources = relationship("Resource", backref='user') meters = relationship("Meter", backref='user')
[docs]class Project(Base): __tablename__ = 'project' id = Column(String(255), primary_key=True) sources = relationship("Source", secondary=lambda: sourceassoc) resources = relationship("Resource", backref='project') meters = relationship("Meter", backref='project')
[docs]class Resource(Base): __tablename__ = 'resource' id = Column(String(255), primary_key=True) sources = relationship("Source", secondary=lambda: sourceassoc) resource_metadata = Column(JSONEncodedDict) user_id = Column(String(255), ForeignKey('user.id')) project_id = Column(String(255), ForeignKey('project.id')) meters = relationship("Meter", backref='resource')