Eager load event's resource prop. data when appropiate
Eager load an event's resource properties data in the list_events "show event" case, i.e. when an event uuid is specified. When showing multiple events, the events' resource properties data should not be eager loaded. Change-Id: I12e371dcbdae398360e28200e68f4a75831f8f17 Closes-bug: #1665506
This commit is contained in:
parent
3e30b16624
commit
283b2d3985
@ -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()
|
||||
|
||||
|
@ -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 {}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user