]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Pass a Stack entity to Stack.load().
authorSteve Baker <sbaker@redhat.com>
Sun, 11 Nov 2012 19:38:38 +0000 (08:38 +1300)
committerSteve Baker <sbaker@redhat.com>
Sun, 11 Nov 2012 19:49:12 +0000 (08:49 +1300)
Every call to Stack.load (except one) is loading models.Stack then passing just
the ID to Stack.load, which then loads models.Stack again.

As far as I can tell, SQLAlchemy doesn't have a 2nd level cache, so this results
in the db being queried twice.

This change makes it possibe to pass a stack *or* an ID to Stack.load, and
converts all calls to pass in a stack if it is available.

Change-Id: I501ebd403a241cc3b4a5c1e3070137cfc360bbda

heat/engine/api.py
heat/engine/parser.py
heat/engine/service.py
heat/engine/watchrule.py
heat/tests/test_api_cfn_v1.py
heat/tests/test_api_openstack_v1.py
heat/tests/test_engine_service.py

index 2c04db392fa28c4a912be092b8849d2ceb5f28df..08795a97097e5203ddb6efb5ab82d3e9e28beb5b 100644 (file)
@@ -164,7 +164,7 @@ EVENT_KEYS = (
 
 
 def format_event(context, event):
-    stack = parser.Stack.load(context, event.stack.id)
+    stack = parser.Stack.load(context, stack=event.stack)
     result = {
         EVENT_ID: event.id,
         EVENT_STACK_ID: dict(stack.identifier()),
index c0ea0008f83d1a7b4bcbcdbafcf543f02dc9ff6c..eda5af997924050efdafafde0fe0aeb94975dc54 100644 (file)
@@ -95,17 +95,18 @@ class Stack(object):
         return deps
 
     @classmethod
-    def load(cls, context, stack_id, resolve_data=True):
+    def load(cls, context, stack_id=None, stack=None, resolve_data=True):
         '''Retrieve a Stack from the database'''
-        s = db_api.stack_get(context, stack_id)
-        if s is None:
+        if stack is None:
+            stack = db_api.stack_get(context, stack_id)
+        if stack is None:
             message = 'No stack exists with id "%s"' % str(stack_id)
             raise exception.NotFound(message)
 
-        template = Template.load(context, s.raw_template_id)
-        params = Parameters(s.name, template, s.parameters)
-        stack = cls(context, s.name, template, params,
-                    stack_id, s.status, s.status_reason, s.timeout,
+        template = Template.load(context, stack.raw_template_id)
+        params = Parameters(stack.name, template, stack.parameters)
+        stack = cls(context, stack.name, template, params,
+                    stack.id, stack.status, stack.status_reason, stack.timeout,
                     resolve_data)
 
         return stack
index b7d754602f33003dc7da7c0a289ec686ba403eef..07d9dbbb5aa00d0787e320386d88de29a4ce3522 100644 (file)
@@ -69,7 +69,7 @@ class EngineService(service.Service):
         """
         s = db_api.stack_get_by_name(context, stack_name)
         if s:
-            stack = parser.Stack.load(context, s.id)
+            stack = parser.Stack.load(context, stack=s)
             return dict(stack.identifier())
         else:
             raise AttributeError('Unknown stack name')
@@ -102,7 +102,7 @@ class EngineService(service.Service):
         stacks = [self._get_stack(context, stack_identity)]
 
         def format_stack_detail(s):
-            stack = parser.Stack.load(context, s.id)
+            stack = parser.Stack.load(context, stack=s)
             return api.format_stack(stack)
 
         return {'stacks': [format_stack_detail(s) for s in stacks]}
@@ -115,7 +115,7 @@ class EngineService(service.Service):
         stacks = db_api.stack_get_by_tenant(context) or []
 
         def format_stack_detail(s):
-            stack = parser.Stack.load(context, s.id, resolve_data=False)
+            stack = parser.Stack.load(context, stack=s, resolve_data=False)
             return api.format_stack(stack)
 
         return {'stacks': [format_stack_detail(s) for s in stacks]}
@@ -173,7 +173,7 @@ class EngineService(service.Service):
         # Get the database representation of the existing stack
         db_stack = self._get_stack(context, stack_identity)
 
-        current_stack = parser.Stack.load(context, db_stack.id)
+        current_stack = parser.Stack.load(context, stack=db_stack)
 
         # Now parse the template and any parameters for the updated
         # stack definition.
@@ -258,7 +258,7 @@ class EngineService(service.Service):
 
         logger.info('deleting stack %s' % st.name)
 
-        stack = parser.Stack.load(context, st.id)
+        stack = parser.Stack.load(context, stack=st)
 
         # TODO Angus do we need a kill or will stop do?
         if st.id in self.stg:
@@ -314,7 +314,7 @@ class EngineService(service.Service):
     def describe_stack_resource(self, context, stack_identity, resource_name):
         s = self._get_stack(context, stack_identity)
 
-        stack = parser.Stack.load(context, s.id)
+        stack = parser.Stack.load(context, stack=s)
         if resource_name not in stack:
             raise AttributeError('Unknown resource name')
 
@@ -339,7 +339,7 @@ class EngineService(service.Service):
         if not s:
             raise AttributeError("The specified stack doesn't exist")
 
-        stack = parser.Stack.load(context, s.id)
+        stack = parser.Stack.load(context, stack=s)
 
         if logical_resource_id is not None:
             name_match = lambda r: r.name == logical_resource_id
@@ -353,7 +353,7 @@ class EngineService(service.Service):
     def list_stack_resources(self, context, stack_identity):
         s = self._get_stack(context, stack_identity)
 
-        stack = parser.Stack.load(context, s.id)
+        stack = parser.Stack.load(context, stack=s)
 
         return [api.format_stack_resource(resource)
                 for resource in stack if resource.id is not None]
@@ -385,7 +385,7 @@ class EngineService(service.Service):
             logger.warn("Stack %s not found" % stack_name)
             return ['stack', None]
 
-        stack = parser.Stack.load(None, s.id)
+        stack = parser.Stack.load(None, stack=s)
         if resource_name not in stack:
             logger.warn("Resource not found %s:%s." % (stack_name,
                                                        resource_name))
@@ -404,7 +404,7 @@ class EngineService(service.Service):
             logger.warn("Stack %s not found" % stack_id)
             return ['stack', None]
 
-        stack = parser.Stack.load(None, s.id)
+        stack = parser.Stack.load(None, stack=s)
         if resource_name not in stack:
             logger.warn("Resource not found %s:%s." % (stack_id,
                                                        resource_name))
index abc0a109ef79a1d7c715bbef42c5601146cf7a3d..3091cf87f233df53308414bf29dfc8d19bd1fea3 100644 (file)
@@ -233,7 +233,7 @@ class WatchRule(object):
                                   parser.Stack.UPDATE_COMPLETE):
                 user_creds = db_api.user_creds_get(s.user_creds_id)
                 ctxt = ctxtlib.RequestContext.from_dict(user_creds)
-                stack = parser.Stack.load(ctxt, s.id)
+                stack = parser.Stack.load(ctxt, stack=s)
                 for a in self.rule[self.ACTION_MAP[new_state]]:
                     greenpool.spawn_n(stack[a].alarm)
                 actioned = True
index e56f231f6f68364a2851bdfb3778027fab4b39bb..8ba73bbecedff1e2080b382fd4411026743fc05d 100644 (file)
@@ -95,8 +95,8 @@ class StackControllerTest(unittest.TestCase):
                         u'stack_name': u'wordpress',
                         u'stack_status': u'CREATE_COMPLETE'}]}
         self.m.StubOutWithMock(rpc, 'call')
-        rpc.call(dummy_req.context, self.topic, {'method': 'show_stack',
-                                    'args': {'stack_identity': None},
+        rpc.call(dummy_req.context, self.topic, {'method': 'list_stacks',
+                                    'args': {},
                                     'version': self.api_version}, None
                 ).AndReturn(engine_resp)
 
@@ -121,8 +121,8 @@ class StackControllerTest(unittest.TestCase):
         # Insert an engine RPC error and ensure we map correctly to the
         # heat exception type
         self.m.StubOutWithMock(rpc, 'call')
-        rpc.call(dummy_req.context, self.topic, {'method': 'show_stack',
-                                    'args': {'stack_identity': None},
+        rpc.call(dummy_req.context, self.topic, {'method': 'list_stacks',
+                                    'args': {},
                                     'version': self.api_version}, None
                 ).AndRaise(rpc_common.RemoteError("AttributeError"))
 
@@ -140,8 +140,8 @@ class StackControllerTest(unittest.TestCase):
         # Insert an engine RPC error and ensure we map correctly to the
         # heat exception type
         self.m.StubOutWithMock(rpc, 'call')
-        rpc.call(dummy_req.context, self.topic, {'method': 'show_stack',
-                                    'args': {'stack_identity': None},
+        rpc.call(dummy_req.context, self.topic, {'method': 'list_stacks',
+                                    'args': {},
                                     'version': self.api_version}, None
                 ).AndRaise(rpc_common.RemoteError("Exception"))
 
index c5b0387855c91c4ebcd55a305ffd8476a68e130a..667aab3ab8aeb0aa372fe1108a0e773caae6a7e5 100644 (file)
@@ -235,8 +235,8 @@ class StackControllerTest(unittest.TestCase):
         }
         self.m.StubOutWithMock(rpc, 'call')
         rpc.call(req.context, self.topic,
-                 {'method': 'show_stack',
-                  'args': {'stack_identity': None},
+                 {'method': 'list_stacks',
+                  'args': {},
                            'version': self.api_version},
                  None).AndReturn(engine_resp)
         self.m.ReplayAll()
@@ -266,8 +266,8 @@ class StackControllerTest(unittest.TestCase):
 
         self.m.StubOutWithMock(rpc, 'call')
         rpc.call(req.context, self.topic,
-                 {'method': 'show_stack',
-                  'args': {'stack_identity': None},
+                 {'method': 'list_stacks',
+                  'args': {},
                            'version': self.api_version},
                  None).AndRaise(rpc_common.RemoteError("AttributeError"))
         self.m.ReplayAll()
@@ -282,8 +282,8 @@ class StackControllerTest(unittest.TestCase):
 
         self.m.StubOutWithMock(rpc, 'call')
         rpc.call(req.context, self.topic,
-                 {'method': 'show_stack',
-                  'args': {'stack_identity': None},
+                 {'method': 'list_stacks',
+                  'args': {},
                            'version': self.api_version},
                  None).AndRaise(rpc_common.RemoteError("Exception"))
         self.m.ReplayAll()
index 056490c22bc183b7aca1702cc665a375073c2989..6647e284f8a88046b09c428d3b36604adf5e4abb 100644 (file)
@@ -215,13 +215,14 @@ class stackServiceCreateUpdateDeleteTest(unittest.TestCase):
     def test_stack_delete(self):
         stack_name = 'service_delete_test_stack'
         stack = get_wordpress_stack(stack_name, self.ctx)
-        stack.store()
+        sid = stack.store()
 
+        s = db_api.stack_get(self.ctx, sid)
         self.m.StubOutWithMock(parser.Stack, 'load')
         #self.m.StubOutWithMock(threadgroup, 'ThreadGroup')
         #threadgroup.ThreadGroup(stack_name).AndReturn(DummyThreadGroup())
 
-        parser.Stack.load(self.ctx, stack.id).AndReturn(stack)
+        parser.Stack.load(self.ctx, stack=s).AndReturn(stack)
 
         self.m.ReplayAll()
 
@@ -246,13 +247,14 @@ class stackServiceCreateUpdateDeleteTest(unittest.TestCase):
         template = '{ "Template": "data" }'
 
         old_stack = get_wordpress_stack(stack_name, self.ctx)
-        old_stack.store()
+        sid = old_stack.store()
+        s = db_api.stack_get(self.ctx, sid)
 
         stack = get_wordpress_stack(stack_name, self.ctx)
 
         self.m.StubOutWithMock(parser, 'Stack')
         self.m.StubOutWithMock(parser.Stack, 'load')
-        parser.Stack.load(self.ctx, old_stack.id).AndReturn(old_stack)
+        parser.Stack.load(self.ctx, stack=s).AndReturn(old_stack)
 
         self.m.StubOutWithMock(parser, 'Template')
         self.m.StubOutWithMock(parser, 'Parameters')
@@ -283,12 +285,14 @@ class stackServiceCreateUpdateDeleteTest(unittest.TestCase):
 
         old_stack = get_wordpress_stack(stack_name, self.ctx)
         old_stack.store()
+        sid = old_stack.store()
+        s = db_api.stack_get(self.ctx, sid)
 
         stack = get_wordpress_stack(stack_name, self.ctx)
 
         self.m.StubOutWithMock(parser, 'Stack')
         self.m.StubOutWithMock(parser.Stack, 'load')
-        parser.Stack.load(self.ctx, old_stack.id).AndReturn(old_stack)
+        parser.Stack.load(self.ctx, stack=s).AndReturn(old_stack)
 
         self.m.StubOutWithMock(parser, 'Template')
         self.m.StubOutWithMock(parser, 'Parameters')
@@ -426,7 +430,7 @@ class stackServiceTest(unittest.TestCase):
             self.assertTrue('event_time' in ev)
 
     def test_stack_describe_all(self):
-        sl = self.man.show_stack(self.ctx, None)
+        sl = self.man.list_stacks(self.ctx)
 
         self.assertEqual(len(sl['stacks']), 1)
         for s in sl['stacks']:
@@ -438,7 +442,7 @@ class stackServiceTest(unittest.TestCase):
         self.tenant = 'stack_describe_all_empty_tenant'
         self.setUp()
 
-        sl = self.man.show_stack(self.ctx, None)
+        sl = self.man.list_stacks(self.ctx)
 
         self.assertEqual(len(sl['stacks']), 0)