Create database models for healthmanager

Co-Authored-By: German german.eichberger@hp.com
Create data models and repositories for healthmanager
Change the health manager's property---lastupdated to be datetime type
Change the code based on the previous comment
Design a new class healthmanager and  implement the update health method
and unit test class test_health_mixin
Add try and exception for get member in update_health_mixin
Delete the pool part when the member gets offline status
Add get_all method for AmphoraHealthRepository so we can pass non equality comparation in it,
also make a test for it in test_repositories.py
Changed the name of test_all and get_all to be test_all_filter and get_all_filter

Change-Id: Ic356dee139e743a9617d401f9658cfefcb49d15f
This commit is contained in:
minwang
2015-01-23 18:07:09 -08:00
parent 8c221e8f66
commit 164c09ef3d
12 changed files with 439 additions and 18 deletions

View File

@@ -0,0 +1,41 @@
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# 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.
"""create healthmanager table
Revision ID: 92fe9857279
Revises: 256852d5ff7c
Create Date: 2015-01-22 16:58:23.440247
"""
# revision identifiers, used by Alembic.
revision = '92fe9857279'
down_revision = '256852d5ff7c'
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
u'amphora_health',
sa.Column(u'amphora_id', sa.String(36), nullable=False),
sa.Column(u'last_update', sa.DateTime(timezone=True),
nullable=False)
)
def downgrade():
op.drop_table('health_manager')

View File

@@ -12,9 +12,11 @@
# License for the specific language governing permissions and limitations
# under the License.
import sqlalchemy as sa
from sqlalchemy import orm
from sqlalchemy.orm import validates
from sqlalchemy.sql import func
from octavia.common import data_models
from octavia.db import base_models
@@ -323,3 +325,13 @@ class Amphora(base_models.BASE):
sa.String(36),
sa.ForeignKey("provisioning_status.name",
name="fk_container_provisioning_status_name"))
class AmphoraHealth(base_models.BASE):
__data_model__ = data_models.AmphoraHealth
__tablename__ = "amphora_health"
amphora_id = sa.Column(
sa.String(36), nullable=False, primary_key=True)
last_update = sa.Column(sa.DateTime, default=func.now(),
nullable=False)

View File

@@ -1,4 +1,4 @@
# Copyright 2014 Rackspace
# Copyright 2014 Rackspace
#
# 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
@@ -22,9 +22,10 @@ from octavia.common import exceptions
from octavia.db import models
from octavia.openstack.common import uuidutils
import datetime
class BaseRepository(object):
model_class = None
def create(self, session, **model_kwargs):
@@ -101,7 +102,6 @@ class BaseRepository(object):
class Repositories(object):
def __init__(self):
self.load_balancer = LoadBalancerRepository()
self.vip = VipRepository()
@@ -113,6 +113,7 @@ class Repositories(object):
self.listener_stats = ListenerStatisticsRepository()
self.amphora = AmphoraRepository()
self.sni = SNIRepository()
self.amphorahealth = AmphoraHealthRepository()
def create_load_balancer_and_vip(self, session, load_balancer_dict,
vip_dict):
@@ -203,7 +204,6 @@ class Repositories(object):
class LoadBalancerRepository(BaseRepository):
model_class = models.LoadBalancer
def test_and_set_provisioning_status(self, session, id, status):
@@ -230,7 +230,6 @@ class LoadBalancerRepository(BaseRepository):
class VipRepository(BaseRepository):
model_class = models.Vip
def update(self, session, load_balancer_id, **model_kwargs):
@@ -241,7 +240,6 @@ class VipRepository(BaseRepository):
class HealthMonitorRepository(BaseRepository):
model_class = models.HealthMonitor
def update(self, session, pool_id, **model_kwargs):
@@ -252,7 +250,6 @@ class HealthMonitorRepository(BaseRepository):
class SessionPersistenceRepository(BaseRepository):
model_class = models.SessionPersistence
def update(self, session, pool_id, **model_kwargs):
@@ -268,12 +265,10 @@ class SessionPersistenceRepository(BaseRepository):
class PoolRepository(BaseRepository):
model_class = models.Pool
class MemberRepository(BaseRepository):
model_class = models.Member
def delete_members(self, session, member_ids):
@@ -282,7 +277,6 @@ class MemberRepository(BaseRepository):
class ListenerRepository(BaseRepository):
model_class = models.Listener
def has_pool(self, session, id):
@@ -292,7 +286,6 @@ class ListenerRepository(BaseRepository):
class ListenerStatisticsRepository(BaseRepository):
model_class = models.ListenerStatistics
def update(self, session, listener_id, **model_kwargs):
@@ -303,7 +296,6 @@ class ListenerStatisticsRepository(BaseRepository):
class AmphoraRepository(BaseRepository):
model_class = models.Amphora
def associate(self, session, load_balancer_id, amphora_id):
@@ -317,7 +309,6 @@ class AmphoraRepository(BaseRepository):
class SNIRepository(BaseRepository):
model_class = models.SNI
def update(self, session, listener_id=None, tls_container_id=None,
@@ -332,3 +323,44 @@ class SNIRepository(BaseRepository):
elif tls_container_id:
session.query(self.model_class).filter_by(
tls_container_id=tls_container_id).update(model_kwargs)
class AmphoraHealthRepository(BaseRepository):
model_class = models.AmphoraHealth
def update(self, session, amphora_id, **model_kwargs):
"""Updates a healthmanager entity in the database by amphora_id."""
with session.begin(subtransactions=True):
session.query(self.model_class).filter_by(
amphora_id=amphora_id).update(model_kwargs)
def check_amphora_expired(self, session, amphora_id, timestamp=None):
"""check if a specific amphora is expired
:param session: A Sql Alchemy database session.
:param amphora_id: id of an amphora object
:param timestamp: A standard datetime which is used to see if an
amphora needs to be updated (default: now - 10s)
:returns: boolean
"""
if not timestamp:
timestamp = datetime.datetime.utcnow() - datetime.timedelta(
seconds=10)
amphora_health = self.get(session, amphora_id=amphora_id)
return amphora_health.last_update < timestamp
def get_expired_amphorae(self, session, timestamp=None):
"""Retrieves a list of entities from the health manager database.
:param session: A Sql Alchemy database session.
:param timestamp: A standard datetime which is used to see if an
amphora needs to be updated (default: now - 10s)
:returns: [octavia.common.data_model]
"""
if not timestamp:
timestamp = datetime.datetime.utcnow() - datetime.timedelta(
seconds=10)
filterquery = self.model_class.last_update < timestamp
model_list = session.query(self.model_class).filter(filterquery).all()
data_model_list = [model.to_data_model() for model in model_list]
return data_model_list