From 57c5aae88b908002d84a933738293c5917926174 Mon Sep 17 00:00:00 2001 From: Crag Wolfe Date: Wed, 31 Aug 2016 01:47:58 -0400 Subject: De-duplicate properties_data between events, resources Properties data (encrypted or not) is now stored in the resource_properties_data table. We still support reading properties data from the legacy locations (separate columns in the resource and event tables) but all new properties data are written to resource_properties_data. Instead of duplicating properties data for a given resource and its events, we refer to the same resource_properties_data object from both resources and events. Notes about encrypting/decrypting properties data: 1. ResourcePropertiesData takes care of encrypting/decrypting, so consumers (events and resources) don't have to worry about it. 2. Previously (not anymore), heat.engine.resource would take care of the encrypting in _store() and _store_or_update(). 3. Previously and currently, heat.object.resource decrypts the legacy properties_data field if needed. Change-Id: I569e16d4a7d3f5ccc22d57fe881c4fd5994677ac Closes-Bug: #1524013 --- heat/engine/resource.py | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'heat/engine/resource.py') diff --git a/heat/engine/resource.py b/heat/engine/resource.py index a5b369bb2..3326c5ed3 100644 --- a/heat/engine/resource.py +++ b/heat/engine/resource.py @@ -44,6 +44,7 @@ from heat.engine import scheduler from heat.engine import support from heat.objects import resource as resource_objects from heat.objects import resource_data as resource_data_objects +from heat.objects import resource_properties_data as rpd_objects from heat.objects import stack as stack_objects from heat.rpc import client as rpc_client @@ -249,6 +250,7 @@ class Resource(object): self.uuid = None self._data = None self._rsrc_metadata = None + self._rsrc_prop_data = None self._stored_properties_data = None self.created_time = stack.created_time self.updated_time = stack.updated_time @@ -291,6 +293,7 @@ class Resource(object): self._data = {} self._rsrc_metadata = resource.rsrc_metadata self._stored_properties_data = resource.properties_data + self._rsrc_prop_data = resource.rsrc_prop_data self.created_time = resource.created_at self.updated_time = resource.updated_at self.needed_by = resource.needed_by @@ -350,7 +353,7 @@ class Resource(object): # Don't set physical_resource_id so that a create is triggered. rs = {'stack_id': self.stack.id, 'name': self.name, - 'properties_data': self._stored_properties_data, + 'rsrc_prop_data_id': self._create_or_replace_rsrc_prop_data(), 'needed_by': self.needed_by, 'requires': self.requires, 'replaces': self.id, @@ -858,7 +861,10 @@ class Resource(object): yield self.action_handler_task(action, args=handler_args) def _update_stored_properties(self): + old_props = self._stored_properties_data self._stored_properties_data = function.resolve(self.properties.data) + if self._stored_properties_data != old_props: + self._rsrc_prop_data = None def preview(self): """Default implementation of Resource.preview. @@ -1721,10 +1727,6 @@ class Resource(object): def _store(self, metadata=None): """Create the resource in the database.""" - - properties_data_encrypted, properties_data = ( - resource_objects.Resource.encrypt_properties_data( - self._stored_properties_data)) if not self.root_stack_id: self.root_stack_id = self.stack.root_stack_id() try: @@ -1735,8 +1737,8 @@ class Resource(object): 'physical_resource_id': self.resource_id, 'name': self.name, 'rsrc_metadata': metadata, - 'properties_data': properties_data, - 'properties_data_encrypted': properties_data_encrypted, + 'rsrc_prop_data_id': + self._create_or_replace_rsrc_prop_data(), 'needed_by': self.needed_by, 'requires': self.requires, 'replaces': self.replaces, @@ -1744,7 +1746,6 @@ class Resource(object): 'current_template_id': self.current_template_id, 'stack_name': self.stack.name, 'root_stack_id': self.root_stack_id} - new_rs = resource_objects.Resource.create(self.context, rs) self.id = new_rs.id self.uuid = new_rs.uuid @@ -1757,7 +1758,7 @@ class Resource(object): """Add a state change event to the database.""" physical_res_id = self.resource_id or self.physical_resource_name() ev = event.Event(self.context, self.stack, action, status, reason, - physical_res_id, self.properties, + physical_res_id, self._rsrc_prop_data, self.name, self.type()) ev.store() @@ -1769,18 +1770,15 @@ class Resource(object): self.status = status self.status_reason = reason - properties_data_encrypted, properties_data = ( - resource_objects.Resource.encrypt_properties_data( - self._stored_properties_data)) data = { 'action': self.action, 'status': self.status, 'status_reason': reason, 'stack_id': self.stack.id, 'updated_at': self.updated_time, - 'properties_data': properties_data, - 'properties_data_encrypted': properties_data_encrypted, 'needed_by': self.needed_by, + 'rsrc_prop_data_id': self._create_or_replace_rsrc_prop_data(), + 'properties_data': None, 'requires': self.requires, 'replaces': self.replaces, 'replaced_by': self.replaced_by, @@ -2286,6 +2284,18 @@ class Resource(object): self._data = None return True + def _create_or_replace_rsrc_prop_data(self): + if self._rsrc_prop_data is not None: + return self._rsrc_prop_data.id + + if not self._stored_properties_data: + return None + + self._rsrc_prop_data = \ + rpd_objects.ResourcePropertiesData(self.context).create( + self.context, self._stored_properties_data) + return self._rsrc_prop_data.id + def is_using_neutron(self): try: sess_client = self.client('neutron').httpclient -- cgit v1.2.1