]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Simplify delete_health_monitor() using cascades
authorRoman Podolyaka <rpodolyaka@mirantis.com>
Mon, 15 Apr 2013 15:10:07 +0000 (18:10 +0300)
committerRoman Podolyaka <rpodolyaka@mirantis.com>
Mon, 22 Apr 2013 10:05:10 +0000 (13:05 +0300)
Currently delete_health_monitor() emulates behaviour of
cascade deletion: when a HealthMonitor instance is deleted,
all corresponding PoolMonitorAssociations are queried and
deleted one by one. This can be done automatically by means
of SQLAlchemy if we set proper cascade flags on the relationship
between HealthMonitor and PoolMonitorAssociations models.

Fixes bug 1169107.

Change-Id: I674c381192719a56433f67be53a32203c36ebe2b

quantum/db/loadbalancer/loadbalancer_db.py
quantum/plugins/services/agent_loadbalancer/plugin.py
quantum/tests/unit/db/loadbalancer/test_db_loadbalancer.py

index ee504059aa915b22341b6dbc5c0b614bcc2d913b..65a01282a06cd2499bb009902d5bbb2bc144304b 100644 (file)
@@ -127,6 +127,12 @@ class HealthMonitor(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
     status = sa.Column(sa.String(16), nullable=False)
     admin_state_up = sa.Column(sa.Boolean(), nullable=False)
 
+    pools = orm.relationship(
+        "PoolMonitorAssociation",
+        backref="healthmonitor",
+        cascade="all"
+    )
+
 
 class PoolMonitorAssociation(model_base.BASEV2):
     """
@@ -139,8 +145,6 @@ class PoolMonitorAssociation(model_base.BASEV2):
     monitor_id = sa.Column(sa.String(36),
                            sa.ForeignKey("healthmonitors.id"),
                            primary_key=True)
-    monitor = orm.relationship("HealthMonitor",
-                               backref="pools_poolmonitorassociations")
 
 
 class LoadBalancerPluginDb(LoadBalancerPluginBase):
@@ -605,7 +609,7 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase):
 
             assoc = PoolMonitorAssociation(pool_id=pool_id,
                                            monitor_id=monitor_id)
-            assoc.monitor = monitor
+            assoc.healthmonitor = monitor
             pool.monitors.append(assoc)
 
         monitors = []
@@ -746,14 +750,6 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase):
 
     def delete_health_monitor(self, context, id):
         with context.session.begin(subtransactions=True):
-            assoc_qry = context.session.query(PoolMonitorAssociation)
-            pool_qry = context.session.query(Pool)
-            for assoc in assoc_qry.filter_by(monitor_id=id).all():
-                try:
-                    pool = pool_qry.filter_by(id=assoc['pool_id']).one()
-                except exc.NoResultFound:
-                    raise loadbalancer.PoolNotFound(pool_id=pool['id'])
-                pool.monitors.remove(assoc)
             monitor_db = self._get_resource(context, HealthMonitor, id)
             context.session.delete(monitor_db)
 
index 7ffe22530a7def338d600dea02d451107ba66002..95aaf0e2e3983b33e005ab26fe863d45d838e25c 100644 (file)
@@ -79,8 +79,8 @@ class LoadBalancerCallbacks(object):
                         m.status = constants.ACTIVE
 
                 for hm in pool.monitors:
-                    if hm.monitor.status in ACTIVE_PENDING:
-                        hm.monitor.status = constants.ACTIVE
+                    if hm.healthmonitor.status in ACTIVE_PENDING:
+                        hm.healthmonitor.status = constants.ACTIVE
 
             if (pool.status != constants.ACTIVE
                 or pool.vip.status != constants.ACTIVE):
@@ -104,9 +104,9 @@ class LoadBalancerCallbacks(object):
                 for m in pool.members if m.status == constants.ACTIVE
             ]
             retval['healthmonitors'] = [
-                self.plugin._make_health_monitor_dict(hm.monitor)
+                self.plugin._make_health_monitor_dict(hm.healthmonitor)
                 for hm in pool.monitors
-                if hm.monitor.status == constants.ACTIVE
+                if hm.healthmonitor.status == constants.ACTIVE
             ]
 
             return retval
index 590ac6907f6b428ad05702942753121dffd146cb..5c2f1e8e84bf822eb4fc50fa0f0c3117217ed529 100644 (file)
@@ -836,6 +836,42 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
             res = req.get_response(self.ext_api)
             self.assertEqual(res.status_int, 204)
 
+    def test_delete_healthmonitor_cascade_deletion_of_associations(self):
+        with self.health_monitor(type='HTTP', no_delete=True) as monitor:
+            with self.pool() as pool:
+                data = {
+                    'health_monitor': {
+                        'id': monitor['health_monitor']['id'],
+                        'tenant_id': self._tenant_id
+                    }
+                }
+                req = self.new_create_request(
+                    'pools',
+                    data,
+                    fmt=self.fmt,
+                    id=pool['pool']['id'],
+                    subresource='health_monitors')
+                res = req.get_response(self.ext_api)
+                self.assertEqual(res.status_int, 201)
+
+                ctx = context.get_admin_context()
+
+                # check if we actually have corresponding Pool associations
+                qry = ctx.session.query(ldb.PoolMonitorAssociation)
+                qry = qry.filter_by(monitor_id=monitor['health_monitor']['id'])
+                self.assertTrue(qry.all())
+                # delete the HealthMonitor instance
+                req = self.new_delete_request(
+                    'health_monitors',
+                    monitor['health_monitor']['id']
+                )
+                res = req.get_response(self.ext_api)
+                self.assertEqual(res.status_int, 204)
+                # check if all corresponding Pool associations are deleted
+                qry = ctx.session.query(ldb.PoolMonitorAssociation)
+                qry = qry.filter_by(monitor_id=monitor['health_monitor']['id'])
+                self.assertFalse(qry.all())
+
     def test_show_healthmonitor(self):
         with self.health_monitor() as monitor:
             keys = [('type', "TCP"),