Commit a38b9025 authored by Ayush Tiwari's avatar Ayush Tiwari Committed by Ayush Tiwari

bt5_config: Update function for comparing old state with ZODB changes

parent b35e4e2f
...@@ -1683,55 +1683,79 @@ class TemplateTool (BaseTool): ...@@ -1683,55 +1683,79 @@ class TemplateTool (BaseTool):
6. If conflict while comaprison at 3, raise the error 6. If conflict while comaprison at 3, raise the error
7. In all other case, install the BM List 7. In all other case, install the BM List
""" """
# Try getting a Business Manager with the title 'Combined Business Manager' # Create old installation state from Instsalled Business Manager
# which we would need to compare. Also using search keeping in mind we installed_bm_list = self.getInstalledBusinessManagerList()
# index Business Manager(s) combined_installed_path_item = [item for bm
installation_state_list = [l for l in installed_bm_list
in self.objectValues(portal_type='Business Manager') for item in bm._path_item_list]
if l.title == 'Installation State']
# Create BM for old installation state and update its path item list
# If there is 1 or more Business Manager(s) with 'Combined Business Manager'
# title, take the firs one, cause it is the one created currently
if len(installation_state_list) :
old_installation_state = installation_state_list[-1]
else:
# Create a new Business Manager which we'll use for comapring installation
# state
old_installation_state = self.newContent( old_installation_state = self.newContent(
portal_type='Business Manager', portal_type='Business Manager',
title='Installation State', title='Old Installation State',
) )
old_installation_state.build() old_installation_state._path_item_list = combined_installed_path_item
# XXX: We can also create old_installation_state BM by other ways, namely
# 1. Combining the Business Item list from all the installed states of forbidden_bm_title_list = ['Old Installation State',]
# last BM(s) for bm in bm_list:
# 2.. forbidden_bm_title_list.append(bm.title)
# Create Single Business Manager by comparing the old_installation_state new_installed_bm_list = [l for l
# with the list of BM(s) we want to install currently. This also should in self.getInstalledBusinessManagerList()
# reduce the combined Business Manager. if l.title not in forbidden_bm_title_list]
new_installation_state = self.createNewInstallationState( new_installed_bm_list.extend(bm_list)
bm_list,
old_installation_state combined_new_path_item = [item for bm
in new_installed_bm_list
for item in bm._path_item_list]
# Create BM for new installation state and update its path item list
new_installation_state = self.newContent(
portal_type='Business Manager',
title='New Installation State',
) )
new_installation_state._path_item_list = combined_new_path_item
# Build Business Manager from ZODB and compare the changes done by # Create installation process, which have the changes to be made in the
# the user which might get affected. # OFS during installation. Importantly, it should also be a Business Manager
buildBM = self.newContent(portal_type='Business Manager') installation_process = self.newContent(
final_template_path_list = list(set(new_installation_state.getTemplatePathList())) portal_type='Business Manager',
buildBM._setTemplatePathList(final_template_path_list) title='Installation Process',
buildBM.build() )
# Compare installation state with OFS state # Get path list for old and new states
self.compareInstallationStateWithOFS(buildBM, old_state_path_list = old_installation_state.getPathList()
new_installation_state, new_state_path_list = new_installation_state.getPathList()
old_installation_state)
# Install the compared installation state to_install_path_item_list = []
self.installBusinessManager(new_installation_state)
# Remove the path_item with negative sign # Get the path which has been removed in new installation_state
self.cleanInstallationState(new_installation_state) removed_path_list = [path for path
in old_state_path_list
if path not in new_state_path_list]
# Add the removed path with negative sign in the to_install_path_item_list
for path in removed_path_list:
old_item = old_installation_state.getBusinessItemByPath(path)
old_item._sign = -1
to_install_path_item_list.append(old_item)
# Path Item List for installation_process should be the difference between
# old and new installation state
for item in new_installation_state._path_item_list:
# If the path has been removed, then add it with sign = -1
old_item = old_installation_state.getBusinessItemByPath(item._path)
if old_item:
# If the old_item exists, we match the hashes and if it differs, then
# add the new item
if old_item._sha != item._sha:
to_install_path_item_list.append(item)
else:
to_install_path_item_list.append(item)
installation_process._path_item_list = to_install_path_item_list
self.compareOldStateToOFS(installation_process, old_installation_state)
# Change status of all BM installed # Change status of all BM installed
for bm in bm_list: for bm in bm_list:
...@@ -1739,6 +1763,87 @@ class TemplateTool (BaseTool): ...@@ -1739,6 +1763,87 @@ class TemplateTool (BaseTool):
installMultipleBusinessManager = updateInstallationState installMultipleBusinessManager = updateInstallationState
def compareOldStateToOFS(self, installation_process, old_state):
# Get the paths about which we are concerned about
to_update_path_list = installation_process.getPathList()
portal = self.getPortalObject()
error_list = []
for path in to_update_path_list:
try:
obj = portal.restrictedTraverse(path)
obj_sha = hashlib.sha256(obj.toXML()).hexdigest()
# Get item at old state
old_item = old_state.getBusinessItemByPath()
# Check if there is an object at old state at this path
if old_item:
# Compare hash with ZODB
if old_item._sha == obj._sha:
# No change at ZODB on old item, so get the new item
new_item = installation_process.getBusinessItemByPath(path)
# Compare new item hash with ZODB
if new_item._sha == obj._sha:
# If same hash, do nothing
continue
else:
# Install the new_item
new_item.install(installation_process)
else:
# Change at ZODB, so get the new item
new_item = installation_process.getBusinessItemByPath(path)
# Compare new item hash with ZODB
if new_item._sha == obj._sha:
# If same hash, do nothing
continue
else:
# Raise error
error_list.append('Trying to remove changes at ZODB at %s' % path)
raise ValueError('Trying to remove changes at ZODB at %s' % path)
else:
# Object created at ZODB by the user
# Compare with the new_item
new_item = installation_process.getBusinessItemByPath(path)
if new_item._sha == obj._sha:
# If same hash, do nothing
continue
else:
# Raise error
error_list.append('Trying to remove changes at ZODB at %s' % path)
raise ValueError('Trying to remove changes at ZODB at %s' % path)
except Exception:
# Get item at old state
old_item = old_state.getBusinessItemByPath(path)
# Check if there is an object at old state at this path
if old_item:
# This means that the user had removed the object at this path
# Check what the sign is for the new_item
new_item = installation_process.getBusinessItemByPath(path)
# Check sign of new_item
if new_item._sign == 1:
error_list.append('Object at %s removed by user' % path)
raise ValueError('Object at %s removed by user' % path)
else:
# If there is no item at old state, install the new_item
new_item = installation_process.getBusinessItemByPath(path)
new_item.install(installation_process)
security.declareProtected(Permissions.ManagePortal, security.declareProtected(Permissions.ManagePortal,
'createNewInstallationState') 'createNewInstallationState')
def createNewInstallationState(self, bm_list, old_installation_state): def createNewInstallationState(self, bm_list, old_installation_state):
...@@ -1849,28 +1954,34 @@ class TemplateTool (BaseTool): ...@@ -1849,28 +1954,34 @@ class TemplateTool (BaseTool):
""" """
# XXX: BAD DESIGN: Should compare both path as well as hash, just path # XXX: BAD DESIGN: Should compare both path as well as hash, just path
# can lead to conflict in case two paths have same sha. # can lead to conflict in case two paths have same sha.
built_item_dict = { built_item_dict = {
item._path: item._sha for item._path: item._sha for item
item in buildBM._path_item_list in buildBM._path_item_list
} }
old_item_dict = { old_item_dict = {
item._path: item._sha for item._path: item._sha for item
item in old_installation_state._path_item_list in old_installation_state._path_item_list
} }
# For creating new_item_dict, we have to take use of template_path_list # For creating new_item_dict, we have to take use of template_path_list
# property as there can be case where we have path but not path_item as # property as there can be case where we have path but not path_item as
# the new state already gets filtered while creation # the new state already gets filtered while creation
new_item_dict = { new_item_dict = {
item._path: item._sha for item._path: item._sha for item
item in new_installation_state._path_item_list in new_installation_state._path_item_list
if item._sign == 1
} }
build_sha_list = built_item_dict.values() build_sha_list = built_item_dict.values()
final_item_list = [] final_item_list = []
for item in new_installation_state._path_item_list:
if item._sign == 1:
if path in old_item_dict.keys():
if old_item_dict[path] == item._sha:
pass
for item in new_installation_state._path_item_list: for item in new_installation_state._path_item_list:
if item._sha in build_sha_list and item._sign == 1: if item._sha in build_sha_list and item._sign == 1:
# No need to install value which we already have # No need to install value which we already have
...@@ -1892,6 +2003,8 @@ class TemplateTool (BaseTool): ...@@ -1892,6 +2003,8 @@ class TemplateTool (BaseTool):
# Return the subtraction of the Business Manager # Return the subtraction of the Business Manager
return compared_bm return compared_bm
security.declareProtected(Permissions.ManagePortal,
'cleanInstallationState')
def cleanInstallationState(self, installation_state): def cleanInstallationState(self, installation_state):
""" """
Installation State is the Business Manager which has been installed Installation State is the Business Manager which has been installed
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment