From 419dcc7ce0319f4b7165ba13e1423cec91a69bea Mon Sep 17 00:00:00 2001 From: melanie witt Date: Wed, 25 Aug 2021 17:36:32 +0000 Subject: [PATCH] Refactor consumer type methods for readability This contains fixups for change I24c2315093e07dbf25c4fb53152e6a4de7477a51 to rename a method to more accurately convey what it does, refactor a keyword arg in a method to increase readability, and update the reshaper request example to show the latest available version 1.38. Story: 2005473 Task: 36421 Change-Id: If6d8ae575400fb8d2f78c871ff7394e9fbcf5816 --- api-ref/source/reshaper.inc | 2 +- placement/handlers/util.py | 8 ++++---- placement/objects/usage.py | 30 +++++++++++++++++++++--------- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/api-ref/source/reshaper.inc b/api-ref/source/reshaper.inc index 67651f4c0..81cfe3cab 100644 --- a/api-ref/source/reshaper.inc +++ b/api-ref/source/reshaper.inc @@ -45,7 +45,7 @@ Request Request Example --------------- -.. literalinclude:: ./samples/reshaper/post-reshaper-1.30.json +.. literalinclude:: ./samples/reshaper/post-reshaper-1.38.json :language: javascript No body content is returned on a successful POST. diff --git a/placement/handlers/util.py b/placement/handlers/util.py index d397663b5..7c52f9f86 100644 --- a/placement/handlers/util.py +++ b/placement/handlers/util.py @@ -25,7 +25,7 @@ from placement.objects import user as user_obj LOG = logging.getLogger(__name__) -def fetch_consumer_type_id(ctx, name): +def get_or_create_consumer_type_id(ctx, name): """Tries to fetch the provided consumer_type and creates a new one if it does not exist. @@ -42,7 +42,7 @@ def fetch_consumer_type_id(ctx, name): return cons_type.id except exception.ConsumerTypeExists: # another thread created concurrently, so try again - return fetch_consumer_type_id(ctx, name) + return get_or_create_consumer_type_id(ctx, name) def _get_or_create_project(ctx, project_id): @@ -174,7 +174,7 @@ def ensure_consumer(ctx, consumer_uuid, project_id, user_id, consumer.update() # Update the consumer type if it's different than the existing one. if requires_consumer_type: - cons_type_id = fetch_consumer_type_id(ctx, consumer_type) + cons_type_id = get_or_create_consumer_type_id(ctx, consumer_type) if cons_type_id != consumer.consumer_type_id: LOG.debug("Supplied consumer type for consumer %s was " "different than existing record. Updating " @@ -193,7 +193,7 @@ def ensure_consumer(ctx, consumer_uuid, project_id, user_id, 'consumer generation conflict - ' 'expected null but got %s' % consumer_generation, comment=errors.CONCURRENT_UPDATE) - cons_type_id = (fetch_consumer_type_id(ctx, consumer_type) + cons_type_id = (get_or_create_consumer_type_id(ctx, consumer_type) if requires_consumer_type else None) # No such consumer. This is common for new allocations. Create the # consumer record diff --git a/placement/objects/usage.py b/placement/objects/usage.py index 02d08cff6..a5c3bd1af 100644 --- a/placement/objects/usage.py +++ b/placement/objects/usage.py @@ -74,7 +74,22 @@ def _get_all_by_resource_provider_uuid(context, rp_uuid): @db_api.placement_context_manager.reader def _get_all_by_project_user(context, project_id, user_id=None, - consumer_type=False): + consumer_type=None): + """Get usages by project, user, and consumer type. + + When consumer_type is *not* "all" or "unknown", usages will be returned + without regard to consumer type (behavior prior to microversion 1.38). + + :param context: `placement.context.RequestContext` that + contains an oslo_db Session + :param project_id: The project ID for which to get usages + :param user_id: The optional user ID for which to get usages + :param consumer_type: Optionally filter usages by consumer type, "all" or + "unknown". If "all" is specified, all results will be + grouped under one key, "all". If "unknown" is + specified, all results will be grouped under one key, + "unknown". + """ query = (context.session.query(models.Allocation.resource_class_id, func.coalesce(func.sum(models.Allocation.used), 0)) .join(models.Consumer, @@ -88,9 +103,7 @@ def _get_all_by_project_user(context, project_id, user_id=None, query = query.filter(models.User.external_id == user_id) query = query.group_by(models.Allocation.resource_class_id) - # Handle 'all' or 'unknown' consumer type. The consumer_type is True if - # 'all' is requested, and None if 'unknown' is requested. - if consumer_type is None or consumer_type: + if consumer_type in ('all', 'unknown'): # NOTE(melwitt): We have to count the number of consumers in a separate # query in order to get a count of unique consumers. If we count in the # same query after grouping by resource class, we will count duplicate @@ -109,18 +122,18 @@ def _get_all_by_project_user(context, project_id, user_id=None, models.User, models.Consumer.user_id == models.User.id) count_query = count_query.filter( models.User.external_id == user_id) - if consumer_type is None: + if consumer_type == 'unknown': count_query = count_query.filter( models.Consumer.consumer_type_id == sa.null()) number_of_unique_consumers = count_query.scalar() # Filter for unknown consumer type if specified. - if consumer_type is None: + if consumer_type == 'unknown': query = query.filter(models.Consumer.consumer_type_id == sa.null()) result = [dict(resource_class=context.rc_cache.string_from_id(item[0]), usage=item[1], - consumer_type='all' if consumer_type else 'unknown', + consumer_type=consumer_type, consumer_count=number_of_unique_consumers) for item in query.all()] else: @@ -135,9 +148,8 @@ def _get_all_by_project_user(context, project_id, user_id=None, def _get_by_consumer_type(context, project_id, user_id=None, consumer_type=None): if consumer_type in ('all', 'unknown'): - cons_type = True if consumer_type == 'all' else None return _get_all_by_project_user(context, project_id, user_id, - consumer_type=cons_type) + consumer_type=consumer_type) query = (context.session.query( models.Allocation.resource_class_id,