Avoid extra queries when retrieving routers

fixes bug 1160333

Instead of making N additional sql requests,
use relationship and joined query.

Change-Id: I8f650691916a252bf2a525343bfa0521ff6fbe43
This commit is contained in:
Eugene Nikanorov 2013-05-06 15:28:09 +04:00
parent 6590388901
commit 9751562cd0
3 changed files with 27 additions and 8 deletions

View File

@ -18,12 +18,15 @@
import netaddr import netaddr
from oslo.config import cfg from oslo.config import cfg
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy import orm
from quantum.common import utils from quantum.common import utils
from quantum.db import db_base_plugin_v2
from quantum.db import l3_db from quantum.db import l3_db
from quantum.db import model_base from quantum.db import model_base
from quantum.db import models_v2 from quantum.db import models_v2
from quantum.extensions import extraroute from quantum.extensions import extraroute
from quantum.extensions import l3
from quantum.openstack.common import log as logging from quantum.openstack.common import log as logging
@ -44,9 +47,24 @@ class RouterRoute(model_base.BASEV2, models_v2.Route):
ondelete="CASCADE"), ondelete="CASCADE"),
primary_key=True) primary_key=True)
router = orm.relationship(l3_db.Router,
backref=orm.backref("route_list",
lazy='joined',
cascade='delete'))
class ExtraRoute_db_mixin(l3_db.L3_NAT_db_mixin): class ExtraRoute_db_mixin(l3_db.L3_NAT_db_mixin):
"""Mixin class to support extra route configuration on router.""" """Mixin class to support extra route configuration on router."""
def _extend_router_dict_extraroute(self, router_res, router_db):
router_res['routes'] = (ExtraRoute_db_mixin.
_make_extra_route_list(
router_db['route_list']
))
db_base_plugin_v2.QuantumDbPluginV2.register_dict_extend_funcs(
l3.ROUTERS, [_extend_router_dict_extraroute])
def update_router(self, context, id, router): def update_router(self, context, id, router):
r = router['router'] r = router['router']
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
@ -123,7 +141,8 @@ class ExtraRoute_db_mixin(l3_db.L3_NAT_db_mixin):
destination=route['destination'], destination=route['destination'],
nexthop=route['nexthop']).delete() nexthop=route['nexthop']).delete()
def _make_extra_route_list(self, extra_routes): @staticmethod
def _make_extra_route_list(extra_routes):
return [{'destination': route['destination'], return [{'destination': route['destination'],
'nexthop': route['nexthop']} 'nexthop': route['nexthop']}
for route in extra_routes] for route in extra_routes]
@ -137,8 +156,6 @@ class ExtraRoute_db_mixin(l3_db.L3_NAT_db_mixin):
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
router = super(ExtraRoute_db_mixin, self).get_router( router = super(ExtraRoute_db_mixin, self).get_router(
context, id, fields) context, id, fields)
router['routes'] = self._get_extra_routes_by_router_id(
context, id)
return router return router
def get_routers(self, context, filters=None, fields=None, def get_routers(self, context, filters=None, fields=None,
@ -148,9 +165,6 @@ class ExtraRoute_db_mixin(l3_db.L3_NAT_db_mixin):
routers = super(ExtraRoute_db_mixin, self).get_routers( routers = super(ExtraRoute_db_mixin, self).get_routers(
context, filters, fields, sorts=sorts, limit=limit, context, filters, fields, sorts=sorts, limit=limit,
marker=marker, page_reverse=page_reverse) marker=marker, page_reverse=page_reverse)
for router in routers:
router['routes'] = self._get_extra_routes_by_router_id(
context, router['id'])
return routers return routers
def _confirm_router_interface_not_in_use(self, context, router_id, def _confirm_router_interface_not_in_use(self, context, router_id,

View File

@ -127,7 +127,8 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
raise l3.RouterNotFound(router_id=id) raise l3.RouterNotFound(router_id=id)
return router return router
def _make_router_dict(self, router, fields=None): def _make_router_dict(self, router, fields=None,
process_extensions=True):
res = {'id': router['id'], res = {'id': router['id'],
'name': router['name'], 'name': router['name'],
'tenant_id': router['tenant_id'], 'tenant_id': router['tenant_id'],
@ -138,6 +139,9 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
if router['gw_port_id']: if router['gw_port_id']:
nw_id = router.gw_port['network_id'] nw_id = router.gw_port['network_id']
res['external_gateway_info'] = {'network_id': nw_id} res['external_gateway_info'] = {'network_id': nw_id}
if process_extensions:
for func in self._dict_extend_functions.get(l3.ROUTERS, []):
func(self, res, router)
return self._fields(res, fields) return self._fields(res, fields)
def create_router(self, context, router): def create_router(self, context, router):

View File

@ -87,10 +87,11 @@ class RouterExternalGatewayInUseByFloatingIp(qexception.InUse):
"gateway to external network %(net_id)s is required by one or " "gateway to external network %(net_id)s is required by one or "
"more floating IPs.") "more floating IPs.")
ROUTERS = 'routers'
# Attribute Map # Attribute Map
RESOURCE_ATTRIBUTE_MAP = { RESOURCE_ATTRIBUTE_MAP = {
'routers': { ROUTERS: {
'id': {'allow_post': False, 'allow_put': False, 'id': {'allow_post': False, 'allow_put': False,
'validate': {'type:uuid': None}, 'validate': {'type:uuid': None},
'is_visible': True, 'is_visible': True,