DB query to get all resources by the root stack

To prevent a resource query for every nested stack during a
resource-list, there needs to be a way to fetch every resource in a
single query.

Change-Id: Ib05b2166d6c7584a844e1ab4a5dd6e35437c96c4
Related-Bug: #1578854
This commit is contained in:
Steve Baker 2016-05-16 11:01:31 +12:00
parent 9852d79ac7
commit de99472c75
4 changed files with 73 additions and 0 deletions

View File

@ -129,6 +129,10 @@ def resource_get_all_active_by_stack(context, stack_id):
return IMPL.resource_get_all_active_by_stack(context, stack_id)
def resource_get_all_by_root_stack(context, stack_id, filters=None):
return IMPL.resource_get_all_by_root_stack(context, stack_id, filters)
def resource_get_by_name_and_stack(context, resource_name, stack_id):
return IMPL.resource_get_by_name_and_stack(context,
resource_name, stack_id)

View File

@ -373,6 +373,19 @@ def resource_get_all_active_by_stack(context, stack_id):
return dict((res.id, res) for res in results)
def resource_get_all_by_root_stack(context, stack_id, filters=None):
query = model_query(
context, models.Resource
).filter_by(
root_stack_id=stack_id
).options(orm.joinedload("data"))
query = db_filters.exact_filter(query, models.Resource, filters)
results = query.all()
return dict((res.id, res) for res in results)
def stack_get_by_name_and_owner_id(context, stack_name, owner_id):
query = soft_delete_aware_query(
context, models.Stack

View File

@ -138,6 +138,10 @@ class Resource(
def get_all_by_stack(cls, context, stack_id, filters=None):
resources_db = db_api.resource_get_all_by_stack(context, stack_id,
filters)
return cls._resources_to_dict(context, resources_db)
@classmethod
def _resources_to_dict(cls, context, resources_db):
resources = [
(
resource_name,
@ -160,6 +164,14 @@ class Resource(
]
return dict(resources)
@classmethod
def get_all_by_root_stack(cls, context, stack_id, filters):
resources_db = db_api.resource_get_all_by_root_stack(
context,
stack_id,
filters)
return cls._resources_to_dict(context, resources_db)
@classmethod
def get_by_name_and_stack(cls, context, resource_name, stack_id):
resource_db = db_api.resource_get_by_name_and_stack(

View File

@ -2278,6 +2278,50 @@ class DBAPIResourceTest(common.HeatTestCase):
for rsrc_id, res in resources.items():
self.assertIn(res.name, ['res2', 'res3', 'res4', 'res5', 'res6'])
def test_resource_get_all_by_root_stack(self):
self.stack1 = create_stack(self.ctx, self.template, self.user_creds)
self.stack2 = create_stack(self.ctx, self.template, self.user_creds)
create_resource(self.ctx, self.stack, name='res1',
root_stack_id=self.stack.id)
create_resource(self.ctx, self.stack, name='res2',
root_stack_id=self.stack.id)
create_resource(self.ctx, self.stack, name='res3',
root_stack_id=self.stack.id)
create_resource(self.ctx, self.stack1, name='res4',
root_stack_id=self.stack.id)
# Test for all resources in a stack
resources = db_api.resource_get_all_by_root_stack(
self.ctx, self.stack.id)
self.assertEqual(4, len(resources))
resource_names = [r.name for r in resources.values()]
self.assertEqual(['res1', 'res2', 'res3', 'res4'],
sorted(resource_names))
# Test for resources matching single entry
resources = db_api.resource_get_all_by_root_stack(
self.ctx, self.stack.id, filters=dict(name='res1'))
self.assertEqual(1, len(resources))
resource_names = [r.name for r in resources.values()]
self.assertEqual(['res1'], resource_names)
self.assertEqual(1, len(resources))
# Test for resources matching multi entry
resources = db_api.resource_get_all_by_root_stack(
self.ctx, self.stack.id, filters=dict(name=[
'res1',
'res2'
])
)
self.assertEqual(2, len(resources))
resource_names = [r.name for r in resources.values()]
self.assertEqual(['res1', 'res2'],
sorted(resource_names))
self.assertEqual({}, db_api.resource_get_all_by_root_stack(
self.ctx, self.stack2.id))
class DBAPIStackLockTest(common.HeatTestCase):
def setUp(self):