Avoid full stack load for identify_stack

identify_stack is used to redirect API requests to the canonical stack
URL. The current approach results in 3 SQL queries to fetch the stack,
the raw template, and the tags.

This change uses the stack object directly to return the identifier.
It doesn't actually change any data access patterns but makes it
possible to avoid the loading of raw template and stack tags in future
changes.

Change-Id: Ic96e1492880368b3d25579893c10c5bd0ca2f165
Partial-Bug: #1578851
This commit is contained in:
Steve Baker 2016-05-18 11:25:35 +12:00
parent b3c228d707
commit e416943538
2 changed files with 6 additions and 29 deletions

View File

@ -460,6 +460,7 @@ class EngineService(service.Service):
:param cnxt: RPC context.
:param stack_name: Name or UUID of the stack to look up.
"""
s = None
if uuidutils.is_uuid_like(stack_name):
s = stack_object.Stack.get_by_id(
cnxt,
@ -467,15 +468,11 @@ class EngineService(service.Service):
show_deleted=True)
# may be the name is in uuid format, so if get by id returns None,
# we should get the info by name again
if not s:
s = stack_object.Stack.get_by_name(cnxt, stack_name)
else:
if not s:
s = stack_object.Stack.get_by_name(cnxt, stack_name)
if s:
stack = parser.Stack.load(cnxt, stack=s)
return dict(stack.identifier())
else:
if not s:
raise exception.EntityNotFound(entity='Stack', name=stack_name)
return dict(s.identifier())
def _get_stack(self, cnxt, stack_identity, show_deleted=False):
identity = identifier.HeatIdentifier(**stack_identity)

View File

@ -413,40 +413,19 @@ class StackServiceTest(common.HeatTestCase):
@tools.stack_context('service_identify_test_stack', False)
def test_stack_identify(self):
self.m.StubOutWithMock(parser.Stack, 'load')
parser.Stack.load(self.ctx,
stack=mox.IgnoreArg()).AndReturn(self.stack)
self.m.ReplayAll()
identity = self.eng.identify_stack(self.ctx, self.stack.name)
self.assertEqual(self.stack.identifier(), identity)
self.m.VerifyAll()
@tools.stack_context('ef0c41a4-644f-447c-ad80-7eecb0becf79', False)
def test_stack_identify_by_name_in_uuid(self):
self.m.StubOutWithMock(parser.Stack, 'load')
parser.Stack.load(self.ctx,
stack=mox.IgnoreArg()).AndReturn(self.stack)
self.m.ReplayAll()
identity = self.eng.identify_stack(self.ctx, self.stack.name)
self.assertEqual(self.stack.identifier(), identity)
self.m.VerifyAll()
@tools.stack_context('service_identify_uuid_test_stack', False)
def test_stack_identify_uuid(self):
self.m.StubOutWithMock(parser.Stack, 'load')
parser.Stack.load(self.ctx,
stack=mox.IgnoreArg()).AndReturn(self.stack)
self.m.ReplayAll()
identity = self.eng.identify_stack(self.ctx, self.stack.id)
self.assertEqual(self.stack.identifier(), identity)
self.m.VerifyAll()
def test_stack_identify_nonexist(self):
ex = self.assertRaises(dispatcher.ExpectedException,
self.eng.identify_stack, self.ctx, 'wibble')
@ -463,7 +442,8 @@ class StackServiceTest(common.HeatTestCase):
def test_stack_by_name_tenants(self):
self.assertEqual(
self.stack.id,
stack_object.Stack.get_by_name(self.ctx, self.stack.name).id)
stack_object.Stack.get_by_name(self.ctx, self.stack.name).id
)
ctx2 = utils.dummy_context(tenant_id='stack_service_test_tenant2')
self.assertIsNone(stack_object.Stack.get_by_name(
ctx2,