diff --git a/product/ERP5Type/ConnectionPlugin/SOAPWSDLConnection.py b/product/ERP5Type/ConnectionPlugin/SOAPWSDLConnection.py index c70bf834ce635ef00dcb5a386ce508cf1f44a4f7..1ac63fb8552c246d7e21062193f3a3bbc181c447 100644 --- a/product/ERP5Type/ConnectionPlugin/SOAPWSDLConnection.py +++ b/product/ERP5Type/ConnectionPlugin/SOAPWSDLConnection.py @@ -29,6 +29,7 @@ import SOAPpy from Products.AGProjects.patches import SOAPpy_WSDL as WSDL from AccessControl.SecurityInfo import allow_class, allow_module +import threading # Exception class. # This allows restricted python to handle exceptions without allowing direct @@ -158,6 +159,10 @@ class MethodWrapper(object): except SOAPpy.Types.faultType, exception: raise SOAPWSDLException(*exception()) +# SOAPpy says nothing about thread-safeness of parsed WSDL. +# Be on the safe side by using threading.local as a storage for it. +wsdl_cache = threading.local() + class SOAPWSDLConnection: """ Holds a SOAP connection described by a WSDL file. @@ -191,8 +196,10 @@ class SOAPWSDLConnection: self._service = service def connect(self): - # TODO: caching of wsdl parsing - wsdl = SOAPpy.wstools.WSDLTools.WSDLReader().loadFromURL(self.url) + try: + wsdl = wsdl_cache.parsed + except AttributeError: + wsdl = wsdl_cache.parsed = SOAPpy.wstools.WSDLTools.WSDLReader().loadFromURL(self.url) # TODO: transport (http) level authentication using self._user_name and # self._password return WSDLConnection(wsdl, self._credentials, self._service)