Commit 9998c6f4 authored by Rafael Monnerat's avatar Rafael Monnerat

Clean up for the JSON API work

See merge request nexedi/slapos.core!388
parents 1ac3ec59 e36b68d4
...@@ -31,31 +31,18 @@ from erp5.component.document.Item import Item ...@@ -31,31 +31,18 @@ from erp5.component.document.Item import Item
from lxml import etree from lxml import etree
import collections import collections
from AccessControl import Unauthorized
from AccessControl.Permissions import access_contents_information
from AccessControl import getSecurityManager
from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
from erp5.component.module.SlapOSCloud import _assertACI
from zLOG import LOG, INFO from zLOG import LOG, INFO
try: try:
from slapos.slap.slap import \
SoftwareInstance as SlapSoftwareInstance
from slapos.util import xml2dict, loads from slapos.util import xml2dict, loads
except ImportError: except ImportError:
def xml2dict(dictionary): def xml2dict(dictionary):
raise ImportError raise ImportError
def loads(*args): def loads(*args):
raise ImportError raise ImportError
class SlapSoftwareInstance:
def __init__(self):
raise ImportError
def _assertACI(document):
sm = getSecurityManager()
if sm.checkPermission(access_contents_information,
document):
return document
raise Unauthorized('User %r has no access to %r' % (sm.getUser(), document))
class DisconnectedSoftwareTree(Exception): class DisconnectedSoftwareTree(Exception):
pass pass
...@@ -160,7 +147,7 @@ class SoftwareInstance(Item): ...@@ -160,7 +147,7 @@ class SoftwareInstance(Item):
LOG('SoftwareInstance', INFO, 'Issue during parsing xml:', error=True) LOG('SoftwareInstance', INFO, 'Issue during parsing xml:', error=True)
return result_dict return result_dict
def _asSoftwareInstance(self): def _asSoftwareInstanceDict(self):
parameter_dict = self._asParameterDict() parameter_dict = self._asParameterDict()
requested_state = self.getSlapState() requested_state = self.getSlapState()
...@@ -182,13 +169,13 @@ class SoftwareInstance(Item): ...@@ -182,13 +169,13 @@ class SoftwareInstance(Item):
parameter_dict.pop('filter_xml')) parameter_dict.pop('filter_xml'))
instance_guid = parameter_dict.pop('instance_guid') instance_guid = parameter_dict.pop('instance_guid')
software_instance = SlapSoftwareInstance(**parameter_dict) software_instance_dict = parameter_dict
software_instance._parameter_dict = xml software_instance_dict['_parameter_dict'] = xml
software_instance._connection_dict = connection_xml software_instance_dict['_connection_dict'] = connection_xml
software_instance._filter_dict = filter_xml software_instance_dict['_filter_dict'] = filter_xml
software_instance._requested_state = state software_instance_dict['_requested_state'] = state
software_instance._instance_guid = instance_guid software_instance_dict['_instance_guid'] = instance_guid
return software_instance return software_instance_dict
@UnrestrictedMethod @UnrestrictedMethod
def _asParameterDict(self, shared_instance_sql_list=None): def _asParameterDict(self, shared_instance_sql_list=None):
......
...@@ -6,12 +6,6 @@ ...@@ -6,12 +6,6 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>SoftwareInstance</string> </value> <value> <string>SoftwareInstance</string> </value>
...@@ -55,28 +49,13 @@ ...@@ -55,28 +49,13 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -89,7 +68,7 @@ ...@@ -89,7 +68,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -98,7 +77,7 @@ ...@@ -98,7 +77,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="4" aka="AAAAAAAAAAQ="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle> </pickle>
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010-2022 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from erp5.component.module.SlapOSCloud import _assertACI
from OFS.Traversable import NotFound
from Products.ERP5Type.Cache import CachingMethod
from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
class SlapOSCatalogToolCacheMixin(object):
""" Quering Caching Extension for Catalog for handle specific queries
relying on caching.
The searches also differ NotFound from Unauthorized, by relying into
unrestricted searches and a custom way to assert Access roles.
Be carefull to not rely on it to hack arround security.
"""
def _getNonCachedComputeNode(self, reference):
# No need to get all results if an error is raised when at least 2 objects
# are found
compute_node_list = self.unrestrictedSearchResults(limit=2,
portal_type='Compute Node',
validation_state="validated",
reference=reference)
if len(compute_node_list) != 1:
raise NotFound, "No document found with parameters: %s" % reference
else:
return _assertACI(compute_node_list[0].getObject()).getRelativeUrl()
def getComputeNodeObject(self, reference):
"""
Get the validated compute_node with this reference.
"""
result = CachingMethod(self._getNonCachedComputeNode,
id='_getComputeNodeObject',
cache_factory='slap_cache_factory')(reference)
return self.getPortalObject().restrictedTraverse(result)
@UnrestrictedMethod
def _getComputeNodeUid(self, reference):
"""
Get the validated compute_node with this reference.
"""
return CachingMethod(self._getNonCachedComputeNodeUid,
id='_getNonCachedComputeNodeUid',
cache_factory='slap_cache_factory')(reference)
@UnrestrictedMethod
def _getNonCachedComputeNodeUid(self, reference):
return self.unrestrictedSearchResults(
portal_type='Compute Node', reference=reference,
validation_state="validated")[0].UID
def getComputePartitionObject(self, compute_node_reference,
compute_partition_reference):
"""
Get the compute partition defined in an available compute_node
"""
# Related key might be nice
compute_partition_list = self.unrestrictedSearchResults(limit=2,
portal_type='Compute Partition',
reference=compute_partition_reference,
parent_uid=self._getNonCachedComputeNodeUid(
compute_node_reference))
if len(compute_partition_list) != 1:
raise NotFound, "No document found with parameters: %s %s" % \
(compute_node_reference, compute_partition_reference)
else:
return _assertACI(compute_partition_list[0].getObject())
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Mixin Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>SlapOSCatalogToolCacheMixin</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>mixin.erp5.SlapOSCatalogToolCacheMixin</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Mixin Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -6,12 +6,6 @@ ...@@ -6,12 +6,6 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>SlapOSComputeNodeMixin</string> </value> <value> <string>SlapOSComputeNodeMixin</string> </value>
...@@ -55,28 +49,13 @@ ...@@ -55,28 +49,13 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -89,7 +68,7 @@ ...@@ -89,7 +68,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -98,7 +77,7 @@ ...@@ -98,7 +77,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="4" aka="AAAAAAAAAAQ="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle> </pickle>
......
...@@ -25,14 +25,11 @@ ...@@ -25,14 +25,11 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# #
############################################################################## ##############################################################################
from AccessControl.Permissions import access_contents_information from erp5.component.module.SlapOSCloud import _assertACI
from AccessControl import getSecurityManager from zLOG import LOG, INFO
from AccessControl import Unauthorized from OFS.Traversable import NotFound
try: try:
from slapos.slap.slap import (
ComputerPartition as SlapComputePartition,
SoftwareRelease)
from slapos.util import calculate_dict_hash from slapos.util import calculate_dict_hash
except ImportError: except ImportError:
# Do no prevent instance from starting # Do no prevent instance from starting
...@@ -46,27 +43,48 @@ except ImportError: ...@@ -46,27 +43,48 @@ except ImportError:
def calculate_dict_hash(*args): def calculate_dict_hash(*args):
raise ImportError raise ImportError
def _assertACI(document): class SlapOSComputePartitionMixin(object):
sm = getSecurityManager()
if sm.checkPermission(access_contents_information,
document):
return document
raise Unauthorized('User %r has no access to %r' % (sm.getUser(), document))
def _getSoftwareInstance(self, slave_reference=None):
if self.getSlapState() != 'busy':
LOG('SlapOSComputePartitionMixin::_getSoftwareInstance', INFO,
'Compute partition %s shall be busy, is free' %
self.getRelativeUrl())
raise NotFound("No software instance found for: %s - %s" % (
self.getParentValue().getTitle(), self.getTitle()))
else:
query_kw = {
'validation_state': 'validated',
'portal_type': 'Slave Instance',
'default_aggregate_uid': self.getUid(),
}
if slave_reference is None:
query_kw['portal_type'] = "Software Instance"
else:
query_kw['reference'] = slave_reference
class SlapOSComputePartitionMixin(object): software_instance = _assertACI(
self.getPortalObject().portal_catalog.unrestrictedGetResultValue(**query_kw))
if software_instance is None:
raise NotFound("No software instance found for: %s - %s" % (
self.getParentValue().getTitle(), self.getTitle()))
else:
return software_instance
def _registerComputePartition(self): def _registerComputePartition(self):
portal = self.getPortalObject() portal = self.getPortalObject()
computer_reference = self.getParentValue().getReference() compute_node = self
computer_partition_reference = self.getReference() while compute_node.getPortalType() != 'Compute Node':
compute_node = compute_node.getParentValue()
compute_node_id = compute_node.getReference().decode("UTF-8")
slap_partition = SlapComputePartition(computer_reference.decode("UTF-8"), partition_dict = {
computer_partition_reference.decode("UTF-8")) "compute_node_id": compute_node_id,
slap_partition._software_release_document = None "partition_id": self.getReference().decode("UTF-8"),
slap_partition._requested_state = 'destroyed' "_software_release_document": None,
slap_partition._need_modification = 0 "_requested_state": 'destroyed',
software_instance = None "_need_modification": 0
}
if self.getSlapState() == 'busy': if self.getSlapState() == 'busy':
software_instance_list = portal.portal_catalog.unrestrictedSearchResults( software_instance_list = portal.portal_catalog.unrestrictedSearchResults(
...@@ -85,31 +103,31 @@ class SlapOSComputePartitionMixin(object): ...@@ -85,31 +103,31 @@ class SlapOSComputePartitionMixin(object):
self.getRelativeUrl()) self.getRelativeUrl())
if software_instance is not None: if software_instance is not None:
# trick client side, that data has been synchronised already for given
# document
slap_partition._synced = True
state = software_instance.getSlapState() state = software_instance.getSlapState()
if state == "stop_requested": if state == "stop_requested":
slap_partition._requested_state = 'stopped' partition_dict['_requested_state'] = 'stopped'
if state == "start_requested": if state == "start_requested":
slap_partition._requested_state = 'started' partition_dict['_requested_state'] = 'started'
slap_partition._software_release_document = SoftwareRelease( partition_dict['_software_release_document'] = {
software_release=software_instance.getUrlString().decode("UTF-8"), "software_release": software_instance.getUrlString().decode("UTF-8"),
computer_guid=computer_reference.decode("UTF-8")) "computer_guid": compute_node_id
}
slap_partition._need_modification = 1 partition_dict['_access_status'] = software_instance.getTextAccessStatus()
partition_dict["_need_modification"] = 1
# trick client side, that data has been synchronised already for given
# document
partition_dict["_synced"] = True
parameter_dict = software_instance._asParameterDict() parameter_dict = software_instance._asParameterDict()
# software instance has to define an xml parameter # software instance has to define an xml parameter
slap_partition._parameter_dict = software_instance._instanceXmlToDict( partition_dict["_parameter_dict"] = software_instance._instanceXmlToDict(
parameter_dict.pop('xml')) parameter_dict.pop('xml'))
slap_partition._connection_dict = software_instance._instanceXmlToDict( partition_dict['_connection_dict'] = software_instance._instanceXmlToDict(
parameter_dict.pop('connection_xml')) parameter_dict.pop('connection_xml'))
slap_partition._filter_dict = software_instance._instanceXmlToDict( partition_dict['_filter_dict'] = software_instance._instanceXmlToDict(
parameter_dict.pop('filter_xml')) parameter_dict.pop('filter_xml'))
slap_partition._instance_guid = parameter_dict.pop('instance_guid') partition_dict['_instance_guid'] = parameter_dict.pop('instance_guid')
for slave_instance_dict in parameter_dict.get("slave_instance_list", []): for slave_instance_dict in parameter_dict.get("slave_instance_list", []):
if slave_instance_dict.has_key("connection_xml"): if slave_instance_dict.has_key("connection_xml"):
connection_dict = software_instance._instanceXmlToDict( connection_dict = software_instance._instanceXmlToDict(
...@@ -120,6 +138,6 @@ class SlapOSComputePartitionMixin(object): ...@@ -120,6 +138,6 @@ class SlapOSComputePartitionMixin(object):
if slave_instance_dict.has_key("xml"): if slave_instance_dict.has_key("xml"):
slave_instance_dict.update(software_instance._instanceXmlToDict( slave_instance_dict.update(software_instance._instanceXmlToDict(
slave_instance_dict.pop("xml"))) slave_instance_dict.pop("xml")))
slap_partition._parameter_dict.update(parameter_dict) partition_dict['_parameter_dict'].update(parameter_dict)
return slap_partition return partition_dict
...@@ -6,12 +6,6 @@ ...@@ -6,12 +6,6 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>SlapOSComputePartitionMixin</string> </value> <value> <string>SlapOSComputePartitionMixin</string> </value>
...@@ -61,28 +55,13 @@ ...@@ -61,28 +55,13 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -95,7 +74,7 @@ ...@@ -95,7 +74,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -104,7 +83,7 @@ ...@@ -104,7 +83,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="4" aka="AAAAAAAAAAQ="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle> </pickle>
......
##############################################################################
#
# Copyright (c) 2021 Nexedi SA and Contributors. All Rights Reserved.
#
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from AccessControl import getSecurityManager
from zExceptions import Unauthorized
from AccessControl.Permissions import access_contents_information
def _assertACI(document):
sm = getSecurityManager()
if sm.checkPermission(access_contents_information,
document):
return document
raise Unauthorized('User %r has no access to %r' % (sm.getUser(), document))
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Module Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>SlapOSCloud</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>module.erp5.SlapOSCloud</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Module Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<type_mixin> <type_mixin>
<portal_type id="Catalog Tool">
<item>SlapOSCatalogToolCacheMixin</item>
</portal_type>
<portal_type id="Compute Node"> <portal_type id="Compute Node">
<item>SlapOSCacheMixin</item> <item>SlapOSCacheMixin</item>
<item>SlapOSComputeNodeMixin</item> <item>SlapOSComputeNodeMixin</item>
......
...@@ -35,7 +35,7 @@ import hashlib ...@@ -35,7 +35,7 @@ import hashlib
from binascii import hexlify from binascii import hexlify
def hashData(data): def hashData(data):
return hexlify(hashlib.sha1(data).digest()) return hexlify(hashlib.sha1(json.dumps(data, sort_keys=True)).digest())
class TestSlapOSCloudSlapOSCacheMixin( class TestSlapOSCloudSlapOSCacheMixin(
SlapOSTestCaseMixin): SlapOSTestCaseMixin):
......
...@@ -6,12 +6,6 @@ ...@@ -6,12 +6,6 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloud</string> </value> <value> <string>testSlapOSCloud</string> </value>
...@@ -61,28 +55,13 @@ ...@@ -61,28 +55,13 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -95,7 +74,7 @@ ...@@ -95,7 +74,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -104,7 +83,7 @@ ...@@ -104,7 +83,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="4" aka="AAAAAAAAAAQ="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle> </pickle>
......
mixin.erp5.SlapOSCacheMixin mixin.erp5.SlapOSCacheMixin
mixin.erp5.SlapOSComputeNodeMixin mixin.erp5.SlapOSComputeNodeMixin
mixin.erp5.SlapOSComputePartitionMixin mixin.erp5.SlapOSComputePartitionMixin
mixin.erp5.SlapOSCatalogToolCacheMixin
\ No newline at end of file
module.erp5.SlapOSCloud
\ No newline at end of file
Catalog Tool | SlapOSCatalogToolCacheMixin
Compute Node | SlapOSCacheMixin Compute Node | SlapOSCacheMixin
Compute Node | SlapOSComputeNodeMixin Compute Node | SlapOSComputeNodeMixin
Compute Partition | SlapOSCacheMixin Compute Partition | SlapOSCacheMixin
......
...@@ -15,12 +15,13 @@ import xml.dom.ext ...@@ -15,12 +15,13 @@ import xml.dom.ext
import StringIO import StringIO
import difflib import difflib
import hashlib import hashlib
import json
from binascii import hexlify from binascii import hexlify
from OFS.Traversable import NotFound from OFS.Traversable import NotFound
def hashData(data): def hashData(data):
return hexlify(hashlib.sha1(data).digest()) return hexlify(hashlib.sha1(json.dumps(data, sort_keys=True)).digest())
class Simulator: class Simulator:
...@@ -87,8 +88,10 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin): ...@@ -87,8 +88,10 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin):
self.commit() self.commit()
first_etag = self.compute_node._calculateRefreshEtag() first_etag = self.compute_node._calculateRefreshEtag()
first_body_fingerprint = hashData( first_body_fingerprint = hashData(
self.portal_slap._getSlapComputeNodeXMLFromDict(
self.compute_node._getCacheComputeNodeInformation(self.compute_node_id) self.compute_node._getCacheComputeNodeInformation(self.compute_node_id)
) )
)
self.assertEqual(200, response.status) self.assertEqual(200, response.status)
self.assertTrue('last-modified' not in response.headers) self.assertTrue('last-modified' not in response.headers)
self.assertEqual(first_etag, response.headers.get('etag')) self.assertEqual(first_etag, response.headers.get('etag'))
...@@ -122,8 +125,10 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin): ...@@ -122,8 +125,10 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin):
self.assertTrue('last-modified' not in response.headers) self.assertTrue('last-modified' not in response.headers)
second_etag = self.compute_node._calculateRefreshEtag() second_etag = self.compute_node._calculateRefreshEtag()
second_body_fingerprint = hashData( second_body_fingerprint = hashData(
self.portal_slap._getSlapComputeNodeXMLFromDict(
self.compute_node._getCacheComputeNodeInformation(self.compute_node_id) self.compute_node._getCacheComputeNodeInformation(self.compute_node_id)
) )
)
self.assertNotEqual(first_etag, second_etag) self.assertNotEqual(first_etag, second_etag)
# The indexation timestamp does not impact the response body # The indexation timestamp does not impact the response body
self.assertEqual(first_body_fingerprint, second_body_fingerprint) self.assertEqual(first_body_fingerprint, second_body_fingerprint)
...@@ -155,8 +160,10 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin): ...@@ -155,8 +160,10 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin):
# Edition does not impact the etag # Edition does not impact the etag
self.assertEqual(second_etag, self.compute_node._calculateRefreshEtag()) self.assertEqual(second_etag, self.compute_node._calculateRefreshEtag())
third_body_fingerprint = hashData( third_body_fingerprint = hashData(
self.portal_slap._getSlapComputeNodeXMLFromDict(
self.compute_node._getCacheComputeNodeInformation(self.compute_node_id) self.compute_node._getCacheComputeNodeInformation(self.compute_node_id)
) )
)
# The edition impacts the response body # The edition impacts the response body
self.assertNotEqual(first_body_fingerprint, third_body_fingerprint) self.assertNotEqual(first_body_fingerprint, third_body_fingerprint)
response = self.portal_slap.getFullComputerInformation(self.compute_node_id) response = self.portal_slap.getFullComputerInformation(self.compute_node_id)
...@@ -194,7 +201,9 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin): ...@@ -194,7 +201,9 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin):
# The edition does not impact the response body yet, as the aggregate relation # The edition does not impact the response body yet, as the aggregate relation
# is not yet unindex # is not yet unindex
self.assertEqual(third_body_fingerprint, hashData( self.assertEqual(third_body_fingerprint, hashData(
self.portal_slap._getSlapComputeNodeXMLFromDict(
self.compute_node._getCacheComputeNodeInformation(self.compute_node_id) self.compute_node._getCacheComputeNodeInformation(self.compute_node_id)
)
)) ))
response = self.portal_slap.getFullComputerInformation(self.compute_node_id) response = self.portal_slap.getFullComputerInformation(self.compute_node_id)
self.commit() self.commit()
...@@ -216,8 +225,10 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin): ...@@ -216,8 +225,10 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin):
self.assertTrue('last-modified' not in response.headers) self.assertTrue('last-modified' not in response.headers)
fourth_etag = self.compute_node._calculateRefreshEtag() fourth_etag = self.compute_node._calculateRefreshEtag()
fourth_body_fingerprint = hashData( fourth_body_fingerprint = hashData(
self.portal_slap._getSlapComputeNodeXMLFromDict(
self.compute_node._getCacheComputeNodeInformation(self.compute_node_id) self.compute_node._getCacheComputeNodeInformation(self.compute_node_id)
) )
)
self.assertNotEqual(third_etag, fourth_etag) self.assertNotEqual(third_etag, fourth_etag)
# The indexation timestamp does not impact the response body # The indexation timestamp does not impact the response body
self.assertNotEqual(third_body_fingerprint, fourth_body_fingerprint) self.assertNotEqual(third_body_fingerprint, fourth_body_fingerprint)
......
...@@ -6,12 +6,6 @@ ...@@ -6,12 +6,6 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>testSlapOSSlapTool</string> </value> <value> <string>testSlapOSSlapTool</string> </value>
...@@ -55,28 +49,13 @@ ...@@ -55,28 +49,13 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -89,7 +68,7 @@ ...@@ -89,7 +68,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -98,7 +77,7 @@ ...@@ -98,7 +77,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="4" aka="AAAAAAAAAAQ="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle> </pickle>
......
...@@ -6,12 +6,6 @@ ...@@ -6,12 +6,6 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>SlapTool</string> </value> <value> <string>SlapTool</string> </value>
...@@ -55,28 +49,13 @@ ...@@ -55,28 +49,13 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -89,7 +68,7 @@ ...@@ -89,7 +68,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -98,7 +77,7 @@ ...@@ -98,7 +77,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="4" aka="AAAAAAAAAAQ="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle> </pickle>
......
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