Don't load nested stack to build the identifier

StackResource is already building HeatIdentifier for the nested stack,
so this should be used by the resource formatter to avoid the overhead
of loading the nested stack.

Change-Id: Iab7a997c0b4d9dcb8ceb3d2f49692216fe611df1
Partial-Bug: #1578854
changes/06/314806/6
Steve Baker 2016-05-11 10:38:20 +12:00
parent 2969f0a49e
commit 0ef5d601c0
5 changed files with 31 additions and 32 deletions

View File

@ -314,9 +314,11 @@ def format_stack_resource(resource, detail=True, with_props=False,
rpc_api.RES_REQUIRED_BY: resource.required_by(),
}
if resource.has_nested():
try:
res[rpc_api.RES_NESTED_STACK_ID] = dict(
resource.nested().identifier())
resource.nested_identifier())
except (AttributeError, TypeError):
pass
if resource.stack.parent_resource_name:
res[rpc_api.RES_PARENT_RESOURCE] = resource.stack.parent_resource_name

View File

@ -119,20 +119,21 @@ class StackResource(resource.Resource):
prev_resource)
except StopIteration:
with excutils.save_and_reraise_exception():
stack_identity = identifier.HeatIdentifier(
self.context.tenant_id,
self.physical_resource_name(),
self.resource_id)
stack_identity = self.nested_identifier()
self.rpc_client().stack_cancel_update(
self.context,
dict(stack_identity),
cancel_with_rollback=False)
def has_nested(self):
if self.nested() is not None:
return True
def nested_identifier(self):
return identifier.HeatIdentifier(
self.context.tenant_id,
self.physical_resource_name(),
self.resource_id)
return False
def has_nested(self):
# This class and its subclasses manage nested stacks
return True
def nested(self):
"""Return a Stack object representing the nested (child) stack.
@ -497,10 +498,7 @@ class StackResource(resource.Resource):
if stack is None:
raise exception.Error(_('Cannot suspend %s, stack not created')
% self.name)
stack_identity = identifier.HeatIdentifier(
self.context.tenant_id,
self.physical_resource_name(),
self.resource_id)
stack_identity = self.nested_identifier()
self.rpc_client().stack_suspend(self.context, dict(stack_identity))
def check_suspend_complete(self, cookie=None):
@ -511,10 +509,7 @@ class StackResource(resource.Resource):
if stack is None:
raise exception.Error(_('Cannot resume %s, stack not created')
% self.name)
stack_identity = identifier.HeatIdentifier(
self.context.tenant_id,
self.physical_resource_name(),
self.resource_id)
stack_identity = self.nested_identifier()
self.rpc_client().stack_resume(self.context, dict(stack_identity))
def check_resume_complete(self, cookie=None):
@ -526,10 +521,7 @@ class StackResource(resource.Resource):
raise exception.Error(_('Cannot check %s, stack not created')
% self.name)
stack_identity = identifier.HeatIdentifier(
self.context.tenant_id,
self.physical_resource_name(),
self.resource_id)
stack_identity = self.nested_identifier()
self.rpc_client().stack_check(self.context, dict(stack_identity))
def check_check_complete(self, cookie=None):

View File

@ -1057,7 +1057,7 @@ class EngineService(service.Service):
def _n_deleted(stk, deleted):
for rsrc in deleted:
deleted_rsrc = stk.resources.get(rsrc)
if deleted_rsrc.has_nested():
if deleted_rsrc.has_nested() and deleted_rsrc.nested():
nested_stk = deleted_rsrc.nested()
nested_rsrc = nested_stk.resources.keys()
n_fmt = fmt_action_map(
@ -1071,7 +1071,7 @@ class EngineService(service.Service):
def _n_added(stk, added):
for rsrc in added:
added_rsrc = stk.resources.get(rsrc)
if added_rsrc.has_nested():
if added_rsrc.has_nested() and added_rsrc.nested():
nested_stk = added_rsrc.nested()
nested_rsrc = nested_stk.resources.keys()
n_fmt = fmt_action_map(
@ -1084,7 +1084,10 @@ class EngineService(service.Service):
for rsrc in act['updated']:
current_rsrc = current.resources.get(rsrc)
updated_rsrc = updated.resources.get(rsrc)
if current_rsrc.has_nested() and updated_rsrc.has_nested():
if (current_rsrc.has_nested()
and current_rsrc.nested()
and updated_rsrc.has_nested()
and updated_rsrc.nested()):
current_nested = current_rsrc.nested()
updated_nested = updated_rsrc.nested()
update_task = update.StackUpdate(

View File

@ -324,6 +324,8 @@ class Stack(collections.Mapping):
continue
nested_stack = res.nested()
if not nested_stack:
continue
for nested_res in nested_stack.iter_resources(nested_depth - 1):
yield nested_res
@ -1047,7 +1049,7 @@ class Stack(collections.Mapping):
def supports_check_action(self):
def is_supported(stack, res):
if res.has_nested():
if res.has_nested() and res.nested():
return res.nested().supports_check_action()
else:
return hasattr(res, 'handle_%s' % self.CHECK.lower())

View File

@ -206,8 +206,8 @@ class FormatTest(common.HeatTestCase):
def test_format_stack_resource_with_nested_stack(self):
res = self.stack['generic4']
nested_id = {'foo': 'bar'}
res.nested = mock.Mock()
res.nested.return_value.identifier.return_value = nested_id
res.nested_identifier = mock.Mock()
res.nested_identifier.return_value = nested_id
formatted = api.format_stack_resource(res, False)
self.assertEqual(nested_id, formatted[rpc_api.RES_NESTED_STACK_ID])
@ -229,6 +229,7 @@ class FormatTest(common.HeatTestCase):
rpc_api.RES_ID,
rpc_api.RES_STACK_ID,
rpc_api.RES_STACK_NAME,
rpc_api.RES_NESTED_STACK_ID,
rpc_api.RES_REQUIRED_BY))
formatted = api.format_stack_resource(res, False)
@ -251,6 +252,7 @@ class FormatTest(common.HeatTestCase):
rpc_api.RES_ID,
rpc_api.RES_STACK_ID,
rpc_api.RES_STACK_NAME,
rpc_api.RES_NESTED_STACK_ID,
rpc_api.RES_REQUIRED_BY))
formatted = api.format_stack_resource(res, False)
@ -261,12 +263,10 @@ class FormatTest(common.HeatTestCase):
res = self.stack['generic4']
nested_id = {'foo': 'bar'}
res.nested = mock.MagicMock()
res.nested.return_value.identifier.return_value = nested_id
res.nested.return_value.__len__.return_value = 0
res.nested_identifier = mock.Mock()
res.nested_identifier.return_value = nested_id
formatted = api.format_stack_resource(res, False)
res.nested.return_value.identifier.assert_called_once_with()
self.assertEqual(nested_id, formatted[rpc_api.RES_NESTED_STACK_ID])
def test_format_stack_resource_required_by(self):