Merge "Eager load event's resource prop. data when appropiate"

This commit is contained in:
Jenkins 2017-03-15 03:35:08 +00:00 committed by Gerrit Code Review
commit 4dc101f10e
4 changed files with 43 additions and 11 deletions

View File

@ -846,6 +846,9 @@ def _query_all_by_stack(context, stack_id):
def event_get_all_by_stack(context, stack_id, limit=None, marker=None,
sort_keys=None, sort_dir=None, filters=None):
query = _query_all_by_stack(context, stack_id)
if filters and 'uuid' in filters:
# retrieving a single event, so eager load its rsrc_prop_data detail
query = query.options(orm.joinedload("rsrc_prop_data"))
return _events_filter_and_page_query(context, query, limit, marker,
sort_keys, sort_dir, filters).all()

View File

@ -14,14 +14,18 @@
"""Event object."""
from oslo_log import log as logging
from oslo_versionedobjects import base
from oslo_versionedobjects import fields
from heat.common.i18n import _LI
from heat.common import identifier
from heat.db.sqlalchemy import api as db_api
from heat.objects import base as heat_base
from heat.objects import resource_properties_data as rpd
LOG = logging.getLogger(__name__)
class Event(
heat_base.HeatObject,
@ -45,16 +49,30 @@ class Event(
@staticmethod
def _from_db_object(context, event, db_event):
event._resource_properties = None
for field in event.fields:
if field == 'resource_status_reason':
# this works whether db_event is a dict or db ref
event[field] = db_event['_resource_status_reason']
else:
event[field] = db_event[field]
if db_event['rsrc_prop_data_id'] is not None:
event._resource_properties = None
else:
if db_event['rsrc_prop_data_id'] is None:
event._resource_properties = db_event['resource_properties'] or {}
else:
if hasattr(db_event, '__dict__'):
rpd_obj = db_event.__dict__.get('rsrc_prop_data')
elif hasattr(db_event, 'rsrc_prop_data'):
rpd_obj = db_event['rsrc_prop_data']
else:
rpd_obj = None
if rpd_obj is not None:
# Object is already eager loaded
rpd_obj = (
rpd.ResourcePropertiesData._from_db_object(
rpd.ResourcePropertiesData(),
context,
rpd_obj))
event._resource_properties = rpd_obj.data
event._context = context
event.obj_reset_changes()
return event
@ -62,6 +80,7 @@ class Event(
@property
def resource_properties(self):
if self._resource_properties is None:
LOG.info(_LI('rsrp_prop_data lazy load'))
rpd_obj = rpd.ResourcePropertiesData.get_by_id(
self._context, self.rsrc_prop_data_id)
self._resource_properties = rpd_obj.data or {}

View File

@ -58,14 +58,15 @@ class FormatTest(common.HeatTestCase):
def _dummy_event(self, res_properties=None):
resource = self.stack['generic1']
ev_uuid = 'abc123yc-9f88-404d-a85b-531529456xyz'
ev = event.Event(self.context, self.stack, 'CREATE',
'COMPLETE', 'state changed',
'z3455xyc-9f88-404d-a85b-5315293e67de',
res_properties, resource.name, resource.type(),
uuid='abc123yc-9f88-404d-a85b-531529456xyz')
uuid=ev_uuid)
ev.store()
return event_object.Event.get_all_by_stack(self.context,
self.stack.id)[0]
return event_object.Event.get_all_by_stack(
self.context, self.stack.id, filters={'uuid': ev_uuid})[0]
def test_format_stack_resource(self):
self.stack.created_time = datetime(2015, 8, 3, 17, 5, 1)

View File

@ -254,13 +254,11 @@ class EventTest(EventCommon):
data = {'p1': 'hello',
'p2': 'too soon?'}
rpd_obj = rpd_object.ResourcePropertiesData().create(self.ctx, data)
rpd_db_obj = self.ctx.session.query(
models.ResourcePropertiesData).get(rpd_obj.id)
e_obj = event_object.Event().create(
self.ctx,
{'stack_id': self.stack.id,
'uuid': str(uuid.uuid4()),
'rsrc_prop_data_id': rpd_db_obj.id})
'rsrc_prop_data_id': rpd_obj.id})
e_obj = event_object.Event.get_all_by_stack(utils.dummy_context(),
self.stack.id)[0]
# properties data appears unencrypted to event object
@ -290,8 +288,19 @@ class EventEncryptedTest(EventCommon):
results[0]['data']['Foo'])
self.assertTrue(results[0]['encrypted'])
# verify encrypted data is decrypted when retrieved through
# heat object layer
ev = event_object.Event.get_all_by_stack(self.ctx,
self.stack.id)[0]
# verify not eager loaded
self.assertIsNone(ev._resource_properties)
# verify encrypted data is decrypted when retrieved through
# heat object layer (normally it would be eager loaded)
self.assertEqual({'Foo': 'goo'}, ev.resource_properties)
# verify eager load case (uuid is specified)
filters = {'uuid': ev.uuid}
ev = event_object.Event.get_all_by_stack(self.ctx,
self.stack.id,
filters=filters)[0]
# verify eager loaded
self.assertIsNotNone(ev._resource_properties)
self.assertEqual({'Foo': 'goo'}, ev.resource_properties)