diff --git a/heat/db/sqlalchemy/api.py b/heat/db/sqlalchemy/api.py index b0bdabf132..470ceb9990 100644 --- a/heat/db/sqlalchemy/api.py +++ b/heat/db/sqlalchemy/api.py @@ -173,7 +173,7 @@ def raw_template_files_get(context, files_id): return result -def resource_get(context, resource_id, refresh=False): +def resource_get(context, resource_id, refresh=False, refresh_data=False): result = context.session.query(models.Resource).get(resource_id) if not result: @@ -181,8 +181,9 @@ def resource_get(context, resource_id, refresh=False): resource_id) if refresh: context.session.refresh(result) - # ensure data is loaded (lazy or otherwise) - result.data + if refresh_data: + # ensure data is loaded (lazy or otherwise) + result.data return result diff --git a/heat/engine/check_resource.py b/heat/engine/check_resource.py index 3972b9cac1..96e2ac0238 100644 --- a/heat/engine/check_resource.py +++ b/heat/engine/check_resource.py @@ -57,7 +57,8 @@ class CheckResource(object): def _try_steal_engine_lock(self, cnxt, resource_id): rs_obj = resource_objects.Resource.get_obj(cnxt, - resource_id) + resource_id, + fields=('engine_id', )) if rs_obj.engine_id not in (None, self.engine_id): if not listener_client.EngineListenerClient( rs_obj.engine_id).is_alive(cnxt): diff --git a/heat/engine/resource.py b/heat/engine/resource.py index c647979470..25bca9fe6d 100644 --- a/heat/engine/resource.py +++ b/heat/engine/resource.py @@ -418,7 +418,8 @@ class Resource(status.ResourceStatus): if self._rsrc_metadata is not None: return self._rsrc_metadata rs = resource_objects.Resource.get_obj(self.stack.context, self.id, - refresh=True) + refresh=True, + fields=('rsrc_metadata', )) self._rsrc_metadata = rs.rsrc_metadata return rs.rsrc_metadata @@ -439,8 +440,10 @@ class Resource(status.ResourceStatus): if self.id is None or self.action == self.INIT: raise exception.ResourceNotAvailable(resource_name=self.name) refresh = merge_metadata is not None - db_res = resource_objects.Resource.get_obj(self.stack.context, self.id, - refresh=refresh) + db_res = resource_objects.Resource.get_obj( + self.stack.context, self.id, refresh=refresh, + fields=('rsrc_metadata', 'atomic_key', 'engine_id', + 'action', 'status')) if db_res.action == self.DELETE: self._db_res_is_deleted = True LOG.debug("resource %(name)s, id: %(id)s is DELETE_%(st)s, " @@ -1618,7 +1621,8 @@ class Resource(status.ResourceStatus): try: db_res = resource_objects.Resource.get_obj( - self.context, self.replaced_by) + self.context, self.replaced_by, + fields=('current_template_id', 'atomic_key')) except exception.NotFound: LOG.info("Could not find replacement of resource %(name)s " "with id %(id)s while updating needed_by.", diff --git a/heat/objects/resource.py b/heat/objects/resource.py index 0fea6db1b9..c60c26f60b 100644 --- a/heat/objects/resource.py +++ b/heat/objects/resource.py @@ -100,10 +100,13 @@ class Resource( } @staticmethod - def _from_db_object(resource, context, db_resource): + def _from_db_object(resource, context, db_resource, only_fields=None): if db_resource is None: return None for field in resource.fields: + if (only_fields is not None and field not in only_fields + and field != 'id'): + continue if field == 'data': resource['data'] = [resource_data.ResourceData._from_db_object( resource_data.ResourceData(context), resd @@ -150,10 +153,16 @@ class Resource( return self._properties_data @classmethod - def get_obj(cls, context, resource_id, refresh=False): + def get_obj(cls, context, resource_id, refresh=False, fields=None): + if fields is None or 'data' in fields: + refresh_data = refresh + else: + refresh_data = False resource_db = db_api.resource_get(context, resource_id, - refresh=refresh) - return cls._from_db_object(cls(context), context, resource_db) + refresh=refresh, + refresh_data=refresh_data) + return cls._from_db_object(cls(context), context, resource_db, + only_fields=fields) @classmethod def get_all(cls, context): diff --git a/heat/tests/test_resource.py b/heat/tests/test_resource.py index 714bb0d58e..68c856a54e 100644 --- a/heat/tests/test_resource.py +++ b/heat/tests/test_resource.py @@ -582,6 +582,16 @@ class ResourceTest(common.HeatTestCase): res.store() self.assertIsNotNone(res.updated_time) + def test_resource_object_get_obj_fields(self): + snippet = rsrc_defn.ResourceDefinition('aresource', + 'GenericResourceType') + res = resource.Resource('aresource', snippet, self.stack) + res.store() + res_obj = resource_objects.Resource.get_obj( + res.context, res.id, refresh=False, fields=('status', )) + self.assertEqual(res_obj.status, res.COMPLETE) + self.assertRaises(AttributeError, getattr, res_obj, 'action') + def test_resource_object_resource_properties_data(self): cfg.CONF.set_override('encrypt_parameters_and_properties', True, enforce_type=True)