Avoid performing extra query for fetching qos bindings
Bug 1215872 Add a relationship with eager loading in the Port and Network models, thus preventing the 'extend' functions from performing extra queries. This patch also slight alters the methods for processing qos_queue bindings in order to allow them for populating the qos_queue id in the response being created. Change-Id: Ie80d12aeed5de94afa61f23d7bcfc21372f23c4f
This commit is contained in:
parent
b857c86f3b
commit
c59456734e
@ -430,7 +430,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
port_data['fixed_ips'],
|
port_data['fixed_ips'],
|
||||||
port_data[psec.PORTSECURITY],
|
port_data[psec.PORTSECURITY],
|
||||||
port_data[ext_sg.SECURITYGROUPS],
|
port_data[ext_sg.SECURITYGROUPS],
|
||||||
port_data[ext_qos.QUEUE],
|
port_data.get(ext_qos.QUEUE),
|
||||||
port_data.get(mac_ext.MAC_LEARNING),
|
port_data.get(mac_ext.MAC_LEARNING),
|
||||||
port_data.get(addr_pair.ADDRESS_PAIRS))
|
port_data.get(addr_pair.ADDRESS_PAIRS))
|
||||||
|
|
||||||
@ -991,12 +991,12 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
# DB Operations for setting the network as external
|
# DB Operations for setting the network as external
|
||||||
self._process_l3_create(context, new_net, net_data)
|
self._process_l3_create(context, new_net, net_data)
|
||||||
# Process QoS queue extension
|
# Process QoS queue extension
|
||||||
if network['network'].get(ext_qos.QUEUE):
|
net_queue_id = net_data.get(ext_qos.QUEUE)
|
||||||
new_net[ext_qos.QUEUE] = network['network'][ext_qos.QUEUE]
|
if net_queue_id:
|
||||||
# Raises if not found
|
# Raises if not found
|
||||||
self.get_qos_queue(context, new_net[ext_qos.QUEUE])
|
self.get_qos_queue(context, net_queue_id)
|
||||||
self._process_network_queue_mapping(context, new_net)
|
self._process_network_queue_mapping(
|
||||||
self._extend_network_qos_queue(context, new_net)
|
context, new_net, net_queue_id)
|
||||||
|
|
||||||
if (net_data.get(mpnet.SEGMENTS) and
|
if (net_data.get(mpnet.SEGMENTS) and
|
||||||
isinstance(provider_type, bool)):
|
isinstance(provider_type, bool)):
|
||||||
@ -1078,7 +1078,6 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
# to add provider networks fields
|
# to add provider networks fields
|
||||||
net_result = self._make_network_dict(network)
|
net_result = self._make_network_dict(network)
|
||||||
self._extend_network_dict_provider(context, net_result)
|
self._extend_network_dict_provider(context, net_result)
|
||||||
self._extend_network_qos_queue(context, net_result)
|
|
||||||
return self._fields(net_result, fields)
|
return self._fields(net_result, fields)
|
||||||
|
|
||||||
def get_networks(self, context, filters=None, fields=None):
|
def get_networks(self, context, filters=None, fields=None):
|
||||||
@ -1087,7 +1086,6 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
networks = super(NvpPluginV2, self).get_networks(context, filters)
|
networks = super(NvpPluginV2, self).get_networks(context, filters)
|
||||||
for net in networks:
|
for net in networks:
|
||||||
self._extend_network_dict_provider(context, net)
|
self._extend_network_dict_provider(context, net)
|
||||||
self._extend_network_qos_queue(context, net)
|
|
||||||
return [self._fields(network, fields) for network in networks]
|
return [self._fields(network, fields) for network in networks]
|
||||||
|
|
||||||
def update_network(self, context, id, network):
|
def update_network(self, context, id, network):
|
||||||
@ -1102,23 +1100,14 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
if psec.PORTSECURITY in network['network']:
|
if psec.PORTSECURITY in network['network']:
|
||||||
self._process_network_port_security_update(
|
self._process_network_port_security_update(
|
||||||
context, network['network'], net)
|
context, network['network'], net)
|
||||||
if network['network'].get(ext_qos.QUEUE):
|
net_queue_id = network['network'].get(ext_qos.QUEUE)
|
||||||
net[ext_qos.QUEUE] = network['network'][ext_qos.QUEUE]
|
if net_queue_id:
|
||||||
self._delete_network_queue_mapping(context, id)
|
self._delete_network_queue_mapping(context, id)
|
||||||
self._process_network_queue_mapping(context, net)
|
self._process_network_queue_mapping(context, net, net_queue_id)
|
||||||
self._process_l3_update(context, net, network['network'])
|
self._process_l3_update(context, net, network['network'])
|
||||||
self._extend_network_dict_provider(context, net)
|
self._extend_network_dict_provider(context, net)
|
||||||
self._extend_network_qos_queue(context, net)
|
|
||||||
return net
|
return net
|
||||||
|
|
||||||
def get_ports(self, context, filters=None, fields=None):
|
|
||||||
filters = filters or {}
|
|
||||||
with context.session.begin(subtransactions=True):
|
|
||||||
ports = super(NvpPluginV2, self).get_ports(context, filters)
|
|
||||||
for port in ports:
|
|
||||||
self._extend_port_qos_queue(context, port)
|
|
||||||
return [self._fields(port, fields) for port in ports]
|
|
||||||
|
|
||||||
def create_port(self, context, port):
|
def create_port(self, context, port):
|
||||||
# If PORTSECURITY is not the default value ATTR_NOT_SPECIFIED
|
# If PORTSECURITY is not the default value ATTR_NOT_SPECIFIED
|
||||||
# then we pass the port to the policy engine. The reason why we don't
|
# then we pass the port to the policy engine. The reason why we don't
|
||||||
@ -1161,9 +1150,10 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
self._process_port_create_security_group(
|
self._process_port_create_security_group(
|
||||||
context, port_data, port_data[ext_sg.SECURITYGROUPS])
|
context, port_data, port_data[ext_sg.SECURITYGROUPS])
|
||||||
# QoS extension checks
|
# QoS extension checks
|
||||||
port_data[ext_qos.QUEUE] = self._check_for_queue_and_create(
|
port_queue_id = self._check_for_queue_and_create(
|
||||||
context, port_data)
|
context, port_data)
|
||||||
self._process_port_queue_mapping(context, port_data)
|
self._process_port_queue_mapping(
|
||||||
|
context, port_data, port_queue_id)
|
||||||
if (isinstance(port_data.get(mac_ext.MAC_LEARNING), bool)):
|
if (isinstance(port_data.get(mac_ext.MAC_LEARNING), bool)):
|
||||||
self._create_mac_learning_state(context, port_data)
|
self._create_mac_learning_state(context, port_data)
|
||||||
elif mac_ext.MAC_LEARNING in port_data:
|
elif mac_ext.MAC_LEARNING in port_data:
|
||||||
@ -1172,9 +1162,6 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
LOG.debug(_("create_port completed on NVP for tenant "
|
LOG.debug(_("create_port completed on NVP for tenant "
|
||||||
"%(tenant_id)s: (%(id)s)"), port_data)
|
"%(tenant_id)s: (%(id)s)"), port_data)
|
||||||
|
|
||||||
# remove since it will be added in extend based on policy
|
|
||||||
del port_data[ext_qos.QUEUE]
|
|
||||||
self._extend_port_qos_queue(context, port_data)
|
|
||||||
self._process_portbindings_create_and_update(context,
|
self._process_portbindings_create_and_update(context,
|
||||||
port, port_data)
|
port, port_data)
|
||||||
# DB Operation is complete, perform NVP operation
|
# DB Operation is complete, perform NVP operation
|
||||||
@ -1272,7 +1259,7 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
self._process_port_port_security_update(
|
self._process_port_port_security_update(
|
||||||
context, port['port'], ret_port)
|
context, port['port'], ret_port)
|
||||||
|
|
||||||
ret_port[ext_qos.QUEUE] = self._check_for_queue_and_create(
|
port_queue_id = self._check_for_queue_and_create(
|
||||||
context, ret_port)
|
context, ret_port)
|
||||||
# Populate the mac learning attribute
|
# Populate the mac learning attribute
|
||||||
new_mac_learning_state = port['port'].get(mac_ext.MAC_LEARNING)
|
new_mac_learning_state = port['port'].get(mac_ext.MAC_LEARNING)
|
||||||
@ -1282,7 +1269,8 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
new_mac_learning_state)
|
new_mac_learning_state)
|
||||||
ret_port[mac_ext.MAC_LEARNING] = new_mac_learning_state
|
ret_port[mac_ext.MAC_LEARNING] = new_mac_learning_state
|
||||||
self._delete_port_queue_mapping(context, ret_port['id'])
|
self._delete_port_queue_mapping(context, ret_port['id'])
|
||||||
self._process_port_queue_mapping(context, ret_port)
|
self._process_port_queue_mapping(context, ret_port,
|
||||||
|
port_queue_id)
|
||||||
LOG.warn(_("Update port request: %s"), port)
|
LOG.warn(_("Update port request: %s"), port)
|
||||||
nvp_port_id = self._nvp_get_port_id(
|
nvp_port_id = self._nvp_get_port_id(
|
||||||
context, self.cluster, ret_port)
|
context, self.cluster, ret_port)
|
||||||
@ -1317,9 +1305,6 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
else:
|
else:
|
||||||
ret_port['status'] = constants.PORT_STATUS_ERROR
|
ret_port['status'] = constants.PORT_STATUS_ERROR
|
||||||
|
|
||||||
# remove since it will be added in extend based on policy
|
|
||||||
del ret_port[ext_qos.QUEUE]
|
|
||||||
self._extend_port_qos_queue(context, ret_port)
|
|
||||||
self._process_portbindings_create_and_update(context,
|
self._process_portbindings_create_and_update(context,
|
||||||
port['port'],
|
port['port'],
|
||||||
port)
|
port)
|
||||||
@ -1371,11 +1356,9 @@ class NvpPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
db_port = self._get_port(context, id)
|
db_port = self._get_port(context, id)
|
||||||
self._synchronizer.synchronize_port(
|
self._synchronizer.synchronize_port(
|
||||||
context, db_port)
|
context, db_port)
|
||||||
port = self._make_port_dict(db_port, fields)
|
return self._make_port_dict(db_port, fields)
|
||||||
else:
|
else:
|
||||||
port = super(NvpPluginV2, self).get_port(context, id, fields)
|
return super(NvpPluginV2, self).get_port(context, id, fields)
|
||||||
self._extend_port_qos_queue(context, port)
|
|
||||||
return port
|
|
||||||
|
|
||||||
def get_router(self, context, id, fields=None):
|
def get_router(self, context, id, fields=None):
|
||||||
if fields and 'status' in fields:
|
if fields and 'status' in fields:
|
||||||
|
@ -17,9 +17,11 @@
|
|||||||
# @author: Aaron Rosen, Nicira, Inc
|
# @author: Aaron Rosen, Nicira, Inc
|
||||||
|
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import orm
|
||||||
from sqlalchemy.orm import exc
|
from sqlalchemy.orm import exc
|
||||||
|
|
||||||
from neutron.api.v2 import attributes as attr
|
from neutron.api.v2 import attributes as attr
|
||||||
|
from neutron.db import db_base_plugin_v2
|
||||||
from neutron.db import model_base
|
from neutron.db import model_base
|
||||||
from neutron.db import models_v2
|
from neutron.db import models_v2
|
||||||
from neutron.openstack.common import log
|
from neutron.openstack.common import log
|
||||||
@ -49,6 +51,13 @@ class PortQueueMapping(model_base.BASEV2):
|
|||||||
queue_id = sa.Column(sa.String(36), sa.ForeignKey("qosqueues.id"),
|
queue_id = sa.Column(sa.String(36), sa.ForeignKey("qosqueues.id"),
|
||||||
primary_key=True)
|
primary_key=True)
|
||||||
|
|
||||||
|
# Add a relationship to the Port model adding a backref which will
|
||||||
|
# allow SQLAlchemy for eagerly load the queue binding
|
||||||
|
port = orm.relationship(
|
||||||
|
models_v2.Port,
|
||||||
|
backref=orm.backref("qos_queue", uselist=False,
|
||||||
|
cascade='delete', lazy='joined'))
|
||||||
|
|
||||||
|
|
||||||
class NetworkQueueMapping(model_base.BASEV2):
|
class NetworkQueueMapping(model_base.BASEV2):
|
||||||
network_id = sa.Column(sa.String(36),
|
network_id = sa.Column(sa.String(36),
|
||||||
@ -58,6 +67,13 @@ class NetworkQueueMapping(model_base.BASEV2):
|
|||||||
queue_id = sa.Column(sa.String(36), sa.ForeignKey("qosqueues.id",
|
queue_id = sa.Column(sa.String(36), sa.ForeignKey("qosqueues.id",
|
||||||
ondelete="CASCADE"))
|
ondelete="CASCADE"))
|
||||||
|
|
||||||
|
# Add a relationship to the Network model adding a backref which will
|
||||||
|
# allow SQLAlcremy for eagerly load the queue binding
|
||||||
|
network = orm.relationship(
|
||||||
|
models_v2.Network,
|
||||||
|
backref=orm.backref("qos_queue", uselist=False,
|
||||||
|
cascade='delete', lazy='joined'))
|
||||||
|
|
||||||
|
|
||||||
class NVPQoSDbMixin(ext_qos.QueuePluginBase):
|
class NVPQoSDbMixin(ext_qos.QueuePluginBase):
|
||||||
"""Mixin class to add queues."""
|
"""Mixin class to add queues."""
|
||||||
@ -96,13 +112,13 @@ class NVPQoSDbMixin(ext_qos.QueuePluginBase):
|
|||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
context.session.delete(qos_queue)
|
context.session.delete(qos_queue)
|
||||||
|
|
||||||
def _process_port_queue_mapping(self, context, p):
|
def _process_port_queue_mapping(self, context, port_data, queue_id):
|
||||||
if not p.get(ext_qos.QUEUE):
|
port_data[ext_qos.QUEUE] = queue_id
|
||||||
|
if not queue_id:
|
||||||
return
|
return
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
db = PortQueueMapping(port_id=p['id'],
|
context.session.add(PortQueueMapping(port_id=port_data['id'],
|
||||||
queue_id=p.get(ext_qos.QUEUE))
|
queue_id=queue_id))
|
||||||
context.session.add(db)
|
|
||||||
|
|
||||||
def _get_port_queue_bindings(self, context, filters=None, fields=None):
|
def _get_port_queue_bindings(self, context, filters=None, fields=None):
|
||||||
return self._get_collection(context, PortQueueMapping,
|
return self._get_collection(context, PortQueueMapping,
|
||||||
@ -121,13 +137,14 @@ class NVPQoSDbMixin(ext_qos.QueuePluginBase):
|
|||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
context.session.delete(binding)
|
context.session.delete(binding)
|
||||||
|
|
||||||
def _process_network_queue_mapping(self, context, network):
|
def _process_network_queue_mapping(self, context, net_data, queue_id):
|
||||||
if not network.get(ext_qos.QUEUE):
|
net_data[ext_qos.QUEUE] = queue_id
|
||||||
|
if not queue_id:
|
||||||
return
|
return
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
db = NetworkQueueMapping(network_id=network['id'],
|
context.session.add(
|
||||||
queue_id=network.get(ext_qos.QUEUE))
|
NetworkQueueMapping(network_id=net_data['id'],
|
||||||
context.session.add(db)
|
queue_id=queue_id))
|
||||||
|
|
||||||
def _get_network_queue_bindings(self, context, filters=None, fields=None):
|
def _get_network_queue_bindings(self, context, filters=None, fields=None):
|
||||||
return self._get_collection(context, NetworkQueueMapping,
|
return self._get_collection(context, NetworkQueueMapping,
|
||||||
@ -141,25 +158,23 @@ class NVPQoSDbMixin(ext_qos.QueuePluginBase):
|
|||||||
if binding:
|
if binding:
|
||||||
context.session.delete(binding)
|
context.session.delete(binding)
|
||||||
|
|
||||||
def _extend_port_qos_queue(self, context, port):
|
def _extend_dict_qos_queue(self, obj_res, obj_db):
|
||||||
filters = {'port_id': [port['id']]}
|
queue_mapping = obj_db['qos_queue']
|
||||||
fields = ['queue_id']
|
if queue_mapping:
|
||||||
port[ext_qos.QUEUE] = None
|
obj_res[ext_qos.QUEUE] = queue_mapping.get('queue_id')
|
||||||
queue_id = self._get_port_queue_bindings(
|
return obj_res
|
||||||
context, filters, fields)
|
|
||||||
if queue_id:
|
|
||||||
port[ext_qos.QUEUE] = queue_id[0]['queue_id']
|
|
||||||
return port
|
|
||||||
|
|
||||||
def _extend_network_qos_queue(self, context, network):
|
def _extend_port_dict_qos_queue(self, port_res, port_db):
|
||||||
filters = {'network_id': [network['id']]}
|
self._extend_dict_qos_queue(port_res, port_db)
|
||||||
fields = ['queue_id']
|
|
||||||
network[ext_qos.QUEUE] = None
|
def _extend_network_dict_qos_queue(self, network_res, network_db):
|
||||||
queue_id = self._get_network_queue_bindings(
|
self._extend_dict_qos_queue(network_res, network_db)
|
||||||
context, filters, fields)
|
|
||||||
if queue_id:
|
# Register dict extend functions for networks and ports
|
||||||
network[ext_qos.QUEUE] = queue_id[0]['queue_id']
|
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
|
||||||
return network
|
attr.NETWORKS, ['_extend_network_dict_qos_queue'])
|
||||||
|
db_base_plugin_v2.NeutronDbPluginV2.register_dict_extend_funcs(
|
||||||
|
attr.PORTS, ['_extend_port_dict_qos_queue'])
|
||||||
|
|
||||||
def _make_qos_queue_dict(self, queue, fields=None):
|
def _make_qos_queue_dict(self, queue, fields=None):
|
||||||
res = {'id': queue['id'],
|
res = {'id': queue['id'],
|
||||||
@ -215,7 +230,6 @@ class NVPQoSDbMixin(ext_qos.QueuePluginBase):
|
|||||||
filters = {'network_id': [port['network_id']]}
|
filters = {'network_id': [port['network_id']]}
|
||||||
network_queue_id = self._get_network_queue_bindings(
|
network_queue_id = self._get_network_queue_bindings(
|
||||||
context, filters, ['queue_id'])
|
context, filters, ['queue_id'])
|
||||||
|
|
||||||
if network_queue_id:
|
if network_queue_id:
|
||||||
# get networks that queue is assocated with
|
# get networks that queue is assocated with
|
||||||
filters = {'queue_id': [network_queue_id[0]['queue_id']]}
|
filters = {'queue_id': [network_queue_id[0]['queue_id']]}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user