summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-08-08 23:34:40 +0000
committerGerrit Code Review <review@openstack.org>2018-08-08 23:34:40 +0000
commitf52ee4f3fde638973c02ceca183c410d4f6a0a46 (patch)
tree5e23c27eec9417e95d3be7484d38f7503d9b8a41
parentc18b1c1bd646d7cefa3d3e4b25ce59460d1a6ebc (diff)
parentf0cc6e68a9b6e6ca052866ba6583a4914ab6cb4e (diff)
downloadnova-f52ee4f3fde638973c02ceca183c410d4f6a0a46.tar.gz
Merge "get provider IDs once when building summaries"
-rw-r--r--nova/api/openstack/placement/objects/resource_provider.py55
1 files changed, 52 insertions, 3 deletions
diff --git a/nova/api/openstack/placement/objects/resource_provider.py b/nova/api/openstack/placement/objects/resource_provider.py
index 851f9719e4..7e2a92f929 100644
--- a/nova/api/openstack/placement/objects/resource_provider.py
+++ b/nova/api/openstack/placement/objects/resource_provider.py
@@ -661,6 +661,47 @@ ProviderIds = collections.namedtuple(
'ProviderIds', 'id uuid parent_id parent_uuid root_id root_uuid')
+def _provider_ids_from_rp_ids(context, rp_ids):
+ """Given an iterable of internal resource provider IDs, returns a dict,
+ keyed by internal provider Id, of ProviderIds namedtuples describing those
+ providers.
+
+ :returns: dict, keyed by internal provider Id, of ProviderIds namedtuples
+ :param rp_ids: iterable of internal provider IDs to look up
+ """
+ # SELECT
+ # rp.id, rp.uuid,
+ # parent.id AS parent_id, parent.uuid AS parent_uuid,
+ # root.id AS root_id, root.uuid AS root_uuid
+ # FROM resource_providers AS rp
+ # LEFT JOIN resource_providers AS parent
+ # ON rp.parent_provider_id = parent.id
+ # LEFT JOIN resource_providers AS root
+ # ON rp.root_provider_id = root.id
+ # WHERE rp.id IN ($rp_ids)
+ me = sa.alias(_RP_TBL, name="me")
+ parent = sa.alias(_RP_TBL, name="parent")
+ root = sa.alias(_RP_TBL, name="root")
+ cols = [
+ me.c.id,
+ me.c.uuid,
+ parent.c.id.label('parent_id'),
+ parent.c.uuid.label('parent_uuid'),
+ root.c.id.label('root_id'),
+ root.c.uuid.label('root_uuid'),
+ ]
+ # TODO(jaypipes): Change this to an inner join when we are sure all
+ # root_provider_id values are NOT NULL
+ me_to_root = sa.outerjoin(me, root, me.c.root_provider_id == root.c.id)
+ me_to_parent = sa.outerjoin(me_to_root, parent,
+ me.c.parent_provider_id == parent.c.id)
+ sel = sa.select(cols).select_from(me_to_parent)
+ sel = sel.where(me.c.id.in_(rp_ids))
+ return {
+ r[0]: ProviderIds(**dict(r)) for r in context.session.execute(sel)
+ }
+
+
def _provider_ids_from_uuid(context, uuid):
"""Given the UUID of a resource provider, returns a namedtuple
(ProviderIds) with the internal ID, the UUID, the parent provider's
@@ -3222,19 +3263,27 @@ def _build_provider_summaries(context, usages, prov_traits):
:param prov_traits: A dict, keyed by internal resource provider ID, of
string trait names associated with that provider
"""
+ # Before we go creating provider summary objects, first grab all the
+ # provider information (including root, parent and UUID information) for
+ # all providers involved in our operation
+ rp_ids = set(usage['resource_provider_id'] for usage in usages)
+ provider_ids = _provider_ids_from_rp_ids(context, rp_ids)
+
# Build up a dict, keyed by internal resource provider ID, of
# ProviderSummary objects containing one or more ProviderSummaryResource
# objects representing the resources the provider has inventory for.
summaries = {}
for usage in usages:
rp_id = usage['resource_provider_id']
- rp_uuid = usage['resource_provider_uuid']
summary = summaries.get(rp_id)
if not summary:
+ pids = provider_ids[rp_id]
summary = ProviderSummary(
context,
- resource_provider=ResourceProvider.get_by_uuid(context,
- uuid=rp_uuid),
+ resource_provider=ResourceProvider(
+ context, id=pids.id, uuid=pids.uuid,
+ root_provider_uuid=pids.root_uuid,
+ parent_provider_uuid=pids.parent_uuid),
resources=[],
)
summaries[rp_id] = summary