From: <bov...@us...> - 2007-02-21 21:14:14
|
Revision: 1361 http://svn.sourceforge.net/pywebsvcs/?rev=1361&view=rev Author: boverhof Date: 2007-02-21 13:14:10 -0800 (Wed, 21 Feb 2007) Log Message: ----------- M test/wsdl2py/config.txt A test/wsdl2py/test_WSDLImport.py A test/wsdl2py/test_WSDLImport2.wsdl A test/wsdl2py/test_WSDLImport.wsdl M ZSI/generate/commands.py M CHANGES -- print stacktrace to stderr when exiting so user has a clue what might have happened. -- added a couple unittests for testing wsdl:import, WSDL donated by Pavel. Modified Paths: -------------- trunk/zsi/CHANGES trunk/zsi/ZSI/generate/commands.py trunk/zsi/test/wsdl2py/config.txt Added Paths: ----------- trunk/zsi/test/wsdl2py/test_WSDLImport.py trunk/zsi/test/wsdl2py/test_WSDLImport.wsdl trunk/zsi/test/wsdl2py/test_WSDLImport2.wsdl Modified: trunk/zsi/CHANGES =================================================================== --- trunk/zsi/CHANGES 2007-02-21 00:50:31 UTC (rev 1360) +++ trunk/zsi/CHANGES 2007-02-21 21:14:10 UTC (rev 1361) @@ -6,6 +6,8 @@ - Record facets (restrictions) in XMLSchema.py <vc...@da...> - Remove Send()'s kwargs out of _args list <ef...@bo...> +Change for 2.1.0 released xxx: + Change for 2.0.0 released xxx: - no more wsdl2dispatch, wsdl2py does it all - simplified and consolidated various wsdl2py script options Modified: trunk/zsi/ZSI/generate/commands.py =================================================================== --- trunk/zsi/ZSI/generate/commands.py 2007-02-21 00:50:31 UTC (rev 1360) +++ trunk/zsi/ZSI/generate/commands.py 2007-02-21 21:14:10 UTC (rev 1361) @@ -4,8 +4,8 @@ # See Copyright for copyright notice! ############################################################################ -import exceptions, sys, optparse, os, warnings -from operator import xor +import exceptions, sys, optparse, os, warnings, traceback +#from operator import xor import ZSI from ConfigParser import ConfigParser from ZSI.generate.wsdl2python import WriteServiceModule, ServiceDescription as wsdl2pyServiceDescription @@ -171,7 +171,8 @@ try: wsdl = load(location) except Exception, e: - print "Error loading %s: \n\t%s" % (location, e) + print >> sys.stderr, "Error loading %s: \n\t%s" % (location, e) + traceback.print_exc(sys.stderr) # exit code UNIX specific, Windows? if hasattr(os, 'EX_NOINPUT'): sys.exit(os.EX_NOINPUT) sys.exit("error loading %s" %location) Modified: trunk/zsi/test/wsdl2py/config.txt =================================================================== --- trunk/zsi/test/wsdl2py/config.txt 2007-02-21 00:50:31 UTC (rev 1360) +++ trunk/zsi/test/wsdl2py/config.txt 2007-02-21 21:14:10 UTC (rev 1361) @@ -158,6 +158,7 @@ test_Attributes = test_Attributes.xsd test_DerivedTypes = test_DerivedTypes.xsd test_SubstitutionGroup = test_SubstitutionGroup.xsd +test_WSDLImport = test_WSDLImport.wsdl test_SquareService = SquareService.wsdl test_DateService = DateService.wsdl Added: trunk/zsi/test/wsdl2py/test_WSDLImport.py =================================================================== --- trunk/zsi/test/wsdl2py/test_WSDLImport.py (rev 0) +++ trunk/zsi/test/wsdl2py/test_WSDLImport.py 2007-02-21 21:14:10 UTC (rev 1361) @@ -0,0 +1,63 @@ +#!/usr/bin/env python +############################################################################ +# Joshua R. Boverhof, LBNL +# See LBNLCopyright for copyright notice! +########################################################################### +import os, sys, unittest, time +from ServiceTest import main, ServiceTestCase, ServiceTestSuite +from ZSI import FaultException +from ZSI.TC import _get_global_element_declaration as GED +from ZSI.writer import SoapWriter +from ZSI.parse import ParsedSoap + +""" +Unittest for Bug Report +[ ] + +test_WSDLImport.wsdl +test_WSDLImport2.wsdl + +""" + +# General targets +def dispatch(): + """Run all dispatch tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(WSDLImportTestCase, 'test_dispatch')) + return suite + +def local(): + """Run all local tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(WSDLImportTestCase, 'test_local')) + return suite + +def net(): + """Run all network tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(WSDLImportTestCase, 'test_net')) + return suite + +def all(): + """Run all tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(WSDLImportTestCase, 'test_')) + return suite + + +class WSDLImportTestCase(ServiceTestCase): + name = "test_WSDLImport" + types_file_name = "OutSchemaTest_client.py" + + def __init__(self, methodName): + ServiceTestCase.__init__(self, methodName) + self.wsdl2py_args.append('-b') + + def test_local_attribute1(self): + """ + """ + return + +if __name__ == "__main__" : + main() + Added: trunk/zsi/test/wsdl2py/test_WSDLImport.wsdl =================================================================== --- trunk/zsi/test/wsdl2py/test_WSDLImport.wsdl (rev 0) +++ trunk/zsi/test/wsdl2py/test_WSDLImport.wsdl 2007-02-21 21:14:10 UTC (rev 1361) @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding='UTF-8'?> +<definitions name="OutSchemaTest" + targetNamespace="urn:test:import:wsdl" + xmlns:tns="urn:test:import:wsdl" + xmlns="http://schemas.xmlsoap.org/wsdl/"> + + <import namespace="urn:test:import:inner" + location="test_WSDLImport2.wsdl"/> +</definitions> Added: trunk/zsi/test/wsdl2py/test_WSDLImport2.wsdl =================================================================== --- trunk/zsi/test/wsdl2py/test_WSDLImport2.wsdl (rev 0) +++ trunk/zsi/test/wsdl2py/test_WSDLImport2.wsdl 2007-02-21 21:14:10 UTC (rev 1361) @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding='UTF-8'?> +<definitions name="SchemaTest" + targetNamespace="urn:test:import:inner" + xmlns:tns="urn:test:import:inner" + xmlns:types="urn:test:import:types" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns="http://schemas.xmlsoap.org/wsdl/"> + + <types> + <xsd:schema + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:tns="urn:test:import:types" + targetNamespace="urn:test:import:types"> + + <xsd:complexType name='innerType'> + <xsd:sequence> + <xsd:element name="comment" type='xsd:string'/> + <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax"/> + </xsd:sequence> + </xsd:complexType> + + </xsd:schema> + </types> + + <message name="test"> + <part name='in' type='types:innerType'/> + </message> + <message name="testResponse"/> + + <portType name="SchemaTestPort"> + <operation name="test"> + <input message="tns:test"/> + <output message="tns:testResponse"/> + </operation> + </portType> + <binding name="SchemaTestBinding" type="tns:SchemaTestPort"> + <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> + <operation name="test"> + <soap:operation soapAction="test"/> + <input> <soap:body use="literal" namespace="urn:test:import:inner"/> </input> + <output> <soap:body use="literal" namespace="urn:test:import:inner"/> </output> + </operation> + </binding> + <service name="SchemaTestService"> + <port name="SchemaTestPort" binding="tns:SchemaTestBinding"> + <soap:address location="http://localhost:8881"/> + </port> + </service> +</definitions> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <eo...@us...> - 2007-04-10 16:11:13
|
Revision: 1373 http://svn.sourceforge.net/pywebsvcs/?rev=1373&view=rev Author: eolson Date: 2007-04-10 09:11:11 -0700 (Tue, 10 Apr 2007) Log Message: ----------- Fix nested lists for rpc encoded. Add test. Modified Paths: -------------- trunk/zsi/ZSI/TC.py trunk/zsi/test/test_t8.py Modified: trunk/zsi/ZSI/TC.py =================================================================== --- trunk/zsi/ZSI/TC.py 2007-04-10 16:01:25 UTC (rev 1372) +++ trunk/zsi/ZSI/TC.py 2007-04-10 16:11:11 UTC (rev 1373) @@ -622,13 +622,13 @@ "xsd:anyType[" + str(len(pyobj)) + "]" ) for o in pyobj: #TODO maybe this should take **self.kwargs... - serializer = getattr(o, 'typecode', Any()) + serializer = getattr(o, 'typecode', Any(**self.kwargs)) serializer.serialize(array, sw, o, name='element', **kw) else: struct = elt.createAppendElement(ns, n) for o in pyobj: #TODO maybe this should take **self.kwargs... - serializer = getattr(o, 'typecode', Any()) + serializer = getattr(o, 'typecode', Any(**self.kwargs)) serializer.serialize(struct, sw, o, **kw) return Modified: trunk/zsi/test/test_t8.py =================================================================== --- trunk/zsi/test/test_t8.py 2007-04-10 16:01:25 UTC (rev 1372) +++ trunk/zsi/test/test_t8.py 2007-04-10 16:11:11 UTC (rev 1373) @@ -132,6 +132,15 @@ ps = ParsedSoap(xml, envelope=False) self.failUnless(int(ps.Parse(TC.Any())) == 12) + def check_any_dict_list_rpcenc(self): + sw = SoapWriter() + testObj = [{"a":1,"b":2}, {"d":4,"e":5}, {"f":{"x":9}, "g":[6,7.0]}] + typecode = TC.Any(aslist=True) + sw.serialize(testObj, typecode=typecode) + xml = str(sw) + ps = ParsedSoap(xml) + result = TC.Any().parse(ps.body_root, ps) + self.failUnless(result == testObj) # # Creates permutation of test options: "check", "check_any", etc This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2007-05-11 18:43:06
|
Revision: 1378 http://svn.sourceforge.net/pywebsvcs/?rev=1378&view=rev Author: boverhof Date: 2007-05-11 11:43:06 -0700 (Fri, 11 May 2007) Log Message: ----------- M test/test_zsi_net.py M test/wsdl2py/runTests.py A test/test_callhome.py M ZSI/ServiceProxy.py M ZSI/generate/commands.py Modified Paths: -------------- trunk/zsi/ZSI/ServiceProxy.py trunk/zsi/ZSI/generate/commands.py trunk/zsi/test/test_zsi_net.py trunk/zsi/test/wsdl2py/runTests.py Added Paths: ----------- trunk/zsi/test/test_callhome.py Modified: trunk/zsi/ZSI/ServiceProxy.py =================================================================== --- trunk/zsi/ZSI/ServiceProxy.py 2007-05-08 20:54:37 UTC (rev 1377) +++ trunk/zsi/ZSI/ServiceProxy.py 2007-05-11 18:43:06 UTC (rev 1378) @@ -18,8 +18,6 @@ from ZSI.schema import GED, GTD import wstools -#from ZSI.wstools.Utility import SplitQName -#from ZSI.wstools.Namespaces import WSDL #url_to_mod = re.compile(r'<([^ \t\n\r\f\v:]+:)?include\s+location\s*=\s*"(\S+)"') @@ -95,18 +93,19 @@ else: # dont do anything to anames containers.ContainerBase.func_aname = lambda instnc,n: str(n) - #client,types = commands.wsdl2py(['-u', wsdl,'-o', cachedir, '-t', "%s_types.py" %]) - types = _urn_to_module(wsdl) - commands.wsdl2py(['-u', wsdl,'-o', cachedir, '-t', types]) + files = commands.wsdl2py(['-o', cachedir, wsdl]) if cp is None: cp = ConfigParser() if not cp.has_section(section): cp.add_section(section) + + types = filter(lambda f: f.endswith('_types.py'), files)[0] cp.set(section, option, types) cp.write(open(file, 'w')) if os.path.abspath(cachedir) not in sys.path: sys.path.append(os.path.abspath(cachedir)) - self._mod = __import__(types) + mod = os.path.split(types)[-1].rstrip('.py') + self._mod = __import__(mod) def _call(self, name, *args, **kwargs): """Call the named remote web service method.""" @@ -198,7 +197,7 @@ if self._asdict: self._nullpyclass(response) return binding.Receive(replytype=response, encodingStyle=callinfo.encodingStyle) - + def _nullpyclass(cls, typecode): typecode.pyclass = None if not hasattr(typecode, 'ofwhat'): return @@ -207,198 +206,6 @@ else: #Struct/ComplexType for i in typecode.ofwhat: cls._nullpyclass(i) _nullpyclass = classmethod(_nullpyclass) - - -# -# -# def _getTypeCodes(self, callinfo): -# """Returns typecodes representing input and output messages, if request and/or -# response fails to be generated return None for either or both. -# -# callinfo -- WSDLTools.SOAPCallInfo instance describing an operation. -# """ -# prefix = None -# self._resetPrefixDict() -# if callinfo.use == 'encoded': -# prefix = self._getPrefix(callinfo.namespace) -# try: -# requestTC = self._getTypeCode(parameters=callinfo.getInParameters(), literal=(callinfo.use=='literal')) -# except EvaluateException, ex: -# print "DEBUG: Request Failed to generate --", ex -# requestTC = None -# -# self._resetPrefixDict() -# try: -# replyTC = self._getTypeCode(parameters=callinfo.getOutParameters(), literal=(callinfo.use=='literal')) -# except EvaluateException, ex: -# print "DEBUG: Response Failed to generate --", ex -# replyTC = None -# -# request = response = None -# if callinfo.style == 'rpc': -# if requestTC: request = TC.Struct(pyclass=None, ofwhat=requestTC, pname=callinfo.methodName) -# if replyTC: response = TC.Struct(pyclass=None, ofwhat=replyTC, pname='%sResponse' %callinfo.methodName) -# else: -# if requestTC: request = requestTC[0] -# if replyTC: response = replyTC[0] -# -# #THIS IS FOR RPC/ENCODED, DOC/ENCODED Wrapper -# if request and prefix and callinfo.use == 'encoded': -# request.oname = '%(prefix)s:%(name)s xmlns:%(prefix)s="%(namespaceURI)s"' \ -# %{'prefix':prefix, 'name':request.aname, 'namespaceURI':callinfo.namespace} -# -# return request, response -# -# def _getTypeCode(self, parameters, literal=False): -# """Returns typecodes representing a parameter set -# parameters -- list of WSDLTools.ParameterInfo instances representing -# the parts of a WSDL Message. -# """ -# ofwhat = [] -# for part in parameters: -# namespaceURI,localName = part.type -# -# if part.element_type: -# #global element -# element = self._wsdl.types[namespaceURI].elements[localName] -# tc = self._getElement(element, literal=literal, local=False, namespaceURI=namespaceURI) -# else: -# #local element -# name = part.name -# typeClass = self._getTypeClass(namespaceURI, localName) -# if not typeClass: -# tp = self._wsdl.types[namespaceURI].types[localName] -# tc = self._getType(tp, name, literal, local=True, namespaceURI=namespaceURI) -# else: -# tc = typeClass(name) -# ofwhat.append(tc) -# return ofwhat -# -# def _globalElement(self, typeCode, namespaceURI, literal): -# """namespaces typecodes representing global elements with -# literal encoding. -# typeCode -- typecode representing an element. -# namespaceURI -- namespace -# literal -- True/False -# """ -# if literal: -# typeCode.oname = '%(prefix)s:%(name)s xmlns:%(prefix)s="%(namespaceURI)s"' \ -# %{'prefix':self._getPrefix(namespaceURI), 'name':typeCode.oname, 'namespaceURI':namespaceURI} -# -# def _getPrefix(self, namespaceURI): -# """Retrieves a prefix/namespace mapping. -# namespaceURI -- namespace -# """ -# prefixDict = self._getPrefixDict() -# if prefixDict.has_key(namespaceURI): -# prefix = prefixDict[namespaceURI] -# else: -# prefix = 'ns1' -# while prefix in prefixDict.values(): -# prefix = 'ns%d' %int(prefix[-1]) + 1 -# prefixDict[namespaceURI] = prefix -# return prefix -# -# def _getPrefixDict(self): -# """Used to hide the actual prefix dictionary. -# """ -# if not hasattr(self, '_prefixDict'): -# self.__prefixDict = {} -# return self.__prefixDict -# -# def _resetPrefixDict(self): -# """Clears the prefix dictionary, this needs to be done -# before creating a new typecode for a message -# (ie. before, and after creating a new message typecode) -# """ -# self._getPrefixDict().clear() -# -# def _getElement(self, element, literal=False, local=False, namespaceURI=None): -# """Returns a typecode instance representing the passed in element. -# element -- XMLSchema.ElementDeclaration instance -# literal -- literal encoding? -# local -- is locally defined? -# namespaceURI -- namespace -# """ -# if not element.isElement(): -# raise TypeError, 'Expecting an ElementDeclaration' -# -# tc = None -# elementName = element.getAttribute('name') -# tp = element.getTypeDefinition('type') -# -# typeObj = None -# if not (tp or element.content): -# nsuriType,localName = element.getAttribute('type') -# typeClass = self._getTypeClass(nsuriType,localName) -# -# typeObj = typeClass(elementName) -# elif not tp: -# tp = element.content -# -# if not typeObj: -# typeObj = self._getType(tp, elementName, literal, local, namespaceURI) -# -# minOccurs = int(element.getAttribute('minOccurs')) -# typeObj.optional = not minOccurs -# typeObj.minOccurs = minOccurs -# -# maxOccurs = element.getAttribute('maxOccurs') -# typeObj.repeatable = (maxOccurs == 'unbounded') or (int(maxOccurs) > 1) -# -# return typeObj -# -# def _getType(self, tp, name, literal, local, namespaceURI): -# """Returns a typecode instance representing the passed in type and name. -# tp -- XMLSchema.TypeDefinition instance -# name -- element name -# literal -- literal encoding? -# local -- is locally defined? -# namespaceURI -- namespace -# """ -# ofwhat = [] -# if not (tp.isDefinition() and tp.isComplex()): -# raise EvaluateException, 'only supporting complexType definition' -# elif tp.content.isComplex(): -# if hasattr(tp.content, 'derivation') and tp.content.derivation.isRestriction(): -# derived = tp.content.derivation -# typeClass = self._getTypeClass(*derived.getAttribute('base')) -# if typeClass == TC.Array: -# attrs = derived.attr_content[0].attributes[WSDL.BASE] -# prefix, localName = SplitQName(attrs['arrayType']) -# nsuri = derived.attr_content[0].getXMLNS(prefix=prefix) -# localName = localName.split('[')[0] -# simpleTypeClass = self._getTypeClass(namespaceURI=nsuri, localName=localName) -# if simpleTypeClass: -# ofwhat = simpleTypeClass() -# else: -# tp = self._wsdl.types[nsuri].types[localName] -# ofwhat = self._getType(tp=tp, name=None, literal=literal, local=True, namespaceURI=nsuri) -# else: -# raise EvaluateException, 'only support soapenc:Array restrictions' -# return typeClass(atype=name, ofwhat=ofwhat, pname=name, childNames='item') -# else: -# raise EvaluateException, 'complexContent only supported for soapenc:Array derivations' -# elif tp.content.isModelGroup(): -# modelGroup = tp.content -# for item in modelGroup.content: -# ofwhat.append(self._getElement(item, literal=literal, local=True)) -# -# tc = TC.Struct(pyclass=None, ofwhat=ofwhat, pname=name) -# if not local: -# self._globalElement(tc, namespaceURI=namespaceURI, literal=literal) -# return tc -# -# raise EvaluateException, 'only supporting complexType w/ model group, or soapenc:Array restriction' -# -# def _getTypeClass(self, namespaceURI, localName): -# """Returns a typecode class representing the type we are looking for. -# localName -- name of the type we are looking for. -# namespaceURI -- defining XMLSchema targetNamespace. -# """ -# bti = BaseTypeInterpreter() -# simpleTypeClass = bti.get_typeclass(localName, namespaceURI) -# return simpleTypeClass class MethodProxy: Modified: trunk/zsi/ZSI/generate/commands.py =================================================================== --- trunk/zsi/ZSI/generate/commands.py 2007-05-08 20:54:37 UTC (rev 1377) +++ trunk/zsi/ZSI/generate/commands.py 2007-05-11 18:43:06 UTC (rev 1378) @@ -179,11 +179,11 @@ if isinstance(wsdl, XMLSchema.XMLSchema): wsdl.location = location - _wsdl2py(options, wsdl) - return + return _wsdl2py(options, wsdl) - _wsdl2py(options, wsdl) - _wsdl2dispatch(options, wsdl) + modules = _wsdl2py(options, wsdl) + modules.append(_wsdl2dispatch(options, wsdl)) + return modules def _wsdl2py(options, wsdl): @@ -231,20 +231,32 @@ wsm = WriteServiceModule(wsdl, addressing=options.address) # if options.types != None: # wsm.setTypesModuleName(options.types) + + files = [] + append = files.append if options.schema is False: - fd = open(os.path.join(options.output_dir, '%s.py' %wsm.getClientModuleName()), 'w+') + client_mod = wsm.getClientModuleName() + client_file = os.path.join(options.output_dir, '%s.py' %client_mod) + append(client_file) + fd = open(client_file, 'w+') + # simple naming writes the messages to a separate file if not options.simple_naming: wsm.writeClient(fd) else: # provide a separate file to store messages to. - msg_fd = open(os.path.join(options.output_dir, '%s.py' %wsm.getMessagesModuleName()), 'w+') + msg_fd = open( os.path.join(options.output_dir, '%s.py' %wsm.getMessagesModuleName()), 'w+' ) wsm.writeClient(fd, msg_fd=msg_fd) msg_fd.close() fd.close() - fd = open( os.path.join(options.output_dir, '%s.py' %wsm.getTypesModuleName()), 'w+') + + types_mod = wsm.getTypesModuleName() + types_file = os.path.join(options.output_dir, '%s.py' %types_mod) + append(types_file) + fd = open( os.path.join(options.output_dir, '%s.py' %types_mod), 'w+' ) wsm.writeTypes(fd) fd.close() + return files def wsdl2dispatch(args=None): @@ -296,7 +308,7 @@ else: wsdl = reader.loadFromURL(args[0]) - _wsdl2dispatch(options, wsdl) + return _wsdl2dispatch(options, wsdl) def _wsdl2dispatch(options, wsdl): @@ -322,6 +334,9 @@ ss = ServiceDescription() ss.fromWSDL(wsdl) - fd = open( os.path.join(options.output_dir, ss.getServiceModuleName()+'.py'), 'w+') + module_name = ss.getServiceModuleName()+'.py' + fd = open( os.path.join(options.output_dir, module_name), 'w+') ss.write(fd) + + return module_name fd.close() Added: trunk/zsi/test/test_callhome.py =================================================================== --- trunk/zsi/test/test_callhome.py (rev 0) +++ trunk/zsi/test/test_callhome.py 2007-05-11 18:43:06 UTC (rev 1378) @@ -0,0 +1,24 @@ +#!/usr/bin/env python +import os,unittest +from ZSI import version +from ZSI.wstools.logging import gridLog + +os.environ['GRIDLOG_ON'] = '1' +os.environ['GRIDLOG_DEST'] = "gridlog-udp://portnoy.lbl.gov:15100" + + +class TestCase(unittest.TestCase): + def ping(self): + gridLog(program="test_callhome.py", zsi="v%d.%d.%d" % version.Version, event="ping") + +def makeTestSuite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(TestCase, "ping")) + return suite + +def main(): + unittest.main(defaultTest="makeTestSuite") + +if __name__ == '__main__': + main() + Modified: trunk/zsi/test/test_zsi_net.py =================================================================== --- trunk/zsi/test/test_zsi_net.py 2007-05-08 20:54:37 UTC (rev 1377) +++ trunk/zsi/test/test_zsi_net.py 2007-05-11 18:43:06 UTC (rev 1378) @@ -14,6 +14,7 @@ import test_URI import test_list import test_rfc2617 +import test_callhome def makeTestSuite(): return unittest.TestSuite( Modified: trunk/zsi/test/wsdl2py/runTests.py =================================================================== --- trunk/zsi/test/wsdl2py/runTests.py 2007-05-08 20:54:37 UTC (rev 1377) +++ trunk/zsi/test/wsdl2py/runTests.py 2007-05-11 18:43:06 UTC (rev 1378) @@ -3,9 +3,13 @@ # Joshua R. Boverhof, LBNL # See Copyright for copyright notice! ########################################################################### -import unittest, warnings +import unittest, warnings, os +from ZSI import version +from ZSI.wstools.logging import gridLog from ServiceTest import main, CONFIG_PARSER, DOCUMENT, LITERAL, BROKE, TESTS +os.environ['GRIDLOG_ON'] = '1' +os.environ['GRIDLOG_DEST'] = "gridlog-udp://portnoy.lbl.gov:15100" # General targets def dispatch(): @@ -95,6 +99,7 @@ if __name__ == "__main__": + gridLog(program="runTests.py", zsi="v%d.%d.%d" % version.Version, event="ping") main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2007-05-16 20:35:10
|
Revision: 1380 http://svn.sourceforge.net/pywebsvcs/?rev=1380&view=rev Author: boverhof Date: 2007-05-16 13:35:07 -0700 (Wed, 16 May 2007) Log Message: ----------- M test/wsdl2py/runTests.py M test/wsdl2py/test_AWSECommerceService.py -- updated targetNamespace of Amazon ECom test M test/test_callhome.py M ZSI/TC.py -- updated TC.XML typecode Modified Paths: -------------- trunk/zsi/ZSI/TC.py trunk/zsi/test/test_callhome.py trunk/zsi/test/wsdl2py/runTests.py trunk/zsi/test/wsdl2py/test_AWSECommerceService.py Modified: trunk/zsi/ZSI/TC.py =================================================================== --- trunk/zsi/ZSI/TC.py 2007-05-12 00:40:26 UTC (rev 1379) +++ trunk/zsi/ZSI/TC.py 2007-05-16 20:35:07 UTC (rev 1380) @@ -880,7 +880,7 @@ return self.readerclass().fromString(v) def get_formatted_content(self, pyobj): - pyobj = Canonicalize(pyobj) + #pyobj = Canonicalize(pyobj) return String.get_formatted_content(self, pyobj) @@ -1267,21 +1267,28 @@ else: self.set_attributes(xmlelt, pyobj) self.set_attribute_href(xmlelt, objid) - sw.AddCallback(self.cb, pyobj, unsuppressedPrefixes) + sw.AddCallback(self.cb, elt, sw, pyobj, unsuppressedPrefixes) def cb(self, elt, sw, pyobj, unsuppressedPrefixes=[]): + """pyobj -- xml.dom.Node.ELEMENT_NODE + """ if sw.Known(pyobj): return - objid = _get_idstr(pyobj) - ns,n = self.get_name(name, objid) - xmlelt = elt.createAppendElement(ns, n) - self.set_attribute_id(xmlelt, objid) - xmlelt.setAttributeNS(SOAP.ENC, 'encodingStyle', '""') - Canonicalize(pyobj, sw, unsuppressedPrefixes=unsuppressedPrefixes, - comments=self.comments) - + ## grab document and import node, and append it + doc = elt.getDocument() + node = doc.importNode(pyobj, deep=1) + child = elt.node.appendChild(node) + ## copy xmlns: attributes into appended node + parent = pyobj.parentNode + while parent.nodeType == _Node.ELEMENT_NODE: + for attr in filter(lambda a: a.name.startswith('xmlns:') and a.name not in child.attributes.keys(), parent.attributes): + child.setAttributeNode(attr.cloneNode(1)) + + parent = parent.parentNode + + class AnyType(TypeCode): """XML Schema xsi:anyType type definition wildCard. class variables: @@ -1708,67 +1715,67 @@ Any.serialmap[key] = instance -def _DynamicImport(moduleName, className): - ''' - Utility function for RegisterTypeWithSchemaAndClass - ''' - mod = __import__(moduleName) - components = moduleName.split('.') - for comp in components[1:]: - mod = getattr(mod, comp) - return getattr(mod, className) +#def _DynamicImport(moduleName, className): +# ''' +# Utility function for RegisterTypeWithSchemaAndClass +# ''' +# mod = __import__(moduleName) +# components = moduleName.split('.') +# for comp in components[1:]: +# mod = getattr(mod, comp) +# return getattr(mod, className) +# +#def _RegisterTypeWithSchemaAndClass(importedSchemaTypes, schemaTypeName, classModuleName, className, generatedClassSuffix="_"): +# ''' +# Used by RegisterGeneratedTypesWithMapping. +# Helps register classes so they can be serialized and parsed as "any". +# Register a type by providing its schema and class. This allows +# Any and AnyType to reconstruct objects made up of your own classes. +# Note: The class module should be able to be imported (by being in your +# pythonpath). Your classes __init__ functions shoud have default +# arguments for all extra parameters. +# Example of use: +# import SchemaToPyTypeMap # Mapping written by you. Also used with wsdl2py -m +# # mapping = {"SomeDescription":("Descriptions", "SomeDescription"), +# # schemaTypeName : moduleName , className +# # The module on the next line is generated by wsdl2py +# from EchoServer_services_types import urn_ZSI_examples as ExampleTypes +# +# for key,value in SchemaToPyTypeMap.mapping.items(): +# ZSI.TC.RegisterTypeWithSchemaAndClass(importedSchemaTypes = ExampleTypes, schemaTypeName=key, classModuleName=value[0], className=value[1]) +# +# ''' +# # Doing this: (schemaTypeName="ExampleTypes", classModuleName="Description", +# # className="SomeDescription") +# # sd_instance = ExampleTypes.SomeDescription_(pname="SomeDescription") +# # Any.serialmap[Descriptions.SomeDescription] = sd_instance +# # Any.parsemap[(None,'SomeDescription')] = sd_instance +# classDef = _DynamicImport(classModuleName, className) +# interfaceDef = getattr(importedSchemaTypes, schemaTypeName + generatedClassSuffix) +# +# instance = interfaceDef(pname=className) +# Any.serialmap[classDef] = instance +# Any.parsemap[(None,schemaTypeName)] = instance +# +#def RegisterGeneratedTypesWithMapping(generatedTypes, mapping, generatedClassSuffix="_"): +# ''' +# Registers python classes so they can be serialized and parsed as "any". +# generatedTypes is a class containing typecode classes generated by zsi. +# mapping is a dictionary that maps +# {schemaTypeName : moduleName, className} +# and is also used with wsdl2py -m +# +# Example of use: +# import SchemaToPyTypeMap # See RegisterTypeWithSchemaAndClass for description +# # The module on the next line is generated by wsdl2py and +# # contains generated typecodes. +# from EchoServer_services_types import urn_ZSI_examples as ExampleTypes +# RegisterGeneratedTypesWithMapping(generatedTypes = ExampleTypes, mapping=SchemaToPyTypeMap.mapping) +# ''' +# for key,value in mapping.items(): +# _RegisterTypeWithSchemaAndClass(importedSchemaTypes = generatedTypes, schemaTypeName=key, classModuleName=value[0], className=value[1], generatedClassSuffix=generatedClassSuffix) -def _RegisterTypeWithSchemaAndClass(importedSchemaTypes, schemaTypeName, classModuleName, className, generatedClassSuffix="_"): - ''' - Used by RegisterGeneratedTypesWithMapping. - Helps register classes so they can be serialized and parsed as "any". - Register a type by providing its schema and class. This allows - Any and AnyType to reconstruct objects made up of your own classes. - Note: The class module should be able to be imported (by being in your - pythonpath). Your classes __init__ functions shoud have default - arguments for all extra parameters. - Example of use: - import SchemaToPyTypeMap # Mapping written by you. Also used with wsdl2py -m - # mapping = {"SomeDescription":("Descriptions", "SomeDescription"), - # schemaTypeName : moduleName , className - # The module on the next line is generated by wsdl2py - from EchoServer_services_types import urn_ZSI_examples as ExampleTypes - for key,value in SchemaToPyTypeMap.mapping.items(): - ZSI.TC.RegisterTypeWithSchemaAndClass(importedSchemaTypes = ExampleTypes, schemaTypeName=key, classModuleName=value[0], className=value[1]) - - ''' - # Doing this: (schemaTypeName="ExampleTypes", classModuleName="Description", - # className="SomeDescription") - # sd_instance = ExampleTypes.SomeDescription_(pname="SomeDescription") - # Any.serialmap[Descriptions.SomeDescription] = sd_instance - # Any.parsemap[(None,'SomeDescription')] = sd_instance - classDef = _DynamicImport(classModuleName, className) - interfaceDef = getattr(importedSchemaTypes, schemaTypeName + generatedClassSuffix) - - instance = interfaceDef(pname=className) - Any.serialmap[classDef] = instance - Any.parsemap[(None,schemaTypeName)] = instance - -def RegisterGeneratedTypesWithMapping(generatedTypes, mapping, generatedClassSuffix="_"): - """ - Registers python classes so they can be serialized and parsed as "any". - generatedTypes is a class containing typecode classes generated by zsi. - mapping is a dictionary that maps - {schemaTypeName : moduleName, className} - and is also used with wsdl2py -m - - Example of use: - import SchemaToPyTypeMap # See RegisterTypeWithSchemaAndClass for description - # The module on the next line is generated by wsdl2py and - # contains generated typecodes. - from EchoServer_services_types import urn_ZSI_examples as ExampleTypes - RegisterGeneratedTypesWithMapping(generatedTypes = ExampleTypes, mapping=SchemaToPyTypeMap.mapping) - """ - for key,value in mapping.items(): - _RegisterTypeWithSchemaAndClass(importedSchemaTypes = generatedTypes, schemaTypeName=key, classModuleName=value[0], className=value[1], generatedClassSuffix=generatedClassSuffix) - - from TCnumbers import * from TCtimes import * from schema import GTD, GED, WrapImmutable Modified: trunk/zsi/test/test_callhome.py =================================================================== --- trunk/zsi/test/test_callhome.py 2007-05-12 00:40:26 UTC (rev 1379) +++ trunk/zsi/test/test_callhome.py 2007-05-16 20:35:07 UTC (rev 1380) @@ -9,7 +9,7 @@ class TestCase(unittest.TestCase): def ping(self): - gridLog(program="test_callhome.py", zsi="v%d.%d.%d" % version.Version, event="ping") + gridLog(event="zsi.test.test_callhome.ping", zsi="v%d.%d.%d" % version.Version, prog="test_callhome.py") def makeTestSuite(): suite = unittest.TestSuite() Modified: trunk/zsi/test/wsdl2py/runTests.py =================================================================== --- trunk/zsi/test/wsdl2py/runTests.py 2007-05-12 00:40:26 UTC (rev 1379) +++ trunk/zsi/test/wsdl2py/runTests.py 2007-05-16 20:35:07 UTC (rev 1380) @@ -99,7 +99,7 @@ if __name__ == "__main__": - gridLog(program="runTests.py", zsi="v%d.%d.%d" % version.Version, event="ping") + gridLog(prog="runTests.py", zsi="v%d.%d.%d" % version.Version, event="zsi.test.wsdl2py.runTests.ping") main() Modified: trunk/zsi/test/wsdl2py/test_AWSECommerceService.py =================================================================== --- trunk/zsi/test/wsdl2py/test_AWSECommerceService.py 2007-05-12 00:40:26 UTC (rev 1379) +++ trunk/zsi/test/wsdl2py/test_AWSECommerceService.py 2007-05-16 20:35:07 UTC (rev 1380) @@ -42,7 +42,7 @@ return suite -TargetNamespace = "http://webservices.amazon.com/AWSECommerceService/2007-02-22" +TargetNamespace = "http://webservices.amazon.com/AWSECommerceService/2007-05-14" class AmazonTestCase(ServiceTestCase): """Test case for Amazon ECommerce Web service """ @@ -146,7 +146,7 @@ <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" -xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SOAP-ENV:Body><ItemSearchResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2007-02-22"><OperationRequest><HTTPHeaders><Header Name="UserAgent"></Header></HTTPHeaders><RequestId>013FGTRCYPQV2EFA975Q</RequestId><Arguments><Argument Name="Service" Value="AWSECommerceService"></Argument></Arguments><RequestProcessingTime>0.353393793106079</RequestProcessingTime></OperationRequest><Items><Request><IsValid>True</IsValid><ItemSearchRequest><ItemPage>1</ItemPage><Keywords>Tamerlane</Keywords><ResponseGroup>Medium</ResponseGroup><SearchIndex>Books</SearchIndex></ItemSearchRequest></Request><TotalResults>61</TotalResults><TotalPages>7</TotalPages><Item><ASIN>030681465X</ASIN><DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=030681465X%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/030681465X%253FSubscriptionId=0HP1WHME000749APYWR2</DetailPageURL><SalesRank>262921</SalesRank><SmallImage><URL>http://ec1.images-amazon.com/images/P/030681465X.01._SCTHUMBZZZ_V66860320_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">50</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/030681465X.01._SCMZZZZZZZ_V66860320_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">108</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/030681465X.01._SCLZZZZZZZ_V66860320_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">337</Width></LargeImage><ImageSets><ImageSet Category="primary"><SwatchImage><URL>http://ec1.images-amazon.com/images/P/030681465X.01._SCSWATCHZZ_V66860320_.jpg</URL><Height Units="pixels">30</Height><Width Units="pixels">20</Width></SwatchImage><SmallImage><URL>http://ec1.images-amazon.com/images/P/030681465X.01._SCTHUMBZZZ_V66860320_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">50</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/030681465X.01._SCMZZZZZZZ_V66860320_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">108</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/030681465X.01._SCLZZZZZZZ_V66860320_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">337</Width></LargeImage></ImageSet></ImageSets><ItemAttributes><Author>Justin Marozzi</Author><Binding>Hardcover</Binding><DeweyDecimalNumber>920</DeweyDecimalNumber><EAN>9780306814655</EAN><Edition>New Ed</Edition><ISBN>030681465X</ISBN><Label>Da Capo Press</Label><ListPrice><Amount>2695</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$26.95</FormattedPrice></ListPrice><Manufacturer>Da Capo Press</Manufacturer><NumberOfItems>1</NumberOfItems><NumberOfPages>368</NumberOfPages><PackageDimensions><Height Units="hundredths-inches">150</Height><Length Units="hundredths-inches">904</Length><Weight Units="hundredths-pounds">174</Weight><Width Units="hundredths-inches">640</Width></PackageDimensions><ProductGroup>Book</ProductGroup><PublicationDate>2006-02-22</PublicationDate><Publisher>Da Capo Press</Publisher><Studio>Da Capo Press</Studio><Title>Tamerlane: Sword of Islam, Conqueror of the World</Title></ItemAttributes><OfferSummary><LowestNewPrice><Amount>399</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$3.99</FormattedPrice></LowestNewPrice><LowestUsedPrice><Amount>399</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$3.99</FormattedPrice></LowestUsedPrice><LowestCollectiblePrice><Amount>2695</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$26.95</FormattedPrice></LowestCollectiblePrice><TotalNew>31</TotalNew><TotalUsed>24</TotalUsed><TotalCollectible>1</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary><EditorialReviews><EditorialReview><Source>Book Description</Source><Content>A powerful account of the life of Tamerlane the Great (1336-1405), the last great Mongol conqueror of Central Asia, ruler of a vast empire, and one of history's most brutal tyrants <P> Tamerlane, aka Temur-the Mongol successor to Genghis Khan-ranks with Alexander the Great as one of the world's great conquerors, yet the details of his life are scarcely known in the West. Born in obscurity and poverty, he rose to become a fierce tribal leader, and with that his dominion and power grew with astonishing speed. He blazed through Asia, razing cities to the ground. He tortured conquered inhabitants without mercy, sometimes ordering them buried alive, at other times decapitating them. Over the ruins of conquered Baghdad, Tamerlane had his soldiers erect a pyramid of 90,000 enemy heads. As he and his armies swept through Central Asia, sacking, and then rebuilding cities, Tamerlane gradually imposed an iron rule and a refined culture over a vast territory-from the steppes of Asia to the Syrian coastline. <P> Justin Marozzi traveled in the footsteps of this fearsome emperor of Samarkand (modern-day Uzbekistan) to write this book, which is part history, part travelogue. He carefully follows the path of this infamous and enigmatic conqueror, recounting the history and the story of this cruel, cultivated, and indomitable warrior.</Content></EditorialReview></EditorialReviews></Item><Item><ASIN>1851684573</ASIN><DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=1851684573%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/1851684573%253FSubscriptionId=0HP1WHME000749APYWR2</DetailPageURL><SalesRank>567693</SalesRank><SmallImage><URL>http://ec1.images-amazon.com/images/P/1851684573.01._SCTHUMBZZZ_V63318467_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">49</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/1851684573.01._SCMZZZZZZZ_V63318467_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">104</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/1851684573.01._SCLZZZZZZZ_V63318467_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">324</Width></LargeImage><ImageSets><ImageSet Category="primary"><SwatchImage><URL>http://ec1.images-amazon.com/images/P/1851684573.01._SCSWATCHZZ_V63318467_.jpg</URL><Height Units="pixels">30</Height><Width Units="pixels">20</Width></SwatchImage><SmallImage><URL>http://ec1.images-amazon.com/images/P/1851684573.01._SCTHUMBZZZ_V63318467_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">49</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/1851684573.01._SCMZZZZZZZ_V63318467_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">104</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/1851684573.01._SCLZZZZZZZ_V63318467_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">324</Width></LargeImage></ImageSet></ImageSets><ItemAttributes><Author>Robert Rand</Author><Binding>Paperback</Binding><DeweyDecimalNumber>958.7086</DeweyDecimalNumber><EAN>9781851684571</EAN><ISBN>1851684573</ISBN><Label>Oneworld Publications</Label><ListPrice><Amount>1495</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$14.95</FormattedPrice></ListPrice><Manufacturer>Oneworld Publications</Manufacturer><NumberOfItems>1</NumberOfItems><NumberOfPages>224</NumberOfPages><PackageDimensions><Height Units="hundredths-inches">66</Height><Length Units="hundredths-inches">784</Length><Weight Units="hundredths-pounds">54</Weight><Width Units="hundredths-inches">512</Width></PackageDimensions><ProductGroup>Book</ProductGroup><PublicationDate>2006-09-11</PublicationDate><Publisher>Oneworld Publications</Publisher><Studio>Oneworld Publications</Studio><Title>Tamerlane's Children: Dispatches from Contemporary Uzbekistan</Title></ItemAttributes><OfferSummary><LowestNewPrice><Amount>708</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$7.08</FormattedPrice></LowestNewPrice><LowestUsedPrice><Amount>708</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$7.08</FormattedPrice></LowestUsedPrice><LowestCollectiblePrice><Amount>1495</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$14.95</FormattedPrice></LowestCollectiblePrice><TotalNew>31</TotalNew><TotalUsed>9</TotalUsed><TotalCollectible>1</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary><EditorialReviews><EditorialReview><Source>Book Description</Source><Content>In the central park of Tashkent, in a place the Uzbeks call the square, a magnificent statue of a mounted warrior dominates the surroundings - Tamerlane - national hero of post-Soviet Uzbekistan. And yet how does this 14th century conqueror reflect one of the world's most diverse and politically intriguing countries?Having spent three years in the region, renowned journalist Robert Rand seeks to answer this question, covering an assortment of fascinating topics, ranging from the effect of 9/11 to the clash of culture in Uzbek pop music. Overflowing with charming anecdotes and loveable personalities, Rand gives the reader a real sense of the country's confused identity and the challenges which it and its people will face in generations to come.</Content></EditorialReview></EditorialReviews></Item><Item><ASIN>0521633842</ASIN><DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0521633842%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0521633842%253FSubscriptionId=0HP1WHME000749APYWR2</DetailPageURL><SalesRank>584780</SalesRank><SmallImage><URL>http://ec1.images-amazon.com/images/P/0521633842.01._SCTHUMBZZZ_V1114821525_.jpg</URL><Height Units="pixels">60</Height><Width Units="pixels">39</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/0521633842.01._SCMZZZZZZZ_V1114821525_.jpg</URL><Height Units="pixels">140</Height><Width Units="pixels">90</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/0521633842.01._SCLZZZZZZZ_V1114821525_.jpg</URL><Height Units="pixels">475</Height><Width Units="pixels">306</Width></LargeImage><ImageSets><ImageSet Category="primary"><SwatchImage><URL>http://ec1.images-amazon.com/images/P/0521633842.01._SCSWATCHZZ_V1114821525_.jpg</URL><Height Units="pixels">30</Height><Width Units="pixels">19</Width></SwatchImage><SmallImage><URL>http://ec1.images-amazon.com/images/P/0521633842.01._SCTHUMBZZZ_V1114821525_.jpg</URL><Height Units="pixels">60</Height><Width Units="pixels">39</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/0521633842.01._SCMZZZZZZZ_V1114821525_.jpg</URL><Height Units="pixels">140</Height><Width Units="pixels">90</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/0521633842.01._SCLZZZZZZZ_V1114821525_.jpg</URL><Height Units="pixels">475</Height><Width Units="pixels">306</Width></LargeImage></ImageSet></ImageSets><ItemAttributes><Author>Beatrice Forbes Manz</Author><Binding>Paperback</Binding><DeweyDecimalNumber>950.2</DeweyDecimalNumber><EAN>9780521633840</EAN><Edition>Reprint</Edition><ISBN>0521633842</ISBN><Label>Cambridge University Press</Label><ListPrice><Amount>2499</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$24.99</FormattedPrice></ListPrice><Manufacturer>Cambridge University Press</Manufacturer><NumberOfItems>1</NumberOfItems><NumberOfPages>248</NumberOfPages><PackageDimensions><Height Units="hundredths-inches">67</Height><Length Units="hundredths-inches">850</Length><Weight Units="hundredths-pounds">74</Weight><Width Units="hundredths-inches">562</Width></PackageDimensions><ProductGroup>Book</ProductGroup><PublicationDate>2002-10-26</PublicationDate><Publisher>Cambridge University Press</Publisher><ReleaseDate>2002-10-26</ReleaseDate><Studio>Cambridge University Press</Studio><Title>Rise and Rule of Tamerlane, The (Canto original series)</Title></ItemAttributes><OfferSummary><LowestNewPrice><Amount>1950</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$19.50</FormattedPrice></LowestNewPrice><LowestUsedPrice><Amount>869</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$8.69</FormattedPrice></LowestUsedPrice><LowestCollectiblePrice><Amount>2499</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$24.99</FormattedPrice></LowestCollectiblePrice><TotalNew>22</TotalNew><TotalUsed>23</TotalUsed><TotalCollectible>2</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary><EditorialReviews><EditorialReview><Source>Book Description</Source><Content>This is the first serious study of Tamerlane, the great nomad conqueror who rose to power in 1370 on the ruins of the Mongol Empire and led his armies on campaigns of unprecedented scope, ranging from Moscow to Delhi. As the last nomad ruler to unite the steppe regions of Eurasia, Tamerlane marks the transition from the era of nomad conquest and rule to the modern ascendency of the settled world.</Content></EditorialReview></EditorialReviews></Item><Item><ASIN>189226420X</ASIN><DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=189226420X%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/189226420X%253FSubscriptionId=0HP1WHME000749APYWR2</DetailPageURL><SalesRank>817168</SalesRank><SmallImage><URL>http://ec1.images-amazon.com/images/P/189226420X.01._SCTHUMBZZZ_V40073149_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">50</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/189226420X.01._SCMZZZZZZZ_V40073149_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">107</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/189226420X.01._SCLZZZZZZZ_V40073149_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">333</Width></LargeImage><ImageSets><ImageSet Category="primary"><SwatchImage><URL>http://ec1.images-amazon.com/images/P/189226420X.01._SCSWATCHZZ_V40073149_.jpg</URL><Height Units="pixels">30</Height><Width Units="pixels">20</Width></SwatchImage><SmallImage><URL>http://ec1.images-amazon.com/images/P/189226420X.01._SCTHUMBZZZ_V40073149_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">50</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/189226420X.01._SCMZZZZZZZ_V40073149_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">107</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/189226420X.01._SCLZZZZZZZ_V40073149_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">333</Width></LargeImage></ImageSet></ImageSets><ItemAttributes><Author>Roy Stier</Author><Binding>Paperback</Binding><DeweyDecimalNumber>930</DeweyDecimalNumber><EAN>9781892264206</EAN><ISBN>189226420X</ISBN><Label>Timeless Voyager Press</Label><ListPrice><Amount>1200</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$12.00</FormattedPrice></ListPrice><Manufacturer>Timeless Voyager Press</Manufacturer><NumberOfItems>1</NumberOfItems><NumberOfPages>356</NumberOfPages><PackageDimensions><Height Units="hundredths-inches">79</Height><Length Units="hundredths-inches">900</Length><Weight Units="hundredths-pounds">115</Weight><Width Units="hundredths-inches">600</Width></PackageDimensions><ProductGroup>Book</ProductGroup><PublicationDate>2006-09-05</PublicationDate><Publisher>Timeless Voyager Press</Publisher><ReleaseDate>2006-09-21</ReleaseDate><Studio>Timeless Voyager Press</Studio><Title>Tamerlane: The Ultimate Warrior- Map Edition</Title></ItemAttributes><OfferSummary><LowestNewPrice><Amount>832</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$8.32</FormattedPrice></LowestNewPrice><LowestUsedPrice><Amount>862</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$8.62</FormattedPrice></LowestUsedPrice><LowestCollectiblePrice><Amount>1200</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$12.00</FormattedPrice></LowestCollectiblePrice><TotalNew>17</TotalNew><TotalUsed>8</TotalUsed><TotalCollectible>1</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary><EditorialReviews><EditorialReview><Source>Book Description</Source><Content>Tamerlane: The Ultimate Warrior- Map Edition (978-1-892264-20-6) In this Third Edition, little-known fourteenth century Muslim leader who inspired a vast army of Islamic followers to swarm through central and western Asia in a conquering wave, has been captured in the first complete history using narrative form by Roy Stier. Tamerlane, the Ultimate Warrior paints the violent and controversial true story of the swift horseman who threatened much of the Old World, crushing the Ottoman Empire and intimidating kings and emperors. A trail of devastation followed the ruthless conqueror from Delhi to Baghdad, yet incidents of mercy for his enemies revealed a benign side to Tamerlane. In the pageantry of rulers, Tamerlane found little recognition from the historians of later centuries. Killer? Demonic? ¿ or charismatic visionary with a flashing sword and a view of the world united under the banner of Islamic purity? Is there a message for moderns in the story of the military genius who scythed his way through a sizable part of the known world? The readers of this book think so. There are 9 illustrations and photographs, 28 new maps of the ancient world circa 1300 A.D., complete references for researchers, glossary of terms, four appendices, a complete chronology of events, and an index in the 354 page 6¿ X 9¿ book. Retail price: $21.95 plus S/H.</Content></EditorialReview></EditorialReviews></Item><Item><ASIN>B00087SKA2</ASIN><DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=B00087SKA2%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/B00087SKA2%253FSubscriptionId=0HP1WHME000749APYWR2</DetailPageURL><SalesRank>955067</SalesRank><ItemAttributes><Author>Harold Lamb</Author><Binding>Unknown Binding</Binding><Label>Bantam Books</Label><Manufacturer>Bantam Books</Manufacturer><NumberOfPages>216</NumberOfPages><ProductGroup>Book</ProductGroup><PublicationDate>1955</PublicationDate><Publisher>Bantam Books</Publisher><Studio>Bantam Books</Studio><Title>Tamerlane: Conqueror of the earth</Title></ItemAttributes><OfferSummary><LowestUsedPrice><Amount>795</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$7.95</FormattedPrice></LowestUsedPrice><TotalNew>0</TotalNew><TotalUsed>3</TotalUsed><TotalCollectible>0</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary></Item><Item><ASIN>0850459494</ASIN><DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0850459494%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0850459494%253FSubscriptionId=0HP1WHME000749APYWR2</DetailPageURL><SalesRank>230563</SalesRank><SmallImage><URL>http://ec1.images-amazon.com/images/P/0850459494.01._SCTHUMBZZZ_V1128022797_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">56</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/0850459494.01._SCMZZZZZZZ_V1128022797_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">119</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/0850459494.01._SCLZZZZZZZ_V1128022797_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">372</Width></LargeImage><ImageSets><ImageSet Category="primary"><SwatchImage><URL>http://ec1.images-amazon.com/images/P/0850459494.01._SCSWATCHZZ_V1128022797_.jpg</URL><Height Units="pixels">30</Height><Width Units="pixels">22</Width></SwatchImage><SmallImage><URL>http://ec1.images-amazon.com/images/P/0850459494.01._SCTHUMBZZZ_V1128022797_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">56</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/0850459494.01._SCMZZZZZZZ_V1128022797_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">119</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/0850459494.01._SCLZZZZZZZ_V1128022797_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">372</Width></LargeImage></ImageSet></ImageSets><ItemAttributes><Author>David Nicolle</Author><Binding>Paperback</Binding><Creator Role="Illustrator">Angus Mcbride</Creator><EAN>9780850459494</EAN><ISBN>0850459494</ISBN><Label>Osprey Publishing</Label><ListPrice><Amount>1595</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$15.95</FormattedPrice></ListPrice><Manufacturer>Osprey Publishing</Manufacturer><NumberOfItems>1</NumberOfItems><NumberOfPages>48</NumberOfPages><PackageDimensions><Height Units="hundredths-inches">15</Height><Length Units="hundredths-inches">978</Length><Weight Units="hundredths-pounds">36</Weight><Width Units="hundredths-inches">722</Width></PackageDimensions><ProductGroup>Book</ProductGroup><PublicationDate>1990-07-26</PublicationDate><Publisher>Osprey Publishing</Publisher><ReleaseDate>1990-07-26</ReleaseDate><Studio>Osprey Publishing</Studio><Title>The Age of Tamerlane (Men-at-Arms)</Title></ItemAttributes><OfferSummary><LowestNewPrice><Amount>900</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$9.00</FormattedPrice></LowestNewPrice><LowestUsedPrice><Amount>1200</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$12.00</FormattedPrice></LowestUsedPrice><TotalNew>4</TotalNew><TotalUsed>3</TotalUsed><TotalCollectible>0</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary><EditorialReviews><EditorialReview><Source>Book Description</Source><Content>Tamerlane or Timur-i-Lenk ('Timur the Lame') is one of the most extraordinary conquerors in history. In the late 14th century his armies seized huge territories from the borders of Mongolia to Palestine and Anatolia. His passage was marked by massacres that outdid even those of the Mongols for sheer savagery. Timur's career was unequalled since Alexander the Great in terms of constant battlefield success. Only in his youth, while recovering his family estates south of Samarqand, did he face occasional defeat. This title tells the remarkable story of Timur and details the organisation, tactics, arms and armour of his all-conquering army.</Content></EditorialReview></EditorialReviews></Item><Item><ASIN>1410222950</ASIN><DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=1410222950%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/1410222950%253FSubscriptionId=0HP1WHME000749APYWR2</DetailPageURL><SalesRank>665664</SalesRank><SmallImage><URL>http://ec1.images-amazon.com/images/P/1410222950.01._SCTHUMBZZZ_V1120611566_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">50</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/1410222950.01._SCMZZZZZZZ_V1120611566_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">107</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/1410222950.01._SCLZZZZZZZ_V1120611566_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">333</Width></LargeImage><ImageSets><ImageSet Category="primary"><SwatchImage><URL>http://ec1.images-amazon.com/images/P/1410222950.01._SCSWATCHZZ_V1120611566_.jpg</URL><Height Units="pixels">30</Height><Width Units="pixels">20</Width></SwatchImage><SmallImage><URL>http://ec1.images-amazon.com/images/P/1410222950.01._SCTHUMBZZZ_V1120611566_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">50</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/1410222950.01._SCMZZZZZZZ_V1120611566_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">107</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/1410222950.01._SCLZZZZZZZ_V1120611566_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">333</Width></LargeImage></ImageSet></ImageSets><ItemAttributes><Binding>Paperback</Binding><Creator Role="Editor">Daniel L. Burghart</Creator><Creator Role="Editor">Theresa Sabonis-helf</Creator><DeweyDecimalNumber>327</DeweyDecimalNumber><EAN>9781410222954</EAN><ISBN>1410222950</ISBN><Label>University Press of the Pacific</Label><ListPrice><Amount>3450</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$34.50</FormattedPrice></ListPrice><Manufacturer>University Press of the Pacific</Manufacturer><NumberOfItems>1</NumberOfItems><NumberOfPages>504</NumberOfPages><PackageDimensions><Height Units="hundredths-inches">112</Height><Length Units="hundredths-inches">900</Length><Weight Units="hundredths-pounds">161</Weight><Width Units="hundredths-inches">600</Width></PackageDimensions><ProductGroup>Book</ProductGroup><PublicationDate>2005-05-31</PublicationDate><Publisher>University Press of the Pacific</Publisher><Studio>University Press of the Pacific</Studio><Title>In the Tracks of Tamerlane: Central Asia's Path to the 21st Century</Title></ItemAttributes><OfferSummary><LowestNewPrice><Amount>2995</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$29.95</FormattedPrice></LowestNewPrice><LowestUsedPrice><Amount>4062</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$40.62</FormattedPrice></LowestUsedPrice><TotalNew>15</TotalNew><TotalUsed>7</TotalUsed><TotalCollectible>0</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary></Item><Item><ASIN>1853141046</ASIN><DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=1853141046%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/1853141046%253FSubscriptionId=0HP1WHME000749APYWR2</DetailPageURL><SalesRank>980362</SalesRank><ItemAttributes><Author>David Nicolle</Author><Author>Richard Hook</Author><Binding>Hardcover</Binding><DeweyDecimalNumber>950.20922</DeweyDecimalNumber><EAN>9781853141041</EAN><ISBN>1853141046</ISBN><Label>Firebird</Label><ListPrice><Amount>2495</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$24.95</FormattedPrice></ListPrice><Manufacturer>Firebird</Manufacturer><NumberOfItems>1</NumberOfItems><NumberOfPages>208</NumberOfPages><PackageDimensions><Height Units="hundredths-inches">1000</Height><Length Units="hundredths-inches">75</Length><Weight Units="hundredths-pounds">160</Weight><Width Units="hundredths-inches">775</Width></PackageDimensions><ProductGroup>Book</ProductGroup><PublicationDate>1990-09</PublicationDate><Publisher>Firebird</Publisher><Studio>Firebird</Studio><Title>The Mongol Warlords: Ghengis Khan, Kublai Khan, Hulegu, Tamerlane (Heroes & Warriors)</Title></ItemAttributes><OfferSummary><LowestUsedPrice><Amount>4700</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$47.00</FormattedPrice></LowestUsedPrice><TotalNew>0</TotalNew><TotalUsed>4</TotalUsed><TotalCollectible>0</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary></Item><Item><ASIN>0306815435</ASIN><DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0306815435%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0306815435%253FSubscriptionId=0HP1WHME000749APYWR2</DetailPageURL><SalesRank>503889</SalesRank><SmallImage><URL>http://ec1.images-amazon.com/images/P/0306815435.01._SCTHUMBZZZ_V35579588_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">50</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/0306815435.01._SCMZZZZZZZ_V35579588_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">107</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/0306815435.01._SCLZZZZZZZ_V35579588_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">333</Width></LargeImage><ImageSets><ImageSet Category="primary"><SwatchImage><URL>http://ec1.images-amazon.com/images/P/0306815435.01._SCSWATCHZZ_V35579588_.jpg</URL><Height Units="pixels">30</Height><Width Units="pixels">20</Width></SwatchImage><SmallImage><URL>http://ec1.images-amazon.com/images/P/0306815435.01._SCTHUMBZZZ_V35579588_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">50</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/0306815435.01._SCMZZZZZZZ_V35579588_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">107</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/0306815435.01._SCLZZZZZZZ_V35579588_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">333</Width></LargeImage></ImageSet></ImageSets><ItemAttributes><Author>Justin Marozzi</Author><Binding>Paperback</Binding><DeweyDecimalNumber>920</DeweyDecimalNumber><EAN>9780306815430</EAN><Edition>New Ed</Edition><ISBN>0306815435</ISBN><Label>Perseus Books Group</Label><ListPrice><Amount>1800</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$18.00</FormattedPrice></ListPrice><Manufacturer>Perseus Books Group</Manufacturer><NumberOfItems>1</NumberOfItems><NumberOfPages>480</NumberOfPages><ProductGroup>Book</ProductGroup><PublicationDate>2007-03-30</PublicationDate><Publisher>Perseus Books Group</Publisher><Studio>Perseus Books Group</Studio><Title>Tamerlane: Sword of Islam, Conqueror of the World</Title></ItemAttributes><OfferSummary><LowestNewPrice><Amount>1224</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$12.24</FormattedPrice></LowestNewPrice><TotalNew>1</TotalNew><TotalUsed>0</TotalUsed><TotalCollectible>0</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary></Item><Item><ASIN>1885221770</ASIN><DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=1885221770%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/1885221770%253FSubscriptionId=0HP1WHME000749APYWR2</DetailPageURL><SalesRank>1135641</SalesRank><SmallImage><URL>http://ec1.images-amazon.com/images/P/1885221770.01._SCTHUMBZZZ_V1056534986_.jpg</URL><Height Units="pixels">60</Height><Width Units="pixels">40</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/1885221770.01._SCMZZZZZZZ_V1056534986_.jpg</URL><Height Units="pixels">140</Height><Width Units="pixels">93</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/1885221770.01._SCLZZZZZZZ_V1056534986_.jpg</URL><Height Units="pixels">475</Height><Width Units="pixels">317</Width></LargeImage><ImageSets><ImageSet Category="primary"><SmallImage><URL>http://ec1.images-amazon.com/images/P/1885221770.01._SCTHUMBZZZ_V1056534986_.jpg</URL><Height Units="pixels">60</Height><Width Units="pixels">40</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/1885221770.01._SCMZZZZZZZ_V1056534986_.jpg</URL><Height Units="pixels">140</Height><Width Units="pixels">93</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/1885221770.01._SCLZZZZZZZ_V1056534986_.jpg</URL><Height Units="pixels">475</Height><Width Units="pixels">317</Width></LargeImage></ImageSet></ImageSets><ItemAttributes><Author>Roy Stier</Author><Binding>Paperback</Binding><DeweyDecimalNumber>920</DeweyDecimalNumber><EAN>9781885221773</EAN><ISBN>1885221770</ISBN><Label>Bookpartners</Label><ListPrice><Amount>1695</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$16.95</FormattedPrice></ListPrice><Manufacturer>Bookpartners</Manufacturer><NumberOfItems>1</NumberOfItems><NumberOfPages>304</NumberOfPages><PackageDimensions><Height Units="hundredths-inches">79</Height><Length Units="hundredths-inches">900</Length><Weight Units="hundredths-pounds">92</Weight><Width Units="hundredths-inches">606</Width></PackageDimensions><ProductGroup>Book</ProductGroup><PublicationDate>1998-09</PublicationDate><Publisher>Bookpartners</Publisher><Studio>Bookpartners</Studio><Title>Tamerlane: The Ultimate Warrior</Title></ItemAttributes><OfferSummary><LowestUsedPrice><Amount>870</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$8.70</FormattedPrice></LowestUsedPrice><LowestCollectiblePrice><Amount>2295</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$22.95</FormattedPrice></LowestCollectiblePrice><TotalNew>0</TotalNew><TotalUsed>4</TotalUsed><TotalCollectible>1</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary><EditorialReviews><EditorialReview><Source>Book Description</Source><Content>From humble beginnings, Tamerlane, the ancient Turki-Mongol conqueror, rose to become the scourge of his time and changed the course of history. <P>The name Tamerlane runs the gamut of human emotions, evoking in many a revulsion for the devil incarnate, in others, an appreciation for the benefactor of millions. <P>By using accounts from Tamerlane's detractors and his admirers, Roy Stier has captured an amazing story that gives credence to the old adage, "truth is stranger than fiction." <P>Tamerlane, the Ultimate Warrior is presented as a fascinating series of events and captures the reader in the first comprehensive view of this historical figure who dominated Asia and made Europe tremble.</Content></EditorialReview></EditorialReviews></Item></Items></ItemSearchResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>""" +xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SOAP-ENV:Body><ItemSearchResponse xmlns="%s">""" %TargetNamespace + """<OperationRequest><HTTPHeaders><Header Name="UserAgent"></Header></HTTPHeaders><RequestId>013FGTRCYPQV2EFA975Q</RequestId><Arguments><Argument Name="Service" Value="AWSECommerceService"></Argument></Arguments><RequestProcessingTime>0.353393793106079</RequestProcessingTime></OperationRequest><Items><Request><IsValid>True</IsValid><ItemSearchRequest><ItemPage>1</ItemPage><Keywords>Tamerlane</Keywords><ResponseGroup>Medium</ResponseGroup><SearchIndex>Books</SearchIndex></ItemSearchRequest></Request><TotalResults>61</TotalResults><TotalPages>7</TotalPages><Item><ASIN>030681465X</ASIN><DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=030681465X%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/030681465X%253FSubscriptionId=0HP1WHME000749APYWR2</DetailPageURL><SalesRank>262921</SalesRank><SmallImage><URL>http://ec1.images-amazon.com/images/P/030681465X.01._SCTHUMBZZZ_V66860320_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">50</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/030681465X.01._SCMZZZZZZZ_V66860320_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">108</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/030681465X.01._SCLZZZZZZZ_V66860320_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">337</Width></LargeImage><ImageSets><ImageSet Category="primary"><SwatchImage><URL>http://ec1.images-amazon.com/images/P/030681465X.01._SCSWATCHZZ_V66860320_.jpg</URL><Height Units="pixels">30</Height><Width Units="pixels">20</Width></SwatchImage><SmallImage><URL>http://ec1.images-amazon.com/images/P/030681465X.01._SCTHUMBZZZ_V66860320_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">50</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/030681465X.01._SCMZZZZZZZ_V66860320_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">108</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/030681465X.01._SCLZZZZZZZ_V66860320_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">337</Width></LargeImage></ImageSet></ImageSets><ItemAttributes><Author>Justin Marozzi</Author><Binding>Hardcover</Binding><DeweyDecimalNumber>920</DeweyDecimalNumber><EAN>9780306814655</EAN><Edition>New Ed</Edition><ISBN>030681465X</ISBN><Label>Da Capo Press</Label><ListPrice><Amount>2695</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$26.95</FormattedPrice></ListPrice><Manufacturer>Da Capo Press</Manufacturer><NumberOfItems>1</NumberOfItems><NumberOfPages>368</NumberOfPages><PackageDimensions><Height Units="hundredths-inches">150</Height><Length Units="hundredths-inches">904</Length><Weight Units="hundredths-pounds">174</Weight><Width Units="hundredths-inches">640</Width></PackageDimensions><ProductGroup>Book</ProductGroup><PublicationDate>2006-02-22</PublicationDate><Publisher>Da Capo Press</Publisher><Studio>Da Capo Press</Studio><Title>Tamerlane: Sword of Islam, Conqueror of the World</Title></ItemAttributes><OfferSummary><LowestNewPrice><Amount>399</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$3.99</FormattedPrice></LowestNewPrice><LowestUsedPrice><Amount>399</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$3.99</FormattedPrice></LowestUsedPrice><LowestCollectiblePrice><Amount>2695</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$26.95</FormattedPrice></LowestCollectiblePrice><TotalNew>31</TotalNew><TotalUsed>24</TotalUsed><TotalCollectible>1</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary><EditorialReviews><EditorialReview><Source>Book Description</Source><Content>A powerful account of the life of Tamerlane the Great (1336-1405), the last great Mongol conqueror of Central Asia, ruler of a vast empire, and one of history's most brutal tyrants <P> Tamerlane, aka Temur-the Mongol successor to Genghis Khan-ranks with Alexander the Great as one of the world's great conquerors, yet the details of his life are scarcely known in the West. Born in obscurity and poverty, he rose to become a fierce tribal leader, and with that his dominion and power grew with astonishing speed. He blazed through Asia, razing cities to the ground. He tortured conquered inhabitants without mercy, sometimes ordering them buried alive, at other times decapitating them. Over the ruins of conquered Baghdad, Tamerlane had his soldiers erect a pyramid of 90,000 enemy heads. As he and his armies swept through Central Asia, sacking, and then rebuilding cities, Tamerlane gradually imposed an iron rule and a refined culture over a vast territory-from the steppes of Asia to the Syrian coastline. <P> Justin Marozzi traveled in the footsteps of this fearsome emperor of Samarkand (modern-day Uzbekistan) to write this book, which is part history, part travelogue. He carefully follows the path of this infamous and enigmatic conqueror, recounting the history and the story of this cruel, cultivated, and indomitable warrior.</Content></EditorialReview></EditorialReviews></Item><Item><ASIN>1851684573</ASIN><DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=1851684573%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/1851684573%253FSubscriptionId=0HP1WHME000749APYWR2</DetailPageURL><SalesRank>567693</SalesRank><SmallImage><URL>http://ec1.images-amazon.com/images/P/1851684573.01._SCTHUMBZZZ_V63318467_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">49</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/1851684573.01._SCMZZZZZZZ_V63318467_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">104</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/1851684573.01._SCLZZZZZZZ_V63318467_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">324</Width></LargeImage><ImageSets><ImageSet Category="primary"><SwatchImage><URL>http://ec1.images-amazon.com/images/P/1851684573.01._SCSWATCHZZ_V63318467_.jpg</URL><Height Units="pixels">30</Height><Width Units="pixels">20</Width></SwatchImage><SmallImage><URL>http://ec1.images-amazon.com/images/P/1851684573.01._SCTHUMBZZZ_V63318467_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">49</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/1851684573.01._SCMZZZZZZZ_V63318467_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">104</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/1851684573.01._SCLZZZZZZZ_V63318467_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">324</Width></LargeImage></ImageSet></ImageSets><ItemAttributes><Author>Robert Rand</Author><Binding>Paperback</Binding><DeweyDecimalNumber>958.7086</DeweyDecimalNumber><EAN>9781851684571</EAN><ISBN>1851684573</ISBN><Label>Oneworld Publications</Label><ListPrice><Amount>1495</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$14.95</FormattedPrice></ListPrice><Manufacturer>Oneworld Publications</Manufacturer><NumberOfItems>1</NumberOfItems><NumberOfPages>224</NumberOfPages><PackageDimensions><Height Units="hundredths-inches">66</Height><Length Units="hundredths-inches">784</Length><Weight Units="hundredths-pounds">54</Weight><Width Units="hundredths-inches">512</Width></PackageDimensions><ProductGroup>Book</ProductGroup><PublicationDate>2006-09-11</PublicationDate><Publisher>Oneworld Publications</Publisher><Studio>Oneworld Publications</Studio><Title>Tamerlane's Children: Dispatches from Contemporary Uzbekistan</Title></ItemAttributes><OfferSummary><LowestNewPrice><Amount>708</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$7.08</FormattedPrice></LowestNewPrice><LowestUsedPrice><Amount>708</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$7.08</FormattedPrice></LowestUsedPrice><LowestCollectiblePrice><Amount>1495</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$14.95</FormattedPrice></LowestCollectiblePrice><TotalNew>31</TotalNew><TotalUsed>9</TotalUsed><TotalCollectible>1</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary><EditorialReviews><EditorialReview><Source>Book Description</Source><Content>In the central park of Tashkent, in a place the Uzbeks call the square, a magnificent statue of a mounted warrior dominates the surroundings - Tamerlane - national hero of post-Soviet Uzbekistan. And yet how does this 14th century conqueror reflect one of the world's most diverse and politically intriguing countries?Having spent three years in the region, renowned journalist Robert Rand seeks to answer this question, covering an assortment of fascinating topics, ranging from the effect of 9/11 to the clash of culture in Uzbek pop music. Overflowing with charming anecdotes and loveable personalities, Rand gives the reader a real sense of the country's confused identity and the challenges which it and its people will face in generations to come.</Content></EditorialReview></EditorialReviews></Item><Item><ASIN>0521633842</ASIN><DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0521633842%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0521633842%253FSubscriptionId=0HP1WHME000749APYWR2</DetailPageURL><SalesRank>584780</SalesRank><SmallImage><URL>http://ec1.images-amazon.com/images/P/0521633842.01._SCTHUMBZZZ_V1114821525_.jpg</URL><Height Units="pixels">60</Height><Width Units="pixels">39</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/0521633842.01._SCMZZZZZZZ_V1114821525_.jpg</URL><Height Units="pixels">140</Height><Width Units="pixels">90</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/0521633842.01._SCLZZZZZZZ_V1114821525_.jpg</URL><Height Units="pixels">475</Height><Width Units="pixels">306</Width></LargeImage><ImageSets><ImageSet Category="primary"><SwatchImage><URL>http://ec1.images-amazon.com/images/P/0521633842.01._SCSWATCHZZ_V1114821525_.jpg</URL><Height Units="pixels">30</Height><Width Units="pixels">19</Width></SwatchImage><SmallImage><URL>http://ec1.images-amazon.com/images/P/0521633842.01._SCTHUMBZZZ_V1114821525_.jpg</URL><Height Units="pixels">60</Height><Width Units="pixels">39</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/0521633842.01._SCMZZZZZZZ_V1114821525_.jpg</URL><Height Units="pixels">140</Height><Width Units="pixels">90</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/0521633842.01._SCLZZZZZZZ_V1114821525_.jpg</URL><Height Units="pixels">475</Height><Width Units="pixels">306</Width></LargeImage></ImageSet></ImageSets><ItemAttributes><Author>Beatrice Forbes Manz</Author><Binding>Paperback</Binding><DeweyDecimalNumber>950.2</DeweyDecimalNumber><EAN>9780521633840</EAN><Edition>Reprint</Edition><ISBN>0521633842</ISBN><Label>Cambridge University Press</Label><ListPrice><Amount>2499</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$24.99</FormattedPrice></ListPrice><Manufacturer>Cambridge University Press</Manufacturer><NumberOfItems>1</NumberOfItems><NumberOfPages>248</NumberOfPages><PackageDimensions><Height Units="hundredths-inches">67</Height><Length Units="hundredths-inches">850</Length><Weight Units="hundredths-pounds">74</Weight><Width Units="hundredths-inches">562</Width></PackageDimensions><ProductGroup>Book</ProductGroup><PublicationDate>2002-10-26</PublicationDate><Publisher>Cambridge University Press</Publisher><ReleaseDate>2002-10-26</ReleaseDate><Studio>Cambridge University Press</Studio><Title>Rise and Rule of Tamerlane, The (Canto original series)</Title></ItemAttributes><OfferSummary><LowestNewPrice><Amount>1950</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$19.50</FormattedPrice></LowestNewPrice><LowestUsedPrice><Amount>869</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$8.69</FormattedPrice></LowestUsedPrice><LowestCollectiblePrice><Amount>2499</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$24.99</FormattedPrice></LowestCollectiblePrice><TotalNew>22</TotalNew><TotalUsed>23</TotalUsed><TotalCollectible>2</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary><EditorialReviews><EditorialReview><Source>Book Description</Source><Content>This is the first serious study of Tamerlane, the great nomad conqueror who rose to power in 1370 on the ruins of the Mongol Empire and led his armies on campaigns of unprecedented scope, ranging from Moscow to Delhi. As the last nomad ruler to unite the steppe regions of Eurasia, Tamerlane marks the transition from the era of nomad conquest and rule to the modern ascendency of the settled world.</Content></EditorialReview></EditorialReviews></Item><Item><ASIN>189226420X</ASIN><DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=189226420X%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/189226420X%253FSubscriptionId=0HP1WHME000749APYWR2</DetailPageURL><SalesRank>817168</SalesRank><SmallImage><URL>http://ec1.images-amazon.com/images/P/189226420X.01._SCTHUMBZZZ_V40073149_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">50</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/189226420X.01._SCMZZZZZZZ_V40073149_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">107</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/189226420X.01._SCLZZZZZZZ_V40073149_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">333</Width></LargeImage><ImageSets><ImageSet Category="primary"><SwatchImage><URL>http://ec1.images-amazon.com/images/P/189226420X.01._SCSWATCHZZ_V40073149_.jpg</URL><Height Units="pixels">30</Height><Width Units="pixels">20</Width></SwatchImage><SmallImage><URL>http://ec1.images-amazon.com/images/P/189226420X.01._SCTHUMBZZZ_V40073149_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">50</Width></SmallImage><MediumImage><URL>http://ec1.images-amazon.com/images/P/189226420X.01._SCMZZZZZZZ_V40073149_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">107</Width></MediumImage><LargeImage><URL>http://ec1.images-amazon.com/images/P/189226420X.01._SCLZZZZZZZ_V40073149_.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">333</Width></LargeImage></ImageSet></ImageSets><ItemAttributes><Author>Roy Stier</Author><Binding>Paperback</Binding><DeweyDecimalNumber>930</DeweyDecimalNumber><EAN>9781892264206</EAN><ISBN>189226420X</ISBN><Label>Timeless Voyager Press</Label><ListPrice><Amount>1200</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$12.00</FormattedPrice></ListPrice><Manufacturer>Timeless Voyager Press</Manufacturer><NumberOfItems>1</NumberOfItems><NumberOfPages>356</NumberOfPages><PackageDimensions><Height Units="hundredths-inches">79</Height><Length Units="hundredths-inches">900</Length><Weight Units="hundredths-pounds">115</Weight><Width Units="hundredths-inches">600</Width></PackageDimensions><ProductGroup>Book</ProductGroup><PublicationDate>2006-09-05</PublicationDate><Publisher>Timeless Voyager Press</Publisher><ReleaseDate>2006-09-21</ReleaseDate><Studio>Timeless Voyager Press</Studio><Title>Tamerlane: The Ultimate Warrior- Map Edition</Title></ItemAttributes><OfferSummary><LowestNewPrice><Amount>832</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$8.32</FormattedPrice></LowestNewPrice><LowestUsedPrice><Amount>862</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$8.62</FormattedPrice></LowestUsedPrice><LowestCollectiblePrice><Amount>1200</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$12.00</FormattedPrice></LowestCollectiblePrice><TotalNew>17</TotalNew><TotalUsed>8</TotalUsed><TotalCollectible>1</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary><EditorialReviews><EditorialReview><Source>Book Description</Source><Content>Tamerlane: The Ultimate Warrior- Map Edition (978-1-892264-20-6) In this Third Edition, little-known fourteenth century Muslim leader who inspired a vast army of Islamic followers to swarm through central and western Asia in a conquering wave, has been captured in the first complete history using narrative form by Roy Stier. Tamerlane, the Ultimate Warrior paints the violent and controversial true story of the swift horseman who threatened much of the Old World, crushing the Ottoman Empire and intimidating kings and emperors. A trail of devastation followed the ruthless conqueror from Delhi to Baghdad, yet incidents of mercy for his enemies revealed a benign side to Tamerlane. In the pageantry of rulers, Tamerlane found little recognition from the historians of later centuries. Killer? Demonic? ¿ or charismatic visionary with a flashing sword and a view of the world united under the banner of Islamic purity? Is there a message for moderns in the story of the military genius who scythed his way thro... [truncated message content] |
From: <bov...@us...> - 2007-05-16 22:16:34
|
Revision: 1381 http://svn.sourceforge.net/pywebsvcs/?rev=1381&view=rev Author: boverhof Date: 2007-05-16 15:16:35 -0700 (Wed, 16 May 2007) Log Message: ----------- M test/wsdl2py/config.txt A test/wsdl2py/test_NVOAdmin.py A test/wsdl2py/wsdl/nvo-admin.wsdl -- dump a <schema> element into a soap message M ZSI/TC.py -- limit the usage scenarios for now Modified Paths: -------------- trunk/zsi/ZSI/TC.py trunk/zsi/test/wsdl2py/config.txt Added Paths: ----------- trunk/zsi/test/wsdl2py/test_NVOAdmin.py trunk/zsi/test/wsdl2py/wsdl/nvo-admin.wsdl Modified: trunk/zsi/ZSI/TC.py =================================================================== --- trunk/zsi/ZSI/TC.py 2007-05-16 20:35:07 UTC (rev 1380) +++ trunk/zsi/ZSI/TC.py 2007-05-16 22:16:35 UTC (rev 1381) @@ -1250,29 +1250,33 @@ return c[0] def serialize(self, elt, sw, pyobj, name=None, unsuppressedPrefixes=[], **kw): - if self.wrapped is False: - Canonicalize(pyobj, sw, unsuppressedPrefixes=unsuppressedPrefixes, - comments=self.comments) - return - objid = _get_idstr(pyobj) ns,n = self.get_name(name, objid) - xmlelt = elt.createAppendElement(ns, n) - if type(pyobj) in _stringtypes: - self.set_attributes(xmlelt, pyobj) - self.set_attribute_href(xmlelt, objid) - elif kw.get('inline', self.inline): - self.cb(xmlelt, sw, pyobj, unsuppressedPrefixes) - else: - self.set_attributes(xmlelt, pyobj) - self.set_attribute_href(xmlelt, objid) - sw.AddCallback(self.cb, elt, sw, pyobj, unsuppressedPrefixes) + xmlelt = elt + if self.wrapped: + xmlelt = elt.createAppendElement(ns, n) + #if type(pyobj) in _stringtypes: + # self.set_attributes(xmlelt, pyobj) + # self.set_attribute_href(xmlelt, objid) + #elif kw.get('inline', self.inline): + # self.cb(xmlelt, sw, pyobj, unsuppressedPrefixes) + #else: + # self.set_attributes(xmlelt, pyobj) + # self.set_attribute_href(xmlelt, objid) + # sw.AddCallback(self.cb, elt, sw, pyobj, unsuppressedPrefixes) + + self.cb(xmlelt, sw, pyobj, unsuppressedPrefixes) + def cb(self, elt, sw, pyobj, unsuppressedPrefixes=[]): """pyobj -- xml.dom.Node.ELEMENT_NODE """ - if sw.Known(pyobj): + #if sw.Known(pyobj): + # return + + if type(pyobj) in _stringtypes: + elt.createAppendTextNode(pyobj) return ## grab document and import node, and append it Modified: trunk/zsi/test/wsdl2py/config.txt =================================================================== --- trunk/zsi/test/wsdl2py/config.txt 2007-05-16 20:35:07 UTC (rev 1380) +++ trunk/zsi/test/wsdl2py/config.txt 2007-05-16 22:16:35 UTC (rev 1381) @@ -177,3 +177,5 @@ test_GoogleAdWords_CS = https://sandbox.google.com/api/adwords/v8/CampaignService?wsdl test_Manufacturer = wsdl/ManufacturerImpl.wsdl test_Racing = wsdl/Racing.wsdl + +test_NVOAdmin = wsdl/nvo-admin.wsdl Added: trunk/zsi/test/wsdl2py/test_NVOAdmin.py =================================================================== --- trunk/zsi/test/wsdl2py/test_NVOAdmin.py (rev 0) +++ trunk/zsi/test/wsdl2py/test_NVOAdmin.py 2007-05-16 22:16:35 UTC (rev 1381) @@ -0,0 +1,107 @@ +#!/usr/bin/env python +############################################################################ +# Joshua R. Boverhof, LBNL +# See LBNLCopyright for copyright notice! +########################################################################### +import os, sys, unittest +from ServiceTest import main, ServiceTestCase, ServiceTestSuite +from ZSI import SoapWriter, ParsedSoap, TC, FaultException +from ZSI import _child_elements, _get_element_nsuri_name, _is_element +from ZSI.schema import ElementDeclaration +from ZSI.wstools.Namespaces import SCHEMA + +from xml.dom.ext.reader import PyExpat +from xml.dom import Node +""" +Unittest for NVO Admin. + +WSDL: +""" +#from ZSI.wstools.logging import setBasicLoggerDEBUG; setBasicLoggerDEBUG() + +class schema(ElementDeclaration, TC.XML): + """Create an element for dealing with <xsd:schema> + """ + schema = SCHEMA.XSD3 + literal = "schema" + + def __init__(self, *args, **kw): + # minOccurs=1, maxOccurs=1, nillable=False, encoded=kw.get("encoded") + TC.XML.__init__(self, pname=(SCHEMA.XSD3, "schema"), wrapped=False, **kw) + + +# General targets +def dispatch(): + """Run all dispatch tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(ServiceTest, 'test_dispatch')) + return suite + +def local(): + """Run all local tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(ServiceTest, 'test_local')) + return suite + +def net(): + """Run all network tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(ServiceTest, 'test_net')) + return suite + +def all(): + """Run all tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(ServiceTest, 'test_')) + return suite + + +class NVOAdmin(ServiceTestCase): + """Test case for NVO Admin + + """ + name = "test_NVOAdmin" + client_file_name = "RegistryAdmin_client.py" + types_file_name = "RegistryAdmin_types.py" + #server_file_name = "RegistryAdmin_server.py" + + def __init__(self, methodName): + ServiceTestCase.__init__(self, methodName) + self.wsdl2py_args.append('-b') + + def test_local_serialize_schema(self): + from ZSI import SoapWriter + from ZSI import _child_elements + from xml.dom.ext.reader import PyExpat + msg = self.client_module.DSQueryRegistrySoapOut() + msg.DSQueryRegistryResult = msg.new_DSQueryRegistryResult() + msg.DSQueryRegistryResult.Any = 'hi' + + input = open('wsdl/nvo-admin.wsdl').read() + reader = PyExpat.Reader() + dom = reader.fromString(input) + + dnode = _child_elements(dom)[0] + tnode = _child_elements(dnode)[0] + snode = _child_elements(tnode)[0] + + msg.DSQueryRegistryResult.Schema = snode + + sw = SoapWriter() + sw.serialize(msg) + soap = str(sw) + print soap + + ps = ParsedSoap(soap) + pyobj = ps.Parse(msg.typecode) + self.failUnlessEqual(pyobj.DSQueryRegistryResult.Any, msg.DSQueryRegistryResult.Any) + self.failUnless(_is_element(pyobj.DSQueryRegistryResult.Schema)) + print _get_element_nsuri_name(pyobj.DSQueryRegistryResult.Schema) + self.failUnlessEqual(_get_element_nsuri_name(pyobj.DSQueryRegistryResult.Schema), (u'http://www.w3.org/2001/XMLSchema', u'schema')) + + +ServiceTest = NVOAdmin + +if __name__ == "__main__" : + main() + Added: trunk/zsi/test/wsdl2py/wsdl/nvo-admin.wsdl =================================================================== --- trunk/zsi/test/wsdl2py/wsdl/nvo-admin.wsdl (rev 0) +++ trunk/zsi/test/wsdl2py/wsdl/nvo-admin.wsdl 2007-05-16 22:16:35 UTC (rev 1381) @@ -0,0 +1,2426 @@ +<?xml version="1.0" encoding="utf-8"?> +<wsdl:definitions xmlns:s1="http://www.ivoa.net/xml/VOResource/v0.10" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s6="http://www.ivoa.net/xml/OpenSkyNode/v0.1" xmlns:s3="http://www.ivoa.net/xml/VORegistry/v0.3" xmlns:s2="http://www.ivoa.net/xml/VODataService/v0.5" xmlns:s5="http://www.ivoa.net/xml/ConeSearch/v0.3" xmlns:s4="http://www.ivoa.net/xml/SIA/v0.7" xmlns:s7="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.us-vo.org" xmlns:s8="http://purl.org/dc/elements/1.1/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://www.us-vo.org" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> + <wsdl:types> + <s:schema elementFormDefault="qualified" targetNamespace="http://www.us-vo.org"> + <!--s:import namespace="http://www.w3.org/2001/XMLSchema" /--> + <s:import namespace="http://www.ivoa.net/xml/VOResource/v0.10" /> + <s:import namespace="http://www.openarchives.org/OAI/2.0/oai_dc/" /> + <s:element name="Load"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="resources" type="tns:ArrayOfDBResource" /> + <s:element minOccurs="0" maxOccurs="1" name="PassPhrase" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:complexType name="ArrayOfDBResource"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="DBResource" nillable="true" type="tns:DBResource" /> + </s:sequence> + </s:complexType> + <s:complexType name="DBResource"> + <s:sequence> + <s:element minOccurs="1" maxOccurs="1" name="dbid" type="s:long" /> + <s:element minOccurs="1" maxOccurs="1" name="status" type="s:int" /> + <s:element minOccurs="0" maxOccurs="1" name="Identifier" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Title" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ShortName" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CurationPublisherName" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CurationPublisherIdentifier" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CurationPublisherDescription" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CurationPublisherReferenceUrl" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CurationCreatorName" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CurationCreatorLogo" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CurationContributor" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="CurationDate" type="s:dateTime" /> + <s:element minOccurs="0" maxOccurs="1" name="CurationVersion" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CurationContactName" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CurationContactEmail" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CurationContactAddress" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CurationContactPhone" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Subject" type="tns:ArrayOfString" /> + <s:element minOccurs="0" maxOccurs="1" name="Description" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ReferenceURL" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Type" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Facility" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Instrument" type="tns:ArrayOfString" /> + <s:element minOccurs="0" maxOccurs="1" name="ContentLevel" type="tns:ArrayOfString" /> + <s:element minOccurs="1" maxOccurs="1" name="ModificationDate" type="s:dateTime" /> + <s:element minOccurs="0" maxOccurs="1" name="ServiceURL" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CoverageSpatial" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CoverageSpectral" type="tns:ArrayOfString" /> + <s:element minOccurs="0" maxOccurs="1" name="CoverageTemporal" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="CoverageRegionOfRegard" type="s:double" /> + <s:element minOccurs="0" maxOccurs="1" name="ResourceType" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="resourceRelations" type="tns:ArrayOfResourceRelation" /> + <s:element minOccurs="0" maxOccurs="1" name="resourceInterfaces" type="tns:ArrayOfResourceInterface" /> + <s:element minOccurs="0" maxOccurs="1" name="xml" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="harvestedfrom" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="harvestedfromDate" type="s:dateTime" /> + <s:element minOccurs="0" maxOccurs="1" name="footprint" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="validationLevel" type="s:int" /> + </s:sequence> + </s:complexType> + <s:complexType name="ArrayOfString"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" /> + </s:sequence> + </s:complexType> + <s:complexType name="ArrayOfResourceRelation"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="ResourceRelation" nillable="true" type="tns:ResourceRelation" /> + </s:sequence> + </s:complexType> + <s:complexType name="ResourceRelation"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="relatedResourceIvoId" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="relationshipType" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="relatedResourceName" type="s:string" /> + </s:sequence> + </s:complexType> + <s:complexType name="ArrayOfResourceInterface"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="ResourceInterface" nillable="true" type="tns:ResourceInterface" /> + </s:sequence> + </s:complexType> + <s:complexType name="ResourceInterface"> + <s:sequence> + <s:element minOccurs="1" maxOccurs="1" name="interfaceNum" type="s:int" /> + <s:element minOccurs="0" maxOccurs="1" name="type" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="qtype" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="accessURL" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="resultType" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="interfaceParams" type="tns:ArrayOfInterfaceParam" /> + </s:sequence> + </s:complexType> + <s:complexType name="ArrayOfInterfaceParam"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="InterfaceParam" nillable="true" type="tns:InterfaceParam" /> + </s:sequence> + </s:complexType> + <s:complexType name="InterfaceParam"> + <s:sequence> + <s:element minOccurs="1" maxOccurs="1" name="interfaceNum" type="s:int" /> + <s:element minOccurs="0" maxOccurs="1" name="name" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="description" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="datatype" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="unit" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ucd" type="s:string" /> + </s:sequence> + </s:complexType> + <s:complexType name="ServiceSimpleImageAccess"> + <s:complexContent mixed="false"> + <s:extension base="tns:DBResource"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="ImageServiceType" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxQueryRegionSizeLong" type="s:double" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxQueryRegionSizeLat" type="s:double" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxImageExtentLong" type="s:double" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxImageExtentLat" type="s:double" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxImageSizeLong" type="s:int" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxImageSizeLat" type="s:int" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxFileSize" type="s:long" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxRecords" type="s:long" /> + <s:element minOccurs="0" maxOccurs="1" name="Format" type="tns:ArrayOfString" /> + <s:element minOccurs="0" maxOccurs="1" name="VOTableColumns" type="s:string" /> + </s:sequence> + </s:extension> + </s:complexContent> + </s:complexType> + <s:complexType name="ServiceCone"> + <s:complexContent mixed="false"> + <s:extension base="tns:DBResource"> + <s:sequence> + <s:element minOccurs="1" maxOccurs="1" name="MaxSearchRadius" type="s:double" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxRecords" type="s:long" /> + <s:element minOccurs="0" maxOccurs="1" name="VOTableColumns" type="s:string" /> + </s:sequence> + </s:extension> + </s:complexContent> + </s:complexType> + <s:complexType name="ServiceSkyNode"> + <s:complexContent mixed="false"> + <s:extension base="tns:DBResource"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="Compliance" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="Latitude" type="s:double" /> + <s:element minOccurs="1" maxOccurs="1" name="Longitude" type="s:double" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxRecords" type="s:long" /> + <s:element minOccurs="0" maxOccurs="1" name="PrimaryTable" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="PrimaryKey" type="s:string" /> + </s:sequence> + </s:extension> + </s:complexContent> + </s:complexType> + <s:element name="LoadResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="LoadResult" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="LoadFlatResource"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="Title" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ShortName" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Publisher" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Creator" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Subject" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Description" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Contributor" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Version" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Identifier" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ReferenceURL" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ServiceURL" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ContactName" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ContactEmail" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Type" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CoverageSpatial" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CoverageSpectral" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CoverageTemporal" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="EntrySize" type="s:float" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxSR" type="s:float" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxRecords" type="s:int" /> + <s:element minOccurs="0" maxOccurs="1" name="ContentLevel" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Facility" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Instrument" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Format" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ResourceType" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Compliance" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="Longitude" type="s:double" /> + <s:element minOccurs="1" maxOccurs="1" name="Latitude" type="s:double" /> + <s:element minOccurs="0" maxOccurs="1" name="PrimaryTable" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="PrimaryKey" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ImageServiceType" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxQueryRegionSizeLat" type="s:float" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxQueryRegionSizeLong" type="s:float" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxImageExtentLat" type="s:int" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxImageExtentLong" type="s:int" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxFileSize" type="s:int" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxImageSizeLat" type="s:int" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxImageSizeLong" type="s:int" /> + <s:element minOccurs="1" maxOccurs="1" name="Date" type="s:dateTime" /> + <s:element minOccurs="0" maxOccurs="1" name="VOTableColumns" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="harvestedfrom" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="footprint" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="validationLevel" type="s:int" /> + <s:element minOccurs="0" maxOccurs="1" name="PassPhrase" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="LoadFlatResourceResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="LoadFlatResourceResult" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="DSQueryRegistry"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="predicate" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="DSQueryRegistryResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="DSQueryRegistryResult"> + <s:complexType> + <s:sequence> + <s:element ref="s:schema" /> + <s:any /> + </s:sequence> + </s:complexType> + </s:element> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="DSQuery"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="sqlStmnt" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="password" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="DSQueryResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="DSQueryResult"> + <s:complexType> + <s:sequence> + <s:element ref="s:schema" /> + <s:any /> + </s:sequence> + </s:complexType> + </s:element> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="HarvestOAI"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="url" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="from" type="s:dateTime" /> + <s:element minOccurs="0" maxOccurs="1" name="passphrase" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="HarvestOAIResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="HarvestOAIResult" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="HarvestVizier"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="passphrase" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="resumptionTokenID" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="HarvestVizierResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="HarvestVizierResult" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="HarvestRecord"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="url" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="IVOA_id" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="passphrase" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="HarvestRecordResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="HarvestRecordResult" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="HarvestAstroGrid"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="passphrase" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="HarvestAstroGridResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="HarvestAstroGridResult" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="DeleteEntry"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="identifier" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="passPhrase" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="DeleteEntryResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="DeleteEntryResult" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="DSKeywordSearch"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="keywords" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="andKeys" type="s:boolean" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="DSKeywordSearchResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="DSKeywordSearchResult"> + <s:complexType> + <s:sequence> + <s:element ref="s:schema" /> + <s:any /> + </s:sequence> + </s:complexType> + </s:element> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="ListDBColumns"> + <s:complexType /> + </s:element> + <s:element name="ListDBColumnsResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="ListDBColumnsResult" type="tns:ArrayOfString" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="DumpRegistry"> + <s:complexType /> + </s:element> + <s:element name="DumpRegistryResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="DumpRegistryResult" type="tns:ArrayOfSimpleResource" /> + </s:sequence> + </s:complexType> + </s:element> + <s:complexType name="ArrayOfSimpleResource"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="SimpleResource" nillable="true" type="tns:SimpleResource" /> + </s:sequence> + </s:complexType> + <s:complexType name="SimpleResource"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="Title" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ShortName" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Publisher" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Creator" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Subject" type="tns:ArrayOfString" /> + <s:element minOccurs="0" maxOccurs="1" name="Description" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Contributor" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="Date" type="s:dateTime" /> + <s:element minOccurs="0" maxOccurs="1" name="Version" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Identifier" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ReferenceURL" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ServiceURL" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ContactName" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ContactEmail" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Type" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CoverageSpatial" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="CoverageSpectral" type="tns:ArrayOfString" /> + <s:element minOccurs="0" maxOccurs="1" name="CoverageTemporal" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="EntrySize" type="s:double" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxSR" type="s:double" /> + <s:element minOccurs="1" maxOccurs="1" name="MaxRecords" type="s:int" /> + <s:element minOccurs="0" maxOccurs="1" name="ContentLevel" type="tns:ArrayOfString" /> + <s:element minOccurs="0" maxOccurs="1" name="Facility" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="Instrument" type="tns:ArrayOfString" /> + <s:element minOccurs="0" maxOccurs="1" name="Format" type="tns:ArrayOfString" /> + <s:element minOccurs="0" maxOccurs="1" name="ServiceType" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="xml" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="validationLevel" type="s:int" /> + </s:sequence> + </s:complexType> + <s:element name="DumpVOResources"> + <s:complexType /> + </s:element> + <s:element name="DumpVOResourcesResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="DumpVOResourcesResult" type="s1:ArrayOfResource" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="Resource" nillable="true" type="s1:Resource" /> + <s:element name="QueryVOResource"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="predicate" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="QueryVOResourceResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="QueryVOResourceResult" type="s1:ArrayOfResource" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="QueryFullVOResource"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="predicate" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="QueryFullVOResourceResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="QueryFullVOResourceResult" type="s1:ArrayOfResource" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="QueryOAIDC"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="predicate" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="QueryOAIDCResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="QueryOAIDCResult" type="s7:ArrayOfOai_dcType" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="oai_dcType" nillable="true" type="s7:oai_dcType" /> + <s:element name="QueryResource"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="predicate" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="QueryResourceResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="QueryResourceResult" type="tns:ArrayOfDBResource" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="QueryRegistry"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="predicate" type="s:string" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="QueryRegistryResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="QueryRegistryResult" type="tns:ArrayOfSimpleResource" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="KeywordSearch"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="keywords" type="s:string" /> + <s:element minOccurs="1" maxOccurs="1" name="andKeys" type="s:boolean" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="KeywordSearchResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="KeywordSearchResult" type="s1:ArrayOfResource" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="Revisions"> + <s:complexType /> + </s:element> + <s:element name="RevisionsResponse"> + <s:complexType> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="RevisionsResult" type="tns:ArrayOfString" /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="string" nillable="true" type="s:string" /> + <s:element name="DataSet" nillable="true"> + <s:complexType> + <s:sequence> + <s:element ref="s:schema" /> + <s:any /> + </s:sequence> + </s:complexType> + </s:element> + <s:element name="ArrayOfString" nillable="true" type="tns:ArrayOfString" /> + <s:element name="ArrayOfSimpleResource" nillable="true" type="tns:ArrayOfSimpleResource" /> + <s:element name="ArrayOfResource" nillable="true" type="s1:ArrayOfResource" /> + <s:element name="ArrayOfOai_dcType" nillable="true" type="s7:ArrayOfOai_dcType" /> + <s:element name="ArrayOfDBResource" nillable="true" type="tns:ArrayOfDBResource" /> + </s:schema> + <s:schema elementFormDefault="qualified" targetNamespace="http://www.ivoa.net/xml/VOResource/v0.10"> + <s:import namespace="http://www.us-vo.org" /> + <s:import namespace="http://www.ivoa.net/xml/VODataService/v0.5" /> + <s:import namespace="http://www.ivoa.net/xml/VORegistry/v0.3" /> + <s:import namespace="http://www.ivoa.net/xml/ConeSearch/v0.3" /> + <s:import namespace="http://www.ivoa.net/xml/OpenSkyNode/v0.1" /> + <s:import namespace="http://www.ivoa.net/xml/SIA/v0.7" /> + <s:complexType name="ArrayOfResource"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" ref="tns:Resource" /> + </s:sequence> + </s:complexType> + <s:complexType name="Resource"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="title" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="shortName" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="identifier" type="s:anyURI" /> + <s:element minOccurs="0" maxOccurs="1" name="curation" type="s1:Curation" /> + <s:element minOccurs="0" maxOccurs="1" name="content" type="s1:Content" /> + </s:sequence> + <s:attribute name="created" type="s:date" /> + <s:attribute name="updated" type="s:date" /> + <s:attribute default="active" name="status" type="s1:ResourceStatus" /> + </s:complexType> + <s:complexType name="Curation"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="publisher" type="s1:ResourceName" /> + <s:element minOccurs="0" maxOccurs="1" name="creator" type="s1:Creator" /> + <s:element minOccurs="0" maxOccurs="unbounded" name="contributor" type="s1:ResourceName" /> + <s:element minOccurs="0" maxOccurs="unbounded" name="date" type="s1:Date" /> + <s:element minOccurs="0" maxOccurs="1" name="version" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="contact" type="s1:Contact" /> + </s:sequence> + </s:complexType> + <s:complexType name="ResourceName"> + <s:simpleContent> + <s:extension base="s:string"> + <s:attribute name="ivo-id" type="s:anyURI" /> + </s:extension> + </s:simpleContent> + </s:complexType> + <s:complexType name="Creator"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="name" type="s1:ResourceName" /> + <s:element minOccurs="0" maxOccurs="1" name="logo" type="s:anyURI" /> + </s:sequence> + </s:complexType> + <s:complexType name="Date"> + <s:simpleContent> + <s:extension base="s:date"> + <s:attribute default="representative" name="role" type="s:string" /> + </s:extension> + </s:simpleContent> + </s:complexType> + <s:complexType name="Contact"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="name" type="s1:ResourceName" /> + <s:element minOccurs="0" maxOccurs="1" name="address" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="email" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="telephone" type="s:string" /> + </s:sequence> + </s:complexType> + <s:complexType name="Content"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="subject" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="description" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="source" type="s1:Source" /> + <s:element minOccurs="0" maxOccurs="1" name="referenceURL" type="s:anyURI" /> + <s:element minOccurs="0" maxOccurs="1" name="type" type="s1:Type" /> + <s:element minOccurs="0" maxOccurs="unbounded" name="contentLevel" type="s1:ContentLevel" /> + <s:element minOccurs="0" maxOccurs="unbounded" name="relationship" type="s1:Relationship" /> + </s:sequence> + </s:complexType> + <s:complexType name="Source"> + <s:simpleContent> + <s:extension base="s:string"> + <s:attribute name="format" type="s:string" /> + </s:extension> + </s:simpleContent> + </s:complexType> + <s:simpleType name="Type"> + <s:restriction base="s:string"> + <s:enumeration value="Other" /> + <s:enumeration value="Archive" /> + <s:enumeration value="Bibliography" /> + <s:enumeration value="Catalog" /> + <s:enumeration value="Journal" /> + <s:enumeration value="Library" /> + <s:enumeration value="Simulation" /> + <s:enumeration value="Survey" /> + <s:enumeration value="Transformation" /> + <s:enumeration value="Education" /> + <s:enumeration value="Outreach" /> + <s:enumeration value="EPOResource" /> + <s:enumeration value="Animation" /> + <s:enumeration value="Artwork" /> + <s:enumeration value="Background" /> + <s:enumeration value="BasicData" /> + <s:enumeration value="Historical" /> + <s:enumeration value="Photographic" /> + <s:enumeration value="Press" /> + <s:enumeration value="Organisation" /> + <s:enumeration value="Project" /> + <s:enumeration value="Registry" /> + </s:restriction> + </s:simpleType> + <s:simpleType name="ContentLevel"> + <s:restriction base="s:string"> + <s:enumeration value="General" /> + <s:enumeration value="Elementary Education" /> + <s:enumeration value="Middle School Education" /> + <s:enumeration value="Secondary Education" /> + <s:enumeration value="Community College" /> + <s:enumeration value="University" /> + <s:enumeration value="Research" /> + <s:enumeration value="Amateur" /> + <s:enumeration value="Informal Education" /> + </s:restriction> + </s:simpleType> + <s:complexType name="Relationship"> + <s:sequence> + <s:element minOccurs="1" maxOccurs="1" name="relationshipType" type="s1:RelationshipType" /> + <s:element minOccurs="0" maxOccurs="unbounded" name="relatedResource" type="s1:ResourceName" /> + </s:sequence> + </s:complexType> + <s:simpleType name="RelationshipType"> + <s:restriction base="s:string"> + <s:enumeration value="mirror-of" /> + <s:enumeration value="service-for" /> + <s:enumeration value="derived-from" /> + <s:enumeration value="related-to" /> + </s:restriction> + </s:simpleType> + <s:simpleType name="ResourceStatus"> + <s:restriction base="s:string"> + <s:enumeration value="active" /> + <s:enumeration value="inactive" /> + <s:enumeration value="deleted" /> + </s:restriction> + </s:simpleType> + <s:complexType name="AccessURL"> + <s:simpleContent> + <s:extension base="s:anyURI"> + <s:attribute name="use" type="s1:AccessURLUse" /> + </s:extension> + </s:simpleContent> + </s:complexType> + <s:simpleType name="AccessURLUse"> + <s:restriction base="s:string"> + <s:enumeration value="full" /> + <s:enumeration value="base" /> + <s:enumeration value="dir" /> + </s:restriction> + </s:simpleType> + <s:complexType name="Organisation"> + <s:complexContent mixed="false"> + <s:extension base="s1:Resource"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="facility" type="s1:ResourceName" /> + <s:element minOccurs="0" maxOccurs="unbounded" name="instrument" type="s1:ResourceName" /> + </s:sequence> + </s:extension> + </s:complexContent> + </s:complexType> + <s:complexType name="Service"> + <s:complexContent mixed="false"> + <s:extension base="s1:Resource"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="interface" type="s1:Interface" /> + </s:sequence> + </s:extension> + </s:complexContent> + </s:complexType> + <s:complexType name="Interface" abstract="true"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="accessURL" type="s1:AccessURL" /> + </s:sequence> + </s:complexType> + <s:complexType name="WebBrowser"> + <s:complexContent mixed="false"> + <s:extension base="s1:Interface" /> + </s:complexContent> + </s:complexType> + <s:complexType name="Capability"> + <s:attribute name="standardID" type="s:anyURI" /> + <s:attribute name="standardURL" type="s:anyURI" /> + </s:complexType> + </s:schema> + <s:schema elementFormDefault="qualified" targetNamespace="http://www.ivoa.net/xml/VODataService/v0.5"> + <s:import namespace="http://www.ivoa.net/xml/VOResource/v0.10" /> + <s:import namespace="http://www.ivoa.net/xml/SIA/v0.7" /> + <s:import namespace="http://www.ivoa.net/xml/OpenSkyNode/v0.1" /> + <s:import namespace="http://www.ivoa.net/xml/ConeSearch/v0.3" /> + <s:complexType name="DataCollection"> + <s:complexContent mixed="false"> + <s:extension base="s1:Resource"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="facility" type="s1:ResourceName" /> + <s:element minOccurs="0" maxOccurs="unbounded" name="instrument" type="s1:ResourceName" /> + <s:element minOccurs="0" maxOccurs="1" name="coverage" type="s2:Coverage" /> + <s:element minOccurs="0" maxOccurs="unbounded" name="format" type="s2:Format" /> + <s:element minOccurs="0" maxOccurs="unbounded" name="rights" type="s2:Rights" /> + <s:element minOccurs="0" maxOccurs="1" name="accessURL" type="s1:AccessURL" /> + </s:sequence> + </s:extension> + </s:complexContent> + </s:complexType> + <s:complexType name="Coverage"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="spatial" type="s2:Spatial" /> + <s:element minOccurs="0" maxOccurs="1" name="spectral" type="s2:Spectral" /> + <s:element minOccurs="0" maxOccurs="1" name="temporal" type="s2:Temporal" /> + </s:sequence> + </s:complexType> + <s:complexType name="Spatial"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="region" type="s2:Region" /> + <s:element minOccurs="0" maxOccurs="1" name="resolution" type="s:float" /> + <s:element minOccurs="0" maxOccurs="1" name="regionOfRegard" type="s:float" /> + </s:sequence> + </s:complexType> + <s:complexType name="Region" abstract="true" /> + <s:complexType name="AllSky"> + <s:complexContent mixed="false"> + <s:extension base="s2:Region" /> + </s:complexContent> + </s:complexType> + <s:complexType name="CircleRegion"> + <s:complexContent mixed="false"> + <s:extension base="s2:Region"> + <s:sequence> + <s:element minOccurs="1" maxOccurs="1" name="coordFrame" type="s2:CoordFrame" /> + <s:element minOccurs="0" maxOccurs="1" name="center" type="s2:Position" /> + <s:element minOccurs="1" maxOccurs="1" name="radius" type="s:float" /> + </s:sequence> + </s:extension> + </s:complexContent> + </s:complexType> + <s:simpleType name="CoordFrame"> + <s:restriction base="s:string"> + <s:enumeration value="ICRS" /> + <s:enumeration value="FK5" /> + <s:enumeration value="FK4" /> + <s:enumeration value="ECL" /> + <s:enumeration value="GAL" /> + <s:enumeration value="SGAL" /> + </s:restriction> + </s:simpleType> + <s:complexType name="Position"> + <s:sequence> + <s:element minOccurs="1" maxOccurs="1" name="long" type="s:double" /> + <s:element minOccurs="1" maxOccurs="1" name="lat" type="s:double" /> + </s:sequence> + </s:complexType> + <s:complexType name="CoordRange"> + <s:complexContent mixed="false"> + <s:extension base="s2:Region"> + <s:sequence> + <s:element minOccurs="1" maxOccurs="1" name="coordFrame" type="s2:CoordFrame" /> + <s:element minOccurs="0" maxOccurs="1" name="long" type="s2:AngleRange" /> + <s:element minOccurs="0" maxOccurs="1" name="lat" type="s2:AngleRange" /> + </s:sequence> + </s:extension> + </s:complexContent> + </s:complexType> + <s:complexType name="AngleRange"> + <s:sequence> + <s:element minOccurs="1" maxOccurs="1" name="min" type="s:double" /> + <s:element minOccurs="1" maxOccurs="1" name="max" type="s:double" /> + </s:sequence> + </s:complexType> + <s:complexType name="Spectral"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="waveband" type="s2:Waveband" /> + <s:element minOccurs="0" maxOccurs="1" name="range" type="s2:WavelengthRange" /> + <s:element minOccurs="0" maxOccurs="1" name="resolution" type="s:float" /> + </s:sequence> + </s:complexType> + <s:simpleType name="Waveband"> + <s:restriction base="s:string"> + <s:enumeration value="Radio" /> + <s:enumeration value="Millimeter" /> + <s:enumeration value="Infrared" /> + <s:enumeration value="Optical" /> + <s:enumeration value="UV" /> + <s:enumeration value="EUV" /> + <s:enumeration value="X-ray" /> + <s:enumeration value="Gamma-ray" /> + </s:restriction> + </s:simpleType> + <s:complexType name="WavelengthRange"> + <s:sequence> + <s:element minOccurs="1" maxOccurs="1" name="min" type="s:float" /> + <s:element minOccurs="1" maxOccurs="1" name="max" type="s:float" /> + </s:sequence> + </s:complexType> + <s:complexType name="Temporal"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="startTime" type="s:date" /> + <s:element minOccurs="0" maxOccurs="1" name="endTime" type="s:date" /> + <s:element minOccurs="0" maxOccurs="1" name="resolution" type="s:float" /> + </s:sequence> + </s:complexType> + <s:complexType name="Format"> + <s:simpleContent> + <s:extension base="s:string"> + <s:attribute default="false" name="isMIMEType" type="s:boolean" /> + </s:extension> + </s:simpleContent> + </s:complexType> + <s:simpleType name="Rights"> + <s:restriction base="s:string"> + <s:enumeration value="public" /> + <s:enumeration value="secure" /> + <s:enumeration value="proprietary" /> + </s:restriction> + </s:simpleType> + <s:complexType name="WebService"> + <s:complexContent mixed="false"> + <s:extension base="s1:Interface" /> + </s:complexContent> + </s:complexType> + <s:complexType name="GLUService"> + <s:complexContent mixed="false"> + <s:extension base="s1:Interface" /> + </s:complexContent> + </s:complexType> + <s:complexType name="ParamHTTP"> + <s:complexContent mixed="false"> + <s:extension base="s1:Interface"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="resultType" type="s:string" /> + <s:element minOccurs="0" maxOccurs="unbounded" name="param" type="s2:Param" /> + </s:sequence> + <s:attribute name="qtype" type="s2:HTTPQueryType" /> + </s:extension> + </s:complexContent> + </s:complexType> + <s:complexType name="Param"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="name" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="description" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="dataType" type="s2:DataType" /> + <s:element minOccurs="0" maxOccurs="1" name="unit" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="ucd" type="s:string" /> + </s:sequence> + </s:complexType> + <s:complexType name="DataType"> + <s:simpleContent> + <s:extension base="s2:ScalarDataType"> + <s:attribute default="1" name="arraysize" type="s:token" /> + </s:extension> + </s:simpleContent> + </s:complexType> + <s:simpleType name="ScalarDataType"> + <s:restriction base="s:string"> + <s:enumeration value="boolean" /> + <s:enumeration value="bit" /> + <s:enumeration value="unsignedByte" /> + <s:enumeration value="short" /> + <s:enumeration value="int" /> + <s:enumeration value="long" /> + <s:enumeration value="char" /> + <s:enumeration value="unicodeChar" /> + <s:enumeration value="float" /> + <s:enumeration value="double" /> + <s:enumeration value="floatComplex" /> + <s:enumeration value="doubleComplex" /> + </s:restriction> + </s:simpleType> + <s:simpleType name="HTTPQueryType"> + <s:restriction base="s:string"> + <s:enumeration value="GET" /> + <s:enumeration value="POST" /> + </s:restriction> + </s:simpleType> + <s:complexType name="SkyService"> + <s:complexContent mixed="false"> + <s:extension base="s1:Service"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="facility" type="s1:ResourceName" /> + <s:element minOccurs="0" maxOccurs="unbounded" name="instrument" type="s1:ResourceName" /> + <s:element minOccurs="0" maxOccurs="1" name="coverage" type="s2:Coverage" /> + </s:sequence> + </s:extension> + </s:complexContent> + </s:complexType> + <s:complexType name="TabularSkyService"> + <s:complexContent mixed="false"> + <s:extension base="s2:SkyService"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="table" type="s2:Table" /> + </s:sequence> + </s:extension> + </s:complexContent> + </s:complexType> + <s:complexType name="Table"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="name" type="s:string" /> + <s:element minOccurs="0" maxOccurs="1" name="description" type="s:string" /> + <s:element minOccurs="0" maxOccurs="unbounded" name="column" type="s2:Param" /> + </s:sequence> + <s:attribute name="role" type="s:string" /> + </s:complexType> + </s:schema> + <s:schema elementFormDefault="qualified" targetNamespace="http://www.ivoa.net/xml/VORegistry/v0.3"> + <s:import namespace="http://www.ivoa.net/xml/VOResource/v0.10" /> + <s:complexType name="Authority"> + <s:complexContent mixed="false"> + <s:extension base="s1:Resource"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="managingOrg" type="s1:ResourceName" /> + </s:sequence> + </s:extension> + </s:complexContent> + </s:complexType> + <s:complexType name="Registry"> + <s:complexContent mixed="false"> + <s:extension base="s1:Service"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="unbounded" name="managedAuthority" type="s:string" /> + </s:sequence> + </s:extension> + </s:complexContent> + </s:complexType> + </s:schema> + <s:schema elementFormDefault="qualified" targetNamespace="http://www.ivoa.net/xml/SIA/v0.7"> + <s:import namespace="http://www.ivoa.net/xml/VODataService/v0.5" /> + <s:import namespace="http://www.ivoa.net/xml/VOResource/v0.10" /> + <s:complexType name="SimpleImageAccess"> + <s:complexContent mixed="false"> + <s:extension base="s2:TabularSkyService"> + <s:sequence> + <s:element minOccurs="0" maxOccurs="1" name="capability" type="s4:SIACapability" /> + </s:sequence> + </s:extension> + </s:complexContent> + </s:complexType> + <s:complexType name="SIACapability"> + <s:complexContent mixed="false"> + <s:extension base="s4:SIACapRestriction"> + <s:sequence> + <s:element minOccurs="1" maxOccurs="1" name="imageServiceType" type="s4:ImageServiceType" /> + <s:element minOccurs="0" maxOccurs="1" name="maxQueryRegionSize" type="s4:SkySize" /> + <s:element minOccurs="0" maxOccurs="1" name="maxImageExtent" type="s4:SkySize" /> + <s:element minOccurs="0" maxOccurs="1" name="maxImageSize" type="s4:ImageSize" /> + <s:element minOccurs="1" maxOccurs="1" name="maxFileSize" type="s:int" /> + <s:element minOccurs="1" maxOccurs="1" name="maxRecords" type="s:int" /> + </s:sequence> + </s:extension> + </s:complexContent> + </s:complexType> + <s:complexType name="SIACapRestriction" abstract="true"> + <s:complexContent mixed="false"> + <s:extension base="s1:Capability" /> + </s:complexContent> + </s:complexType> + <s:simpleType name="ImageServiceType"> + <s:restriction base="s:string"> + <s:enumeration value="Cutout" /> + <s:enumeration value="Mosaic" /> + <s:enumeration value="Atlas" /> + <s:enumeration value="Pointed" /> + </s:restriction> + </s:simpleType> + <s:complexType name="SkySize"> + <s:sequence> + <s:element minOccurs="1" maxOccurs="1" name="long" type="s:float" /> + <s:element minOccurs="1" maxOccurs="1" name="lat" type="s:float" /> + </s:sequence> + </s:complexType> + <s:complexType name="ImageSize"> + <s:sequence> + <s:element minOccurs="1" maxOccurs="1" name="long" type="s:int" /> + <s:element minOccurs="1" maxOccurs="1" name="lat" type="s:int" /> + </s:sequence> + </s:complexType> + </s:schema> + <s:schema elementFormDefault="qualified" targetNamespace="http://www.ivoa.net/xml/ConeSearch/v0.3"> + <s:import namespace="http://www.ivoa.net/xml/VOResource/v0.10" /> + <s:import namespace="http://www.ivoa.net/xml/VODataService/v0.5" /> + <s:complexType name="CSCapRestriction" abstract="true"> + <s:complexContent mixed="false"> + <s:extension base="s1:Capability" /> + </s:complexContent> + </s:complexType> + <s:complexType name="ConeSearchCapability"> + <s:complexContent mixed="false"> + <s:extension base="s5:CSCapRestriction"> + ... [truncated message content] |
From: <bov...@us...> - 2007-06-08 21:59:36
|
Revision: 1392 http://svn.sourceforge.net/pywebsvcs/?rev=1392&view=rev Author: boverhof Date: 2007-06-08 14:59:37 -0700 (Fri, 08 Jun 2007) Log Message: ----------- M test/test_callhome.py A ZSI/twisted/wsgi.py M ZSI/twisted/__init__.py M ZSI/twisted/WSresource.py -- moving some stuff around, like to use soap handler stuff for all WSGI -- Added a "DeferHandlerChain" for twisted, did some minor refactoring to "render_POST" in order to support it, doesn't affect existing apps. This will add all soap "handler" callbacks into a Deferred, thus returning control to the reactor before processing the soap request/response messages. To use this processing model just set appropriate chain factory protocol from ZSI.twisted.WSresource import * DefaultHandlerChainFactory.protocol = DeferHandlerChain WSAddressHandlerChainFactory.protocol = DeferHandlerChain WSSecurityHandlerChainFactory WSResource.factory = DefaultHandlerChainFactory # or WSResource.factory = WSAddressHandlerChainFactory # or WSResource.factory = Modified Paths: -------------- trunk/zsi/ZSI/twisted/WSresource.py trunk/zsi/ZSI/twisted/__init__.py trunk/zsi/test/test_callhome.py Added Paths: ----------- trunk/zsi/ZSI/twisted/wsgi.py Modified: trunk/zsi/ZSI/twisted/WSresource.py =================================================================== --- trunk/zsi/ZSI/twisted/WSresource.py 2007-06-08 21:31:45 UTC (rev 1391) +++ trunk/zsi/ZSI/twisted/WSresource.py 2007-06-08 21:59:37 UTC (rev 1392) @@ -24,65 +24,13 @@ from ZSI.address import Address from ZSI.ServiceContainer import WSActionException +from interfaces import CheckInputArgs, HandlerChainInterface, CallbackChainInterface,\ + DataHandler, DefaultHandlerChain + # # Stability: Unstable -# - -class HandlerChainInterface(Interface): - - def processRequest(self, input, **kw): - """returns a representation of the request, the - last link in the chain must return a response - pyobj with a typecode attribute. - Parameters: - input -- - Keyword Parameters: - request -- HTTPRequest instance - resource -- Resource instance - """ - def processResponse(self, output, **kw): - """returns a string representing the soap response. - Parameters - output -- - Keyword Parameters: - request -- HTTPRequest instance - resource -- Resource instance - """ - -class CallbackChainInterface(Interface): - - def processRequest(self, input, **kw): - """returns a response pyobj with a typecode - attribute. - Parameters: - input -- - Keyword Parameters: - request -- HTTPRequest instance - resource -- Resource instance - """ - -class DataHandler: - """ - class variables: - readerClass -- factory class to create reader for ParsedSoap instances. - writerClass -- ElementProxy implementation to use for SoapWriter instances. - """ - classProvides(HandlerChainInterface) - readerClass = None - writerClass = None - - @classmethod - def processRequest(cls, input, **kw): - return ParsedSoap(input, readerclass=cls.readerClass) - - @classmethod - def processResponse(cls, output, **kw): - sw = SoapWriter(outputclass=cls.writerClass) - sw.serialize(output) - return sw - - +# class DefaultCallbackHandler: classProvides(CallbackChainInterface) @@ -218,26 +166,12 @@ raise return rsp_pyobj + - -def CheckInputArgs(*interfaces): - """Must provide at least one interface, the last one may be repeated. +class DeferHandlerChain: + """Each handler is """ - l = len(interfaces) - def wrapper(func): - def check_args(self, *args, **kw): - for i in range(len(args)): - if (l > i and interfaces[i].providedBy(args[i])) or interfaces[-1].providedBy(args[i]): - continue - if l > i: raise TypeError, 'arg %s does not implement %s' %(args[i], interfaces[i]) - raise TypeError, 'arg %s does not implement %s' %(args[i], interfaces[-1]) - func(self, *args, **kw) - return check_args - return wrapper - -class DefaultHandlerChain: - @CheckInputArgs(CallbackChainInterface, HandlerChainInterface) def __init__(self, cb, *handlers): self.handlercb = cb @@ -245,31 +179,51 @@ self.debug = len(log.theLogPublisher.observers) > 0 def processRequest(self, arg, **kw): - if self.debug: - log.msg('--->PROCESS REQUEST\n%s' %arg, debug=1) - + from twisted.internet import reactor + from twisted.internet.defer import Deferred + + debug = self.debug + if debug: log.msg('--->DEFER PROCESS REQUEST: %s' %arg, debug=1) + + d = Deferred() for h in self.handlers: - arg = h.processRequest(arg, **kw) + if debug: + log.msg('\t%s handler: %s' %(arg, h), debug=1) + log.msg('\thandler callback: %s' %h.processRequest) + #arg = h.processRequest(arg, **kw) + d.addCallback(h.processRequest, **kw) - return self.handlercb.processRequest(arg, **kw) + #return self.handlercb.processRequest(arg, **kw) + d.addCallback(self.handlercb.processRequest, **kw) + reactor.callLater(.0001, d.callback, arg) + #return d - def processResponse(self, arg, **kw): - if self.debug: - log.msg('===>PROCESS RESPONSE: %s' %str(arg), debug=1) + #def processResponse(self, arg, **kw): + #from twisted.internet.defer import Deferred + + #debug = self.debug + if debug: log.msg('===>DEFER PROCESS RESPONSE: %s' %str(arg), debug=1) - if arg is None: - return - + #if arg is None: + # return d + for h in self.handlers: - arg = h.processResponse(arg, **kw) + if debug: log.msg('\t%s handler: %s' %(arg, h), debug=1) + #arg = h.processResponse(arg, **kw) + d.addCallback(h.processResponse, **kw) - s = str(arg) - if self.debug: - log.msg(s, debug=1) + #s = str(arg) + #if debug: log.msg(s, debug=1) + #return s + + # convert SoapWriter into a string + d.addCallback(str) + return d + + def processResponse(self, arg, **kw): + return arg - return s - class DefaultHandlerChainFactory: protocol = DefaultHandlerChain @@ -285,8 +239,8 @@ def newInstance(cls): return cls.protocol(WSAddressCallbackHandler, DataHandler, WSAddressHandler()) - + class WSResource(twisted.web.resource.Resource, object): """ class variables: @@ -302,7 +256,7 @@ """ twisted.web.resource.Resource.__init__(self) - def _writeResponse(self, request, response, status=200): + def _writeResponse(self, response, request, status=200): """ request -- request message response --- response message @@ -318,38 +272,32 @@ request.setHeader("Content-Length", str(len(response))) request.write(response) request.finish() - return NOT_DONE_YET - def _writeFault(self, request, ex): + def _writeFault(self, fail, request): """ + fail -- failure request -- request message ex -- Exception """ - response = None - response = fault.FaultFromException(ex, False, sys.exc_info()[2]).AsSOAP() - log.err('SOAP FAULT: %s' % response) - return self._writeResponse(request, response, status=500) + response = fault.FaultFromException(fail.value, False, fail.tb).AsSOAP() + self._writeResponse(response, request, status=500) def render_POST(self, request): """Dispatch Method called by twisted render, creates a request/response handler chain. request -- twisted.web.server.Request """ + from twisted.internet.defer import maybeDeferred + chain = self.factory.newInstance() data = request.content.read() - try: - pyobj = chain.processRequest(data, request=request, resource=self) - except Exception, ex: - return self._writeFault(request, ex) + + d = maybeDeferred(chain.processRequest, data, request=request, resource=self) + d.addCallback(chain.processResponse, request=request, resource=self) + d.addCallback(self._writeResponse, request) + d.addErrback(self._writeFault, request) + + return NOT_DONE_YET - try: - soap = chain.processResponse(pyobj, request=request, resource=self) - except Exception, ex: - return self._writeFault(request, ex) - if soap is not None: - return self._writeResponse(request, soap) - request.finish() - return NOT_DONE_YET - Modified: trunk/zsi/ZSI/twisted/__init__.py =================================================================== --- trunk/zsi/ZSI/twisted/__init__.py 2007-06-08 21:31:45 UTC (rev 1391) +++ trunk/zsi/ZSI/twisted/__init__.py 2007-06-08 21:59:37 UTC (rev 1392) @@ -4,4 +4,5 @@ # $Id$ ########################################################################### -__all__=['WSresource', 'WSsecurity'] +__all__=['interfaces', 'client', 'WSresource', 'WSsecurity'] +import interfaces \ No newline at end of file Added: trunk/zsi/ZSI/twisted/wsgi.py =================================================================== --- trunk/zsi/ZSI/twisted/wsgi.py (rev 0) +++ trunk/zsi/ZSI/twisted/wsgi.py 2007-06-08 21:59:37 UTC (rev 1392) @@ -0,0 +1,186 @@ +############################################################################ +# Joshua R. Boverhof, LBNL +# See Copyright for copyright notice! +# $Id: __init__.py 1132 2006-02-17 01:55:41Z boverhof $ +########################################################################### +import os, sys, warnings +from StringIO import StringIO + +# twisted & related imports +from zope.interface import classProvides, implements, Interface +from twisted.python import log, failure +#from twisted.web.error import NoResource +#from twisted.web.server import NOT_DONE_YET +#import twisted.web.http +#import twisted.web.resource + +# ZSI imports +from ZSI import _get_element_nsuri_name, EvaluateException, ParseException +from ZSI import fault, ParsedSoap, SoapWriter + + +# WS-Address related imports +from ZSI.address import Address + + +class WSAddressException(Exception): + """ + """ + +from ZSI.twisted.interfaces import HandlerChainInterface, CallbackChainInterface,\ + DataHandler, CheckInputArgs, DefaultHandlerChain + + + +class DefaultCallbackHandler: + classProvides(CallbackChainInterface) + + @classmethod + def processRequest(cls, ps, **kw): + """invokes callback that should return a (request,response) tuple. + representing the SOAP request and response respectively. + ps -- ParsedSoap instance representing HTTP Body. + request -- twisted.web.server.Request + """ + #env = kw['env'] + #start_response = kw['start_response'] + resource = kw['resource'] + #request = kw['request'] + method = getattr(resource, 'soap_%s' % + _get_element_nsuri_name(ps.body_root)[-1]) + + try: + req_pyobj,rsp_pyobj = method(ps) + except TypeError, ex: + log.err( + 'ERROR: service %s is broken, method MUST return request, response'\ + % cls.__name__ + ) + raise + except Exception, ex: + log.err('failure when calling bound method') + raise + + return rsp_pyobj + + +class DefaultHandlerChainFactory: + protocol = DefaultHandlerChain + + @classmethod + def newInstance(cls): + return cls.protocol(DefaultCallbackHandler, DataHandler) + + + +class WSGIApplication(dict): + encoding = "UTF-8" + + def __call__(self, env, start_response): + """do dispatching, else process + """ + script = env['SCRIPT_NAME'] # consumed + ipath = os.path.split(env['PATH_INFO'])[1:] + for i in range(1, len(ipath)+1): + path = os.path.join(*ipath[:i]) + print "PATH: ", path + application = self.get(path) + if application is not None: + env['SCRIPT_NAME'] = script + path + env['PATH_INFO'] = '' + print "SCRIPT: ", env['SCRIPT_NAME'] + return application(env, start_response) + + return self._request_cb(env, start_response) + + def _request_cb(self, env, start_response): + """callback method, override + """ + start_response("404 ERROR", [('Content-Type','text/plain')]) + return ['Move along people, there is nothing to see to hear'] + + +class SOAPApplication(WSGIApplication): + """ + """ + factory = DefaultHandlerChainFactory + soapAction = {} + root = {} + + def __init__(self, **kw): + dict.__init__(self, **kw) + self.delegate = None + + def _request_cb(self, env, start_response): + """process request, + """ + if env['REQUEST_METHOD'] == 'GET': + return self._handle_GET(env, start_response) + + if env['REQUEST_METHOD'] == 'POST': + return self._handle_POST(env, start_response) + + start_response("500 ERROR", [('Content-Type','text/plain')]) + s = StringIO() + h = env.items(); h.sort() + for k,v in h: + print >>s, k,'=',`v` + return [s.getvalue()] + + def _handle_GET(self, env, start_response): + if env['QUERY_STRING'].lower() == 'wsdl': + start_response("200 OK", [('Content-Type','text/plain')]) + return ['NO WSDL YET'] + + start_response("404 ERROR", [('Content-Type','text/plain')]) + return ['NO RESOURCE FOR GET'] + + def _handle_POST(self, env, start_response): + """Dispatch Method called by twisted render, creates a + request/response handler chain. + request -- twisted.web.server.Request + """ + input = env['wsgi.input'] + data = input.read( int(env['CONTENT_LENGTH']) ) + mimeType = "text/xml" + if self.encoding is not None: + mimeType = 'text/xml; charset="%s"' % self.encoding + + request = None + resource = self.delegate or self + chain = self.factory.newInstance() + try: + pyobj = chain.processRequest(data, request=request, resource=resource) + except Exception, ex: + start_response("500 ERROR", [('Content-Type',mimeType)]) + return [fault.FaultFromException(ex, False, sys.exc_info()[2]).AsSOAP()] + + try: + soap = chain.processResponse(pyobj, request=request, resource=resource) + except Exception, ex: + start_response("500 ERROR", [('Content-Type',mimeType)]) + return [fault.FaultFromException(ex, False, sys.exc_info()[2]).AsSOAP()] + + start_response("200 OK", [('Content-Type',mimeType)]) + return [soap] + + +def test(app, port=8080, host="localhost"): + """ + """ + import sys + from twisted.internet import reactor + from twisted.python import log + from twisted.web2.channel import HTTPFactory + from twisted.web2.server import Site + from twisted.web2.wsgi import WSGIResource + + log.startLogging(sys.stdout) + reactor.listenTCP(port, + HTTPFactory( Site(WSGIResource(app)) ), + interface=host, + ) + reactor.run() + + + Modified: trunk/zsi/test/test_callhome.py =================================================================== --- trunk/zsi/test/test_callhome.py 2007-06-08 21:31:45 UTC (rev 1391) +++ trunk/zsi/test/test_callhome.py 2007-06-08 21:59:37 UTC (rev 1392) @@ -4,7 +4,7 @@ from ZSI.wstools.logging import gridLog os.environ['GRIDLOG_ON'] = '1' -os.environ['GRIDLOG_DEST'] = "gridlog-udp://portnoy.lbl.gov:15100" +os.environ['GRIDLOG_DEST'] = "gridlog-udp://netlogger.lbl.gov:15100" class TestCase(unittest.TestCase): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2007-06-29 22:50:58
|
Revision: 1400 http://svn.sourceforge.net/pywebsvcs/?rev=1400&view=rev Author: boverhof Date: 2007-06-29 15:50:57 -0700 (Fri, 29 Jun 2007) Log Message: ----------- M test/test_t8.py M test/wsdl2py/servers/BasicServer.py M test/wsdl2py/servers/DateService.py M test/wsdl2py/servers/SquareService.py M test/wsdl2py/servers/EchoWSAddr200403Server.py M test/wsdl2py/servers/EchoServer.py M test/wsdl2py/servers/FinancialService.py M test/wsdl2py/servers/WhiteMesa.py M ZSI/twisted/wsgi.py M ZSI/dispatch.py M ZSI/__init__.py M ZSI/ServiceProxy.py M ZSI/ServiceContainer.py M ZSI/generate/wsdl2dispatch.py M ZSI/generate/commands.py M ZSI/TC.py M ZSI/client.py -- update server to return request,response making some changes so can use ~same generated code for ServiceContainer, WSGI, twisted, etc -- added UNICODE_ENCODING="utf-8" that use, changed TC.String to encode all parsed strings to expected encoding. Should be no issues, except maybe expected type (unicode vs. string), since utf-8 is superset of ascii the default codec Modified Paths: -------------- trunk/zsi/ZSI/ServiceContainer.py trunk/zsi/ZSI/ServiceProxy.py trunk/zsi/ZSI/TC.py trunk/zsi/ZSI/__init__.py trunk/zsi/ZSI/client.py trunk/zsi/ZSI/dispatch.py trunk/zsi/ZSI/generate/commands.py trunk/zsi/ZSI/generate/wsdl2dispatch.py trunk/zsi/ZSI/twisted/wsgi.py trunk/zsi/test/test_t8.py trunk/zsi/test/wsdl2py/servers/BasicServer.py trunk/zsi/test/wsdl2py/servers/DateService.py trunk/zsi/test/wsdl2py/servers/EchoServer.py trunk/zsi/test/wsdl2py/servers/EchoWSAddr200403Server.py trunk/zsi/test/wsdl2py/servers/FinancialService.py trunk/zsi/test/wsdl2py/servers/SquareService.py trunk/zsi/test/wsdl2py/servers/WhiteMesa.py Modified: trunk/zsi/ZSI/ServiceContainer.py =================================================================== --- trunk/zsi/ZSI/ServiceContainer.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/ServiceContainer.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -103,9 +103,9 @@ try: if isWSResource is True: - result = method(ps, address) + request,result = method(ps, address) else: - result = method(ps) + request,result = method(ps) except Exception, e: return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw) Modified: trunk/zsi/ZSI/ServiceProxy.py =================================================================== --- trunk/zsi/ZSI/ServiceProxy.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/ServiceProxy.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -30,32 +30,31 @@ service that is described with WSDL. The proxy exposes methods that reflect the methods of the remote web service.""" - def __init__(self, wsdl, url=None, service=None, port=None, tracefile=None, - nsdict=None, transport=None, transdict=None, + def __init__(self, wsdl, url=None, service=None, port=None, cachedir=os.path.join(os.path.expanduser('~'), '.zsi_service_proxy_dir'), - asdict=True): + asdict=True, lazy=False, pyclass=False, force=False, **kw): """ Parameters: wsdl -- URL of WSDL. url -- override WSDL SOAP address location service -- service name or index port -- port name or index - tracefile -- - nsdict -- key prefix to namespace mappings for serialization - in SOAP Envelope. - transport -- override default transports. - transdict -- arguments to pass into HTTPConnection constructor. cachedir -- where to store generated files asdict -- use dicts, else use generated pyclass + lazy -- use lazy typecode evaluation + pyclass -- use pyclass_type metaclass adds properties, "new_", "set_, + "get_" methods for schema element and attribute declarations. + force -- regenerate all WSDL code, write over cache. + + NOTE: all other **kw will be passed to the underlying + ZSI.client._Binding constructor. + """ self._asdict = asdict # client._Binding - self._tracefile = tracefile - self._nsdict = nsdict or {} - self._transdict = transdict - self._transport = transport self._url = url + self._kw = kw # WSDL self._wsdl = wstools.WSDLTools.WSDLReader().loadFromURL(wsdl) @@ -65,6 +64,9 @@ self._name = self._service.name self._methods = {} self._cachedir = cachedir + self._lazy = lazy + self._pyclass = pyclass + self._force = force # Set up rpc methods for service/port port = self._port @@ -102,13 +104,19 @@ del cp; cp = None option = location.replace(':', '-') # colons seem to screw up option - if (cp is not None and cp.has_section(section) and + if (not self._force and cp is not None and cp.has_section(section) and cp.has_option(section, option)): types = cp.get(section, option) else: # dont do anything to anames - containers.ContainerBase.func_aname = lambda instnc,n: str(n) - files = commands.wsdl2py(['-o', cachedir, location]) + if not self._pyclass: + containers.ContainerBase.func_aname = lambda instnc,n: str(n) + + args = ['-o', cachedir, location] + if self._lazy: args.insert(0, '-l') + if self._pyclass: args.insert(0, '-b') + files = commands.wsdl2py(args) + if cp is None: cp = ConfigParser() if not cp.has_section(section): cp.add_section(section) types = filter(lambda f: f.endswith('_types.py'), files)[0] @@ -144,10 +152,10 @@ types = cp.get(section, option) else: # dont do anything to anames - containers.ContainerBase.func_aname = lambda instnc,n: str(n) + if not self._pyclass: + containers.ContainerBase.func_aname = lambda instnc,n: str(n) + from ZSI.wstools import XMLSchema - - reader = XMLSchema.SchemaReader(base_url=location) if xml is not None and isinstance(xml, basestring): schema = reader.loadFromString(xml) @@ -164,6 +172,9 @@ schema = True simple_naming = False address = False + lazy = self._lazy + complexType = self._pyclass + schema.location = location files = commands._wsdl2py(options, schema) if cp is None: cp = ConfigParser() @@ -205,10 +216,9 @@ if len(method.callinfo.inparams) == len(kwargs): callinfo = method.callinfo - binding = _Binding(tracefile=self._tracefile, - url=self._url or callinfo.location, - nsdict=self._nsdict, - soapaction=callinfo.soapAction) + binding = _Binding(url=self._url or callinfo.location, + soapaction=callinfo.soapAction, + **self._kw) kw = dict(unique=True) if callinfo.use == 'encoded': Modified: trunk/zsi/ZSI/TC.py =================================================================== --- trunk/zsi/ZSI/TC.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/TC.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -8,7 +8,7 @@ _find_arraytype, _find_default_namespace, _find_href, _find_encstyle, \ _resolve_prefix, _find_xsi_attr, _find_type, \ _find_xmlns_prefix, _get_element_nsuri_name, _get_idstr, \ - _Node, EvaluateException, \ + _Node, EvaluateException, UNICODE_ENCODING, \ _valid_encoding, ParseException from ZSI.wstools.Namespaces import SCHEMA, SOAP @@ -708,16 +708,19 @@ def text_to_data(self, text, elt, ps): '''convert text into typecode specific data. + Encode all strings as UTF-8, which will be type 'str' + not 'unicode' ''' if self.strip: text = text.strip() if self.pyclass is not None: - return self.pyclass(text) - return text + return self.pyclass(text.encode(UNICODE_ENCODING)) + return text.encode(UNICODE_ENCODING) def get_formatted_content(self, pyobj): if type(pyobj) not in _stringtypes: pyobj = str(pyobj) - if type(pyobj) == types.UnicodeType: pyobj = pyobj.encode('utf-8') + if type(pyobj) == unicode: + return pyobj.encode(UNICODE_ENCODING) return pyobj Modified: trunk/zsi/ZSI/__init__.py =================================================================== --- trunk/zsi/ZSI/__init__.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/__init__.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -150,8 +150,8 @@ ## ## Public constants. from ZSI.wstools.Namespaces import ZSI_SCHEMA_URI +UNICODE_ENCODING = 'utf-8' - ## ## Not public constants. _inttypes = [ _types.IntType, _types.LongType ] Modified: trunk/zsi/ZSI/client.py =================================================================== --- trunk/zsi/ZSI/client.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/client.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -5,7 +5,8 @@ from ZSI import _copyright, _seqtypes, ParsedSoap, SoapWriter, TC, ZSI_SCHEMA_URI,\ EvaluateException, FaultFromFaultMessage, _child_elements, _attrs, _find_arraytype,\ - _find_type, _get_idstr, _get_postvalue_from_absoluteURI, FaultException, WSActionException + _find_type, _get_idstr, _get_postvalue_from_absoluteURI, FaultException, WSActionException,\ + UNICODE_ENCODING from ZSI.auth import AUTH from ZSI.TC import AnyElement, AnyType, String, TypeCode, _get_global_element_declaration,\ _get_type_definition @@ -300,7 +301,7 @@ request_uri = _get_postvalue_from_absoluteURI(url) self.h.putrequest("POST", request_uri) self.h.putheader("Content-Length", "%d" % len(soapdata)) - self.h.putheader("Content-Type", 'text/xml; charset=utf-8') + self.h.putheader("Content-Type", 'text/xml; charset="%s"' %UNICODE_ENCODING) self.__addcookies() for header,value in headers.items(): Modified: trunk/zsi/ZSI/dispatch.py =================================================================== --- trunk/zsi/ZSI/dispatch.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/dispatch.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -169,13 +169,13 @@ def _JonPySendXML(text, code=200, **kw): req = kw['request'] - req.set_header("Content-Type", 'text/xml; charset="utf-8"') + req.set_header("Content-Type", 'text/xml; charset="%s"' %UNICODE_ENCODING) req.set_header("Content-Length", str(len(text))) req.write(text) def _CGISendXML(text, code=200, **kw): print 'Status: %d' % code - print 'Content-Type: text/xml; charset="utf-8"' + print 'Content-Type: text/xml; charset="%s"' %UNICODE_ENCODING print 'Content-Length: %d' % len(text) print '' print text @@ -195,7 +195,7 @@ self.send_response(code) if text: - self.send_header('Content-type', 'text/xml; charset="utf-8"') + self.send_header('Content-type', 'text/xml; charset="%s"' %UNICODE_ENCODING) self.send_header('Content-Length', str(len(text))) self.end_headers() Modified: trunk/zsi/ZSI/generate/commands.py =================================================================== --- trunk/zsi/ZSI/generate/commands.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/generate/commands.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -16,9 +16,7 @@ from ZSI.generate import containers, utility from ZSI.generate.utility import NCName_to_ClassName as NC_to_CN, TextProtect from ZSI.generate.wsdl2dispatch import ServiceModuleWriter as ServiceDescription -from ZSI.generate.wsdl2dispatch import DelAuthServiceModuleWriter as DelAuthServiceDescription from ZSI.generate.wsdl2dispatch import WSAServiceModuleWriter as ServiceDescriptionWSA -from ZSI.generate.wsdl2dispatch import DelAuthWSAServiceModuleWriter as DelAuthServiceDescriptionWSA warnings.filterwarnings('ignore', '', exceptions.UserWarning) Modified: trunk/zsi/ZSI/generate/wsdl2dispatch.py =================================================================== --- trunk/zsi/ZSI/generate/wsdl2dispatch.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/generate/wsdl2dispatch.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -4,7 +4,8 @@ from ZSI.wstools import WSDLTools from ZSI.generate.wsdl2python import WriteServiceModule, MessageTypecodeContainer from ZSI.ServiceContainer import ServiceSOAPBinding, SimpleWSResource, WSAResource -from ZSI.generate.utility import TextProtect, GetModuleBaseNameFromWSDL, NCName_to_ClassName, GetPartsSubNames, TextProtectAttributeName +from ZSI.generate.utility import TextProtect, GetModuleBaseNameFromWSDL, \ + NCName_to_ClassName, GetPartsSubNames, TextProtectAttributeName from ZSI.generate import WsdlGeneratorError, Wsdl2PythonError from ZSI.generate.wsdl2python import SchemaDescription @@ -14,6 +15,7 @@ if sys.version_info[0:2] == (2, 4, 0, 'final', 0)[0:2]: rsplit = lambda x,sep,: x.rsplit(sep, 1) + class SOAPService: def __init__(self, service): self.classdef = StringIO() @@ -27,6 +29,7 @@ self.methods.append(StringIO()) return self.methods[-1] + class ServiceModuleWriter: '''Creates a skeleton for a SOAP service instance. ''' @@ -34,12 +37,14 @@ server_module_suffix = '_server' func_aname = TextProtectAttributeName func_aname = staticmethod(func_aname) - separate_messages = False # Whether to write message definitions into a separate file. + separate_messages = False - def __init__(self, base=ServiceSOAPBinding, prefix='soap', service_class=SOAPService, do_extended=False): + def __init__(self, base=ServiceSOAPBinding, prefix='soap', + service_class=SOAPService): ''' parameters: - base -- either a class definition, or a str representing a qualified class name. + base -- either a class definition, or a str representing a qualified + class name. prefix -- method prefix. ''' self.wsdl = None @@ -53,16 +58,12 @@ self.client_module_path = None self.client_module_name = None self.messages_module_name = None - self.do_extended = do_extended - def reset(self): - self.header = StringIO() - self.imports = StringIO() - self._services = {} - def _getBaseClassName(self): '''return base class name, do not override. ''' + if self.base_class is None: + return if type(self.base_class) is types.ClassType: return self.base_class.__name__ return rsplit(self.base_class, '.')[-1] @@ -70,12 +71,19 @@ def _getBaseClassModule(self): '''return base class module, do not override. ''' + if self.base_class is None: + return if type(self.base_class) is types.ClassType: return self.base_class.__module__ if self.base_class.find('.') >= 0: return rsplit(self.base_class, '.')[0] - return None + return + def reset(self): + self.header = StringIO() + self.imports = StringIO() + self._services = {} + def getIndent(self, level=1): '''return indent. ''' @@ -102,7 +110,7 @@ if self.client_module_name is not None: return self.client_module_name - wsm = WriteServiceModule(self.wsdl, do_extended=self.do_extended) + wsm = WriteServiceModule(self.wsdl) return wsm.getClientModuleName() def getMessagesModuleName(self): @@ -112,7 +120,7 @@ if self.messages_module_name is not None: return self.messages_module_name - wsm = WriteServiceModule(self.wsdl, do_extended=self.do_extended) + wsm = WriteServiceModule(self.wsdl) return wsm.getMessagesModuleName() def getServiceModuleName(self): @@ -142,11 +150,15 @@ 'expecting WSDLTools.Service instance.' s = self._services[service.name].classdef - print >>s, 'class %s(%s):' %(self.getClassName(service.name), self._getBaseClassName()) + base = self._getBaseClassName() + if base is None: + print >>s, 'class %s:' %(self.getClassName(service.name)) + else: + print >>s, 'class %s(%s):' %(self.getClassName(service.name), base) + print >>s, '%ssoapAction = {}' % self.getIndent(level=1) print >>s, '%sroot = {}' % self.getIndent(level=1) - print >>s, "%s_wsdl = \"\"\"%s\"\"\"" % (self.getIndent(level=1), self.raw_wsdl) - + def setUpImports(self): '''set import statements ''' @@ -165,7 +177,9 @@ mod = self._getBaseClassModule() name = self._getBaseClassName() - if mod is None: + if mod is None and name is None: + pass + elif mod is None: print >>i, 'import %s' %name else: print >>i, 'from %s import %s' %(mod, name) @@ -173,7 +187,9 @@ def setUpInitDef(self, service): '''set __init__ function ''' - assert isinstance(service, WSDLTools.Service), 'expecting WSDLTools.Service instance.' + assert isinstance(service, WSDLTools.Service), \ + 'expecting WSDLTools.Service instance.' + sd = self._services[service.name] d = sd.initdef @@ -183,9 +199,10 @@ else: print >>d, '%sdef __init__(self, post, **kw):' %self.getIndent(level=1) - print >>d, '%s%s.__init__(self, post)' %(self.getIndent(level=2),self._getBaseClassName()) + base = self._getBaseClassName() + if base is not None: + print >>d, '%s%s.__init__(self, post)' %(self.getIndent(level=2), base) - def mangle(self, name): return TextProtect(name) @@ -230,81 +247,17 @@ m = sd.newMethod() print >>m, '%sdef %s(self, ps):' %(self.getIndent(level=1), method_name) if msgin is not None: - print >>m, '%sself.request = ps.Parse(%s.typecode)' %(self.getIndent(level=2), msgin_name) + print >>m, '%srequest = ps.Parse(%s.typecode)' %(self.getIndent(level=2), msgin_name) else: print >>m, '%s# NO input' %self.getIndent(level=2) msgout = op.getOutputMessage() - - if self.do_extended: - input_args = msgin.parts.values() - iargs = ["%s" % x.name for x in input_args] - if msgout is not None: - output_args = msgout.parts.values() - else: - output_args = [] - oargs = ["%s" % x.name for x in output_args] - if output_args: - if len(output_args) > 1: - print "Message has more than one return value (Bad Design)." - output_args = "(%s)" % output_args - else: - output_args = "" - # Get arg list - iSubNames = GetPartsSubNames(msgin.parts.values(), self.wsdl) - for i in range( len(iargs) ): # should only be one part to messages here anyway - argSubNames = iSubNames[i] - if len(argSubNames) > 0: - subNamesStr = "self.request." + ", self.request.".join(map(self.getAttributeName, argSubNames)) - if len(argSubNames) > 1: - subNamesStr = "(" + subNamesStr + ")" - print >>m, "%s%s = %s" % (self.getIndent(level=2), iargs[i], subNamesStr) - - print >>m, "\n%s# If we have an implementation object use it" % (self.getIndent(level=2)) - print >>m, "%sif hasattr(self,'impl'):" % (self.getIndent(level=2)) - - iargsStrList = [] - for arg in iargs: - argSubNames = iSubNames[i] - if len(argSubNames) > 0: - if len(argSubNames) > 1: - for i in range(len(argSubNames)): - iargsStrList.append( arg + "[%i]" % i ) - else: - iargsStrList.append( arg ) - iargsStr = ",".join(iargsStrList) - oargsStr = ", ".join(oargs) - if len(oargsStr) > 0: - oargsStr += " = " - print >>m, "%s%sself.impl.%s(%s)" % (self.getIndent(level=3), oargsStr, op.name, iargsStr) - if msgout is not None: msgout_name = TextProtect(msgout.name) - if self.do_extended: - print >>m, '\n%sresult = %s()' %(self.getIndent(level=2), msgout_name) - oSubNames = GetPartsSubNames(msgout.parts.values(), self.wsdl) - if (len(oSubNames) > 0) and (len(oSubNames[0]) > 0): - print >>m, "%s# If we have an implementation object, copy the result " % (self.getIndent(level=2)) - print >>m, "%sif hasattr(self,'impl'):" % (self.getIndent(level=2)) - # copy result's members - for i in range( len(oargs) ): # should only be one part messages here anyway - oargSubNames = oSubNames[i] - if len(oargSubNames) > 1: - print >>m, '%s# Should have a tuple of %i args' %(self.getIndent(level=3), len(oargSubNames)) - for j in range(len(oargSubNames)): - oargSubName = oargSubNames[j] - print >>m, '%sresult.%s = %s[%i]' %(self.getIndent(level=3), self.getAttributeName(oargSubName), oargs[i], j) - elif len(oargSubNames) == 1: - oargSubName = oargSubNames[0] - print >>m, '%sresult.%s = %s' %(self.getIndent(level=3), self.getAttributeName(oargSubName), oargs[i]) - else: - raise Exception("The subnames within message " + msgout_name + "'s part were not found. Message is the output of operation " + op.name) - print >>m, '%sreturn result' %(self.getIndent(level=2)) - else: - print >>m, '%sreturn %s()' %(self.getIndent(level=2), msgout_name) + print >>m, '%sreturn request,%s()' %(self.getIndent(level=2), msgout_name) else: print >>m, '%s# NO output' % self.getIndent(level=2) - print >>m, '%sreturn None' % self.getIndent(level=2) + print >>m, '%sreturn request,None' % self.getIndent(level=2) print >>m, '' print >>m, '%ssoapAction[\'%s\'] = \'%s\'' %(self.getIndent(level=1), action_in, method_name) @@ -343,7 +296,6 @@ self.reset() self.wsdl = wsdl - self.raw_wsdl = wsdl.document.toxml().replace("\"", "\\\"") self.setUpHeader() self.setUpImports() for service in wsdl.services: @@ -364,7 +316,8 @@ class WSAServiceModuleWriter(ServiceModuleWriter): '''Creates a skeleton for a WS-Address service instance. ''' - def __init__(self, base=WSAResource, prefix='wsa', service_class=SOAPService, strict=True): + def __init__(self, base=WSAResource, prefix='wsa', service_class=SOAPService, + strict=True): ''' Parameters: strict -- check that soapAction and input ws-action do not collide. @@ -379,12 +332,12 @@ ''' body = [] if msgInName is not None: - body.append('self.request = ps.Parse(%s.typecode)' %msgInName) + body.append('request = ps.Parse(%s.typecode)' %msgInName) if msgOutName is not None: - body.append('return %s()' %msgOutName) + body.append('return request,%s()' %msgOutName) else: - body.append('return None') + body.append('return request,None') return tuple(body) createMethodBody = staticmethod(createMethodBody) @@ -465,68 +418,3 @@ print >>m, '%sroot[(%s.typecode.nspname,%s.typecode.pname)] = \'%s\'' \ %(self.getIndent(level=1), msgin_name, msgin_name, method_name) - -class DelAuthServiceModuleWriter(ServiceModuleWriter): - ''' Includes the generation of lines to call an authorization method on the server side - if an authorization function has been defined. - ''' - def __init__(self, base=ServiceSOAPBinding, prefix='soap', service_class=SOAPService, do_extended=False): - ServiceModuleWriter.__init__(self, base=base, prefix=prefix, service_class=service_class, do_extended=do_extended) - - def fromWSDL(self, wsdl): - ServiceModuleWriter.fromWSDL(self, wsdl) - for service in wsdl.services: - self.setUpAuthDef(service) - - def setUpInitDef(self, service): - ServiceModuleWriter.setUpInitDef(self, service) - sd = self._services[service.name] - d = sd.initdef - print >>d, '%sif kw.has_key(\'impl\'):' % self.getIndent(level=2) - print >>d, '%sself.impl = kw[\'impl\']' % self.getIndent(level=3) - - print >>d, '%sself.auth_method_name = None' % self.getIndent(level=2) - print >>d, '%sif kw.has_key(\'auth_method_name\'):' % self.getIndent(level=2) - print >>d, '%sself.auth_method_name = kw[\'auth_method_name\']' % self.getIndent(level=3) - - def setUpAuthDef(self, service): - '''set __auth__ function - ''' - sd = self._services[service.name] - e = sd.initdef - print >>e, "%sdef authorize(self, auth_info, post, action):" % self.getIndent(level=1) - print >>e, "%sif self.auth_method_name and hasattr(self.impl, self.auth_method_name):" % self.getIndent(level=2) - print >>e, "%sreturn getattr(self.impl, self.auth_method_name)(auth_info, post, action)" % self.getIndent(level=3) - print >>e, "%selse:" % self.getIndent(level=2) - print >>e, "%sreturn 1" % self.getIndent(level=3) - -class DelAuthWSAServiceModuleWriter(WSAServiceModuleWriter): - def __init__(self, base=SimpleWSResource, prefix='wsa', service_class=SOAPService, strict=True): - WSAServiceModuleWriter.__init__(self, base=base, prefix=prefix, service_class=service_class, strict=strict) - - def fromWSDL(self, wsdl): - WSAServiceModuleWriter.fromWSDL(self, wsdl) - for service in wsdl.services: - self.setUpAuthDef(service) - - def setUpInitDef(self, service): - WSAServiceModuleWriter.setUpInitDef(self, service) - sd = self._services[service.name] - d = sd.initdef - print >>d, '%sif kw.has_key(\'impl\'):' % self.getIndent(level=2) - print >>d, '%sself.impl = kw[\'impl\']' % self.getIndent(level=3) - - print >>d, '%sif kw.has_key(\'auth_method_name\'):' % self.getIndent(level=2) - print >>d, '%sself.auth_method_name = kw[\'auth_method_name\']' % self.getIndent(level=3) - - def setUpAuthDef(self, service): - '''set __auth__ function - ''' - sd = self._services[service.name] - e = sd.initdef - print >>e, "%sdef authorize(self, auth_info, post, action):" % self.getIndent(level=1) - print >>e, "%sif self.auth_method_name and hasattr(self.impl, self.auth_method_name):" % self.getIndent(level=2) - print >>e, "%sreturn getattr(self.impl, self.auth_method_name)(auth_info, post, action)" % self.getIndent(level=3) - print >>e, "%selse:" % self.getIndent(level=2) - print >>e, "%sreturn 1" % self.getIndent(level=3) - Modified: trunk/zsi/ZSI/twisted/wsgi.py =================================================================== --- trunk/zsi/ZSI/twisted/wsgi.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/ZSI/twisted/wsgi.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -3,38 +3,44 @@ # See Copyright for copyright notice! # $Id: __init__.py 1132 2006-02-17 01:55:41Z boverhof $ ########################################################################### -import os, sys, warnings +import os, sys, types from StringIO import StringIO # twisted & related imports from zope.interface import classProvides, implements, Interface -from twisted.python import log, failure -#from twisted.web.error import NoResource -#from twisted.web.server import NOT_DONE_YET -#import twisted.web.http -#import twisted.web.resource # ZSI imports -from ZSI import _get_element_nsuri_name, EvaluateException, ParseException -from ZSI import fault, ParsedSoap, SoapWriter +from ZSI import _get_element_nsuri_name, EvaluateException, ParseException,\ + fault, ParsedSoap, SoapWriter +from ZSI.twisted.reverse import DataHandler, ReverseHandlerChain,\ + HandlerChainInterface -# WS-Address related imports -from ZSI.address import Address +def soapmethod(requesttypecode, responsetypecode, soapaction='', + operation=None, **kw): + """@soapmethod + decorator function for soap methods + """ + def _closure(func_cb): + func_cb.root = (requesttypecode.nspname,requesttypecode.pname) + func_cb.action = soapaction + func_cb.requesttypecode = requesttypecode + func_cb.responsetypecode = responsetypecode + func_cb.soapmethod = True + func_cb.operation = None + return func_cb + return _closure -class WSAddressException(Exception): + +class SOAPCallbackHandler: + """ ps --> pyobj, pyobj --> sw + class variables: + writerClass -- ElementProxy implementation to use for SoapWriter instances. """ - """ + classProvides(HandlerChainInterface) + writerClass = None -from ZSI.twisted.interfaces import HandlerChainInterface, CallbackChainInterface,\ - DataHandler, CheckInputArgs, DefaultHandlerChain - - - -class DefaultCallbackHandler: - classProvides(CallbackChainInterface) - @classmethod def processRequest(cls, ps, **kw): """invokes callback that should return a (request,response) tuple. @@ -42,35 +48,47 @@ ps -- ParsedSoap instance representing HTTP Body. request -- twisted.web.server.Request """ - #env = kw['env'] - #start_response = kw['start_response'] resource = kw['resource'] - #request = kw['request'] - method = getattr(resource, 'soap_%s' % - _get_element_nsuri_name(ps.body_root)[-1]) - + request = kw['request'] + + root = _get_element_nsuri_name(ps.body_root) + for key,method in resource.__dict__: + if (callable(method) and + getattr(method, 'soapmethod', False) and + method.root == root): + break + else: + raise RuntimeError, 'Missing soap callback method for root "%s"' %root + try: - req_pyobj,rsp_pyobj = method(ps) - except TypeError, ex: - log.err( - 'ERROR: service %s is broken, method MUST return request, response'\ - % cls.__name__ - ) + req = ps.Parse(method.requesttypecode) + except Exception, ex: raise + try: + rsp = method.responsetypecode.pyclass() except Exception, ex: - log.err('failure when calling bound method') raise - return rsp_pyobj + try: + req,rsp = method(req, rsp) + except Exception, ex: + raise + + return rsp + + @classmethod + def processResponse(cls, output, **kw): + sw = SoapWriter(outputclass=cls.writerClass) + sw.serialize(output) + return sw -class DefaultHandlerChainFactory: - protocol = DefaultHandlerChain - +class SOAPHandlerChainFactory: + protocol = ReverseHandlerChain + @classmethod def newInstance(cls): - return cls.protocol(DefaultCallbackHandler, DataHandler) - + return cls.protocol(DataHandler, SOAPCallbackHandler) class WSGIApplication(dict): @@ -104,8 +122,6 @@ """ """ factory = DefaultHandlerChainFactory - soapAction = {} - root = {} def __init__(self, **kw): dict.__init__(self, **kw) @@ -130,7 +146,8 @@ def _handle_GET(self, env, start_response): if env['QUERY_STRING'].lower() == 'wsdl': start_response("200 OK", [('Content-Type','text/plain')]) - return ['NO WSDL YET'] + r = self.delegate or self + return _resourceToWSDL(r) start_response("404 ERROR", [('Content-Type','text/plain')]) return ['NO RESOURCE FOR GET'] @@ -168,7 +185,6 @@ def test(app, port=8080, host="localhost"): """ """ - import sys from twisted.internet import reactor from twisted.python import log from twisted.web2.channel import HTTPFactory @@ -183,4 +199,77 @@ reactor.run() +def _issoapmethod(f): + return type(f) is types.MethodType and getattr(f, 'soapmethod', False) +def _resourceToWSDL(resource): + from xml.etree import ElementTree + from xml.etree.ElementTree import Element, QName + from ZSI.wstools.Namespaces import WSDL + + r = resource + methods = filter(_issoapmethod, map(lambda i: getattr(r, i), dir(r))) + tns = '' + + #tree = ElementTree() + defs = Element("{%s}definitions" %WSDL.BASE) + defs.attrib['name'] = 'SampleDefs' + defs.attrib['targetNamespace'] = tns + #tree.append(defs) + + porttype = Element("{%s}portType" %WSDL) + porttype.attrib['name'] = QName("{%s}SamplePortType" %tns) + + binding = Element("{%s}binding" %WSDL) + defs.append(binding) + binding.attrib['name'] = QName("{%s}SampleBinding" %tns) + binding.attrib['type'] = porttype.get('name') + + for m in methods: + m.action + + service = Element("{%s}service" %WSDL.BASE) + defs.append(service) + service.attrib['name'] = 'SampleService' + + port = Element("{%s}port" %WSDL.BASE) + service.append(port) + port.attrib['name'] = "SamplePort" + port.attrib['binding'] = binding.get('name') + + soapaddress = Element("{%s}address" %WSDL.BIND_SOAP) + soapaddress.attrib['location'] = 'http://localhost/bla' + port.append(soapaddress) + + return [ElementTree.tostring(defs)] + + + +""" +<?xml version="1.0" encoding="UTF-8"?> +<wsdl:definitions name="Counter" targetNamespace="http://counter.com/bindings" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:porttype="http://counter.com" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> + <wsdl:import namespace="http://counter.com" location="counter_flattened.wsdl"/> + <wsdl:binding name="CounterPortTypeSOAPBinding" type="porttype:CounterPortType"> + <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> + <wsdl:operation name="createCounter"> + <soap:operation soapAction="http://counter.com/CounterPortType/createCounterRequest"/> + <wsdl:input> + <soap:body use="literal"/> + </wsdl:input> + <wsdl:output> + <soap:body use="literal"/> + </wsdl:output> + </wsdl:operation> + + +<wsdl:definitions name="Counter" targetNamespace="http://counter.com/service" +xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:binding="http://counter.com/bindings"> + <wsdl:import namespace="http://counter.com/bindings" location="counter_bindings.wsdl"/> + <wsdl:service name="CounterService"> + <wsdl:port name="CounterPortTypePort" binding="binding:CounterPortTypeSOAPBinding"> + <soap:address location="http://localhost:8080/wsrf/services/"/> + </wsdl:port> + </wsdl:service> +</wsdl:definitions> +""" + Modified: trunk/zsi/test/test_t8.py =================================================================== --- trunk/zsi/test/test_t8.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/test_t8.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -73,7 +73,7 @@ self.assertEqual(type(myInt), type(parsed[0])) self.assertEqual(type(myLong), type(parsed[1])) - self.assertEqual(type(myStr), type(parsed[2])) + self.assertEqual(str, type(parsed[2])) self.assertEqual(tuple, type(parsed[3])) self.assertEqual(type(myFloat), type(parsed[4])) Modified: trunk/zsi/test/wsdl2py/servers/BasicServer.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/BasicServer.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/wsdl2py/servers/BasicServer.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -14,17 +14,17 @@ class Service(BasicServer): def soap_Basic(self, ps): - response = BasicServer.soap_Basic(self, ps) - response._BasicResult = self.request._BasicIn - return response + request,response = BasicServer.soap_Basic(self, ps) + response._BasicResult = request._BasicIn + return request,response def soap_BasicOneWay(self, ps): - response = BasicServer.soap_BasicOneWay(self, ps) - if self.request._BasicIn == 'fault': + request,response = BasicServer.soap_BasicOneWay(self, ps) + if request._BasicIn == 'fault': # return a soap:fault raise RuntimeError, 'you wanted a fault?' - return response + return request,response if __name__ == "__main__" : Modified: trunk/zsi/test/wsdl2py/servers/DateService.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/DateService.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/wsdl2py/servers/DateService.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -9,18 +9,18 @@ class Service(_DateService): def soap_getCurrentDate(self, ps): - response = _DateService.soap_getCurrentDate(self, ps) + request,response = _DateService.soap_getCurrentDate(self, ps) response.Today = today = response.new_today() - self.request._input + request._input _SetCurrentDate(today) - return response + return request,response def soap_getDate(self, ps): - response = _DateService.soap_getDate(self, ps) + request,response = _DateService.soap_getDate(self, ps) response.Day = day = response.new_day() - _SetDay(day, offset=self.request.Offset, - date=self.request.Someday) - return response + _SetDay(day, offset=request.Offset, + date=request.Someday) + return request,response ## ADDED WORKER CODE Modified: trunk/zsi/test/wsdl2py/servers/EchoServer.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/EchoServer.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/wsdl2py/servers/EchoServer.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -17,9 +17,9 @@ class Service(EchoServer): def soap_Echo(self, ps): - response = EchoServer.soap_Echo(self, ps) - response.EchoResult = self.request.EchoIn - return response + request,response = EchoServer.soap_Echo(self, ps) + response.EchoResult = request.EchoIn + return request,response if __name__ == "__main__" : Modified: trunk/zsi/test/wsdl2py/servers/EchoWSAddr200403Server.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/EchoWSAddr200403Server.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/wsdl2py/servers/EchoWSAddr200403Server.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -20,8 +20,8 @@ class WSAService(EchoServer): def wsa_Echo(self, ps, addr): - response = EchoServer.wsa_Echo(self, ps, addr) - response.EchoResult = self.request.EchoIn + request,response = EchoServer.wsa_Echo(self, ps, addr) + response.EchoResult = request.EchoIn if isinstance(response.EchoResult, EndpointReferenceType): addr1 = response.EchoResult @@ -29,7 +29,7 @@ if a not in addr1.ReferenceProperties.Any: raise RuntimeError, 'EPRs dont match' - return response + return request,response if __name__ == "__main__" : Modified: trunk/zsi/test/wsdl2py/servers/FinancialService.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/FinancialService.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/wsdl2py/servers/FinancialService.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -10,8 +10,8 @@ class Service(FinancialService): def soap_getPV(self, ps): - reponse = FinancialService.soap_getPV(self, ps) - args = self.request + request,response = FinancialService.soap_getPV(self, ps) + args = request # Worker code: Actual present value calculation t = 0 @@ -27,8 +27,8 @@ # WARNING specify value eg. SimpleTypeWrapper(1) #response = SimpleTypeWrapper(PV) - response = reponse.__class__(PV) - return response + response = response.__class__(PV) + return request,response Modified: trunk/zsi/test/wsdl2py/servers/SquareService.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/SquareService.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/wsdl2py/servers/SquareService.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -10,9 +10,9 @@ class Service(Square.SquareService): def soap_getSquare(self, ps): - response = Square.SquareService.soap_getSquare(self, ps) - response._return = self.getSquare(self.request._x) - return response + request,response = Square.SquareService.soap_getSquare(self, ps) + response._return = self.getSquare(request._x) + return request,response def getSquare(self, x): return x**2 Modified: trunk/zsi/test/wsdl2py/servers/WhiteMesa.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/WhiteMesa.py 2007-06-19 15:59:55 UTC (rev 1399) +++ trunk/zsi/test/wsdl2py/servers/WhiteMesa.py 2007-06-29 22:50:57 UTC (rev 1400) @@ -15,36 +15,36 @@ class Service(WhiteMesa): def soap_echoStruct(self, ps): - response = WhiteMesa.soap_echoStruct(self, ps) - return response + request,response = WhiteMesa.soap_echoStruct(self, ps) + return request,response def soap_echoStructArray(self, ps): - response = WhiteMesa.soap_echoStructArray(self, ps) - return response + request,response = WhiteMesa.soap_echoStructArray(self, ps) + return request,response def soap_echoStructAsSimpleTypes(self, ps): - response = WhiteMesa.soap_echoStructAsSimpleTypes(self, ps) - return response + request,response = WhiteMesa.soap_echoStructAsSimpleTypes(self, ps) + return request,response def soap_echoSimpleTypesAsStruct(self, ps): - response = WhiteMesa.soap_echoSimpleTypesAsStruct(self, ps) - return response + request,response = WhiteMesa.soap_echoSimpleTypesAsStruct(self, ps) + return request,response def soap_echoNestedStruct(self, ps): - response = WhiteMesa.soap_echoNestedStruct(self, ps) - return response + request,response = WhiteMesa.soap_echoNestedStruct(self, ps) + return request,response def soap_echoNestedArray(self, ps): - response = WhiteMesa.soap_echoNestedArray(self, ps) - return response + request,response = WhiteMesa.soap_echoNestedArray(self, ps) + return request,response def soap_echoStringArray(self, ps): - response = WhiteMesa.soap_echoStringArray(self, ps) - return response + request,response = WhiteMesa.soap_echoStringArray(self, ps) + return request,response def soap_echoIntegerArray(self, ps): - response = WhiteMesa.soap_echoIntegerArray(self, ps) - return response + request,response = WhiteMesa.soap_echoIntegerArray(self, ps) + return request,response def soap_echoBoolean(self, ps): - response = WhiteMesa.soap_echoBoolean(self, ps) - response._return = self.request._inputBoolean - return response + request,response = WhiteMesa.soap_echoBoolean(self, ps) + response._return = request._inputBoolean + return request,response def soap_echoString(self, ps): - response = WhiteMesa.soap_echoString(self, ps) - return response + request,response = WhiteMesa.soap_echoString(self, ps) + return request,response if __name__ == "__main__" : port = int(sys.argv[1]) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2007-07-06 18:35:44
|
Revision: 1401 http://svn.sourceforge.net/pywebsvcs/?rev=1401&view=rev Author: boverhof Date: 2007-07-06 11:35:46 -0700 (Fri, 06 Jul 2007) Log Message: ----------- M RELEASE -- python is now in svn not cvs M ZSI/twisted/wsgi.py -- couple main functions for testing M ZSI/TC.py FIX [ 1749290 ] TC.QName default namespace error Modified Paths: -------------- trunk/zsi/RELEASE trunk/zsi/ZSI/TC.py trunk/zsi/ZSI/twisted/wsgi.py Modified: trunk/zsi/RELEASE =================================================================== --- trunk/zsi/RELEASE 2007-06-29 22:50:57 UTC (rev 1400) +++ trunk/zsi/RELEASE 2007-07-06 18:35:46 UTC (rev 1401) @@ -123,12 +123,11 @@ - Get the LaTeX version of the documentation package and unpack it. Create the symlink to .../Python-Doc-VERSION/tools/mkhowto. -- Get them from CVS. If you have an existing Python checkout, you can +- Get them from SVN. If you have an existing Python checkout, you can symlink to the .../Doc/tools/mkhowto script in that. If not, then you only need to check out the Doc/ tree:: - cvs -d :pserver:ano...@cv...:/cvsroot/python \ - checkout -d someplace python/dist/src/Doc + svn co http://svn.python.org/projects/python/trunk/Doc python-Do The symlink can then be made to .../someplace/tools/mkhowto. Modified: trunk/zsi/ZSI/TC.py =================================================================== --- trunk/zsi/ZSI/TC.py 2007-06-29 22:50:57 UTC (rev 1400) +++ trunk/zsi/ZSI/TC.py 2007-07-06 18:35:46 UTC (rev 1401) @@ -782,6 +782,7 @@ ''' prefix,localName = SplitQName(text) nsdict = ps.GetElementNSdict(elt) + prefix = prefix or '' try: namespaceURI = nsdict[prefix] except KeyError, ex: Modified: trunk/zsi/ZSI/twisted/wsgi.py =================================================================== --- trunk/zsi/ZSI/twisted/wsgi.py 2007-06-29 22:50:57 UTC (rev 1400) +++ trunk/zsi/ZSI/twisted/wsgi.py 2007-07-06 18:35:46 UTC (rev 1401) @@ -15,7 +15,46 @@ from ZSI.twisted.reverse import DataHandler, ReverseHandlerChain,\ HandlerChainInterface +""" +WSGI Module +unstable + +EXAMPLE APPLICATION: +# +from EchoServer_client import * +from ZSI.twisted.wsgi import SOAPApplication, soapmethod, SOAPHandlerChainFactory + +class EchoService(SOAPApplication): + factory = SOAPHandlerChainFactory + wsdl_content = dict(name='', targetNamespace='', imports=(), portType='') + + @soapmethod(EchoRequest.typecode, EchoResponse.typecode, operation='Echo', soapaction='Echo') + def soap_Echo(self, request, response, **kw): + response.EchoResult = request.EchoIn + return request,response + + +def main(): + from wsgiref.simple_server import make_server, demo_app + application = WSGIApplication() + httpd = make_server('', 8000, application) + application['echo'] = EchoService() + httpd.serve_forever() + +def main_twisted(): + from ZSI.twisted.wsgi import test, WSGIApplication + app = WSGIApplication() + app['echo'] = EchoService() + test(app) + +if __name__ == '__main__': + main_twisted() + +""" + + + def soapmethod(requesttypecode, responsetypecode, soapaction='', operation=None, **kw): """@soapmethod @@ -116,6 +155,29 @@ """ start_response("404 ERROR", [('Content-Type','text/plain')]) return ['Move along people, there is nothing to see to hear'] + + def putChild(self, path, resource): + """ + """ + path = path.split('/') + lp = len(path) + if lp == 0: + raise RuntimeError, 'bad path "%s"' %path + + if lp == 1: + self[path[0]] = resource + + for i in range(len(path)): + if not path[i]: continue + break + + next = self.get(path[i], None) + if next is None: + next = self[path[i]] = WSGIApplication() + + next.putChild('/'.join(path[-1:]), resource) + + class SOAPApplication(WSGIApplication): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2007-07-06 22:51:32
|
Revision: 1402 http://svn.sourceforge.net/pywebsvcs/?rev=1402&view=rev Author: boverhof Date: 2007-07-06 15:51:32 -0700 (Fri, 06 Jul 2007) Log Message: ----------- A test/test_QName.py M test/test_zsi.py M test/test_zsi_net.py -- added QName test for undeclared default namespace M test/wsdl2py/test_AWSECommerceService.py -- update amazon test to 6/13 version M ZSI/generate/wsdl2dispatch.py M ZSI/generate/wsdl2python.py M ZSI/generate/commands.py M ZSI/generate/containers.py -- server skeleton generated with all "messages" so it only needs to import the types -- FIX [ 1731012 ] wsdl2py should include command-line options Modified Paths: -------------- trunk/zsi/ZSI/generate/commands.py trunk/zsi/ZSI/generate/containers.py trunk/zsi/ZSI/generate/wsdl2dispatch.py trunk/zsi/ZSI/generate/wsdl2python.py trunk/zsi/test/test_zsi.py trunk/zsi/test/test_zsi_net.py trunk/zsi/test/wsdl2py/test_AWSECommerceService.py Added Paths: ----------- trunk/zsi/test/test_QName.py Modified: trunk/zsi/ZSI/generate/commands.py =================================================================== --- trunk/zsi/ZSI/generate/commands.py 2007-07-06 18:35:46 UTC (rev 1401) +++ trunk/zsi/ZSI/generate/commands.py 2007-07-06 22:51:32 UTC (rev 1402) @@ -219,22 +219,13 @@ client_file = join(options.output_dir, '%s.py' %client_mod) append(client_file) fd = open(client_file, 'w+') - - # simple naming writes the messages to a separate file - if not options.simple_naming: - wsm.writeClient(fd) - else: # provide a separate file to store messages to. - msg_fd = open(join(options.output_dir, - '%s.py' %(wsm.getMessagesModuleName()), 'w+' )) - wsm.writeClient(fd, msg_fd=msg_fd) - msg_fd.close() - + wsm.writeClient(fd) fd.close() types_mod = wsm.getTypesModuleName() types_file = join(options.output_dir, '%s.py' %types_mod) append(types_file) - fd = open( join(options.output_dir, '%s.py' %types_mod), 'w+' ) + fd = open(types_file, 'w+' ) wsm.writeTypes(fd) fd.close() @@ -242,12 +233,12 @@ def _wsdl2dispatch(options, wsdl): - if options.simple_naming: - ServiceDescription.server_module_suffix = '_interface' - ServiceDescription.func_aname = lambda instnc,n: TextProtect(n) - ServiceDescription.separate_messages = True - # use module names rather than their number. - utility.namespace_name = lambda cls, ns: utility.Namespace2ModuleName(ns) +# if options.simple_naming: +# ServiceDescription.server_module_suffix = '_interface' +# ServiceDescription.func_aname = lambda instnc,n: TextProtect(n) +# ServiceDescription.separate_messages = True +# # use module names rather than their number. +# utility.namespace_name = lambda cls, ns: utility.Namespace2ModuleName(ns) if options.address is True: ss = ServiceDescriptionWSA() Modified: trunk/zsi/ZSI/generate/containers.py =================================================================== --- trunk/zsi/ZSI/generate/containers.py 2007-07-06 18:35:46 UTC (rev 1401) +++ trunk/zsi/ZSI/generate/containers.py 2007-07-06 22:51:32 UTC (rev 1402) @@ -306,6 +306,7 @@ imports = ['\nimport urlparse, types', 'from ZSI.TCcompound import ComplexType, Struct', 'from ZSI import client', + 'from ZSI.schema import GED, GTD', 'import ZSI' ] logger = _GetLogger("ServiceHeaderContainer") @@ -913,13 +914,16 @@ kw = KW.copy() - kw['message'],kw['prefix'],kw['typecode'] = \ - self.content.mName, self.getNSAlias(), element_class_name(self.content.pName) + kw.update(dict(message=self.content.mName, nsuri=self.content.ns, + name=self.content.pName)) +# kw['message'],kw['prefix'],kw['typecode'] = \ +# self.content.mName, self.getNSAlias(), element_class_name(self.content.pName) +# # These messsages are just global element declarations - self.writeArray(['%(message)s = %(prefix)s.%(typecode)s().pyclass' %kw]) +# self.writeArray(['%(message)s = %(prefix)s.%(typecode)s().pyclass' %kw]) + self.writeArray(['%(message)s = GED("%(nsuri)s", "%(name)s").pyclass' %kw]) - class ServiceRPCEncodedMessageContainer(ServiceContainerBase, MessageContainerInterface): logger = _GetLogger("ServiceRPCEncodedMessageContainer") Modified: trunk/zsi/ZSI/generate/wsdl2dispatch.py =================================================================== --- trunk/zsi/ZSI/generate/wsdl2dispatch.py 2007-07-06 18:35:46 UTC (rev 1401) +++ trunk/zsi/ZSI/generate/wsdl2dispatch.py 2007-07-06 22:51:32 UTC (rev 1402) @@ -2,14 +2,15 @@ from cStringIO import StringIO import ZSI, string, sys, getopt, urlparse, types, warnings from ZSI.wstools import WSDLTools -from ZSI.generate.wsdl2python import WriteServiceModule, MessageTypecodeContainer from ZSI.ServiceContainer import ServiceSOAPBinding, SimpleWSResource, WSAResource -from ZSI.generate.utility import TextProtect, GetModuleBaseNameFromWSDL, \ + +from ZSI.generate import WsdlGeneratorError, Wsdl2PythonError +from utility import TextProtect, GetModuleBaseNameFromWSDL, \ NCName_to_ClassName, GetPartsSubNames, TextProtectAttributeName -from ZSI.generate import WsdlGeneratorError, Wsdl2PythonError -from ZSI.generate.wsdl2python import SchemaDescription +from containers import BindingDescription +from wsdl2python import MessageWriter, WriteServiceModule,\ + MessageTypecodeContainer, SchemaDescription - # Split last token rsplit = lambda x,sep,: (x[:x.rfind(sep)], x[x.rfind(sep)+1:],) if sys.version_info[0:2] == (2, 4, 0, 'final', 0)[0:2]: @@ -54,9 +55,10 @@ self.header = None self.imports = None + self.messages = [] self._services = None - self.client_module_path = None - self.client_module_name = None + self.types_module_path = None + self.types_module_name = None self.messages_module_name = None def _getBaseClassName(self): @@ -82,6 +84,7 @@ def reset(self): self.header = StringIO() self.imports = StringIO() + self.message = [] self._services = {} def getIndent(self, level=1): @@ -100,28 +103,31 @@ ''' return NCName_to_ClassName(name) - def setClientModuleName(self, name): - self.client_module_name = name + def setTypesModuleName(self, name): + self.types_module_name = name - def getClientModuleName(self): + # Backwards compatibility + setClientModuleName = setTypesModuleName + + def getTypesModuleName(self): '''return module name. ''' assert self.wsdl is not None, 'initialize, call fromWSDL' - if self.client_module_name is not None: - return self.client_module_name + if self.types_module_name is not None: + return self.types_module_name wsm = WriteServiceModule(self.wsdl) - return wsm.getClientModuleName() + return wsm.getTypesModuleName() - def getMessagesModuleName(self): - '''return module name. - ''' - assert self.wsdl is not None, 'initialize, call fromWSDL' - if self.messages_module_name is not None: - return self.messages_module_name - - wsm = WriteServiceModule(self.wsdl) - return wsm.getMessagesModuleName() +# def getMessagesModuleName(self): +# '''return module name. +# ''' +# assert self.wsdl is not None, 'initialize, call fromWSDL' +# if self.messages_module_name is not None: +# return self.messages_module_name +# +# wsm = WriteServiceModule(self.wsdl) +# return wsm.getMessagesModuleName() def getServiceModuleName(self): '''return module name. @@ -134,14 +140,16 @@ return name return '%s%s' %(name, self.server_module_suffix) - def getClientModulePath(self): - return self.client_module_path - - def setClientModulePath(self, path): + def getTypesModulePath(self): + return self.types_module_path + getClientModulePath = getTypesModulePath + + def setTypesModulePath(self, path): '''setup module path to where client module before calling fromWSDL. ''' - self.client_module_path = path - + self.types_module_path = path + setClientModulePath = setTypesModulePath + def setUpClassDef(self, service): '''set class definition and class variables. service -- ServiceDescription instance @@ -162,19 +170,27 @@ def setUpImports(self): '''set import statements ''' - path = self.getClientModulePath() i = self.imports - if path is None: - if self.separate_messages: - print >>i, 'from %s import *' %self.getMessagesModuleName() - else: - print >>i, 'from %s import *' %self.getClientModuleName() - else: - if self.separate_messages: - print >>i, 'from %s.%s import *' %(path, self.getMessagesModuleName()) - else: - print >>i, 'from %s.%s import *' %(path, self.getClientModuleName()) + print >>i, 'from ZSI.schema import GED, GTD' + print >>i, 'from ZSI.TCcompound import ComplexType, Struct' +# if path is None: +# if self.separate_messages: +# print >>i, 'from %s import *' %self.getMessagesModuleName() +# else: +# print >>i, 'from %s import *' %self.getClientModuleName() +# else: +# if self.separate_messages: +# print >>i, 'from %s.%s import *' %(path, self.getMessagesModuleName()) +# else: +# print >>i, 'from %s.%s import *' %(path, self.getClientModuleName()) + module = self.getTypesModuleName() + package = self.getTypesModulePath() + if package: + module = '%s.%s' %(package, module) + + print >>i, 'from %s import *' %(module) + mod = self._getBaseClassModule() name = self._getBaseClassName() if mod is None and name is None: @@ -267,11 +283,13 @@ return def setUpHeader(self): - print >>self.header, '##################################################' - print >>self.header, '# %s.py' %self.getServiceModuleName() - print >>self.header, '# Generated by %s' %(self.__class__) + print >>self.header, '#'*50 + print >>self.header, '# file: %s.py' %self.getServiceModuleName() print >>self.header, '#' - print >>self.header, '##################################################' + print >>self.header, '# skeleton generated by "%s"' %self.__class__ + print >>self.header, '# %s' %' '.join(sys.argv) + print >>self.header, '#' + print >>self.header, '#'*50 def write(self, fd=sys.stdout): '''write out to file descriptor, @@ -279,6 +297,14 @@ ''' print >>fd, self.header.getvalue() print >>fd, self.imports.getvalue() + + print >>fd, '# Messages ', + for m in self.messages: + print >>fd, m + + print >>fd, '' + print >>fd, '' + print >>fd, '# Service Skeletons' for k,v in self._services.items(): print >>fd, v.classdef.getvalue() print >>fd, v.initdef.getvalue() @@ -293,16 +319,32 @@ if len(wsdl.services) == 0: raise WsdlGeneratorError, 'No service defined' - + self.reset() self.wsdl = wsdl self.setUpHeader() self.setUpImports() + for service in wsdl.services: sd = self._service_class(service.name) self._services[service.name] = sd for port in service.ports: + desc = BindingDescription(wsdl=wsdl) + try: + desc.setUp(port.getBinding()) + except Wsdl2PythonError, ex: + continue + + for soc in desc.operations: + if not soc.hasInput(): continue + + self.messages.append(MessageWriter()) + self.messages[-1].setUp(soc, port, input=True) + if soc.hasOutput(): + self.messages.append(MessageWriter()) + self.messages[-1].setUp(soc, port, input=False) + for e in port.extensions: if isinstance(e, WSDLTools.SoapAddressBinding): sd.location = e.location @@ -346,10 +388,12 @@ '''use soapAction dict for WS-Action input, setup wsAction dict for grabbing WS-Action output values. ''' - assert isinstance(service, WSDLTools.Service), 'expecting WSDLTools.Service instance' + assert isinstance(service, WSDLTools.Service), \ + 'expecting WSDLTools.Service instance' s = self._services[service.name].classdef - print >>s, 'class %s(%s):' %(self.getClassName(service.name), self._getBaseClassName()) + print >>s, 'class %s(%s):' %(self.getClassName(service.name), + self._getBaseClassName()) print >>s, '%ssoapAction = {}' % self.getIndent(level=1) print >>s, '%swsAction = {}' % self.getIndent(level=1) print >>s, '%sroot = {}' % self.getIndent(level=1) Modified: trunk/zsi/ZSI/generate/wsdl2python.py =================================================================== --- trunk/zsi/ZSI/generate/wsdl2python.py 2007-07-06 18:35:46 UTC (rev 1401) +++ trunk/zsi/ZSI/generate/wsdl2python.py 2007-07-06 22:51:32 UTC (rev 1402) @@ -7,7 +7,7 @@ # $Id$ -import os, warnings +import os, sys, warnings from ZSI import _get_idstr from ZSI.wstools.logging import getLogger as _GetLogger from ZSI.wstools import WSDLTools @@ -83,19 +83,19 @@ return '%s%s' %(name, self.client_module_suffix) - def getMessagesModuleName(self): - name = GetModuleBaseNameFromWSDL(self._wsdl) - if not name: - raise WsdlGeneratorError, 'could not determine a service name' - - if self.messages_module_suffix is None: - return name +# def getMessagesModuleName(self): +# name = GetModuleBaseNameFromWSDL(self._wsdl) +# if not name: +# raise WsdlGeneratorError, 'could not determine a service name' +# +# if self.messages_module_suffix is None: +# return name +# +# if len(self.messages_module_suffix) == 0: +# return self.getClientModuleName() +# +# return '%s%s' %(name, self.messages_module_suffix) - if len(self.messages_module_suffix) == 0: - return self.getClientModuleName() - - return '%s%s' %(name, self.messages_module_suffix) - def setTypesModuleName(self, name): self.types_module_name = name @@ -125,11 +125,11 @@ """ return self.types_module_path - def getMessagesModulePath(self): - '''module path to messages module - same as types path - ''' - return self.messages_module_path +# def getMessagesModulePath(self): +# '''module path to messages module +# same as types path +# ''' +# return self.messages_module_path def setTypesModulePath(self, path): """setup module path to where service module before calling fromWsdl. @@ -137,11 +137,11 @@ """ self.types_module_path = path - def setMessagesModulePath(self, path): - """setup module path to where message module before calling fromWsdl. - module path to types module eg. MyApp.types - """ - self.messages_module_path = path +# def setMessagesModulePath(self, path): +# """setup module path to where message module before calling fromWsdl. +# module path to types module eg. MyApp.types +# """ +# self.messages_module_path = path def gatherNamespaces(self): '''This method must execute once.. Grab all schemas @@ -174,11 +174,10 @@ self.usedNamespaces[k].append(v) NAD.add(k) - def writeClient(self, fd, sdClass=None, msg_fd=None, **kw): + def writeClient(self, fd, sdClass=None, **kw): """write out client module to file descriptor. Parameters and Keywords arguments: fd -- file descriptor - msg_fd -- optional messsages module file descriptor sdClass -- service description class name imports -- list of imports readerclass -- class name of ParsedSoap reader @@ -188,40 +187,47 @@ assert issubclass(sdClass, ServiceDescription), \ 'parameter sdClass must subclass ServiceDescription' - header = '%s \n# %s.py \n# generated by %s\n%s\n\n'\ - %('#'*50, self.getClientModuleName(), self.__module__, '#'*50) - fd.write(header) +# header = '%s \n# %s.py \n# generated by %s\n%s\n'\ +# %('#'*50, self.getClientModuleName(), self.__module__, '#'*50) + print >>fd, '#'*50 + print >>fd, '# file: %s.py' %self.getClientModuleName() + print >>fd, '# ' + print >>fd, '# client stubs generated by "%s"' %self.__class__ + print >>fd, '# %s' %' '.join(sys.argv) + print >>fd, '# ' + print >>fd, '#'*50 - if msg_fd is not None: - # TODO: Why is this not getMessagesModuleName? - msg_filename = str(self.getClientModuleName()).replace("client", "messages") - if self.getMessagesModulePath() is not None: - msg_filename = os.path.join(self.getMessagesModulePath(), msg_filename) - messages_header = header.replace("client", "messages") - msg_fd.write(messages_header) - self.services = [] for service in self._wsdl.services: - sd = sdClass(self._addressing, do_extended=self.do_extended, wsdl=self._wsdl) + sd = sdClass(self._addressing, do_extended=self.do_extended, + wsdl=self._wsdl) if len(self._wsdl.types) > 0: - sd.setTypesModuleName(self.getTypesModuleName(), self.getTypesModulePath()) - sd.setMessagesModuleName(self.getMessagesModuleName(), self.getMessagesModulePath()) + sd.setTypesModuleName(self.getTypesModuleName(), + self.getTypesModulePath()) +# sd.setMessagesModuleName(self.getMessagesModuleName(), +# self.getMessagesModulePath()) self.gatherNamespaces() sd.fromWsdl(service, **kw) - sd.write(fd,msg_fd) + sd.write(fd) self.services.append(sd) def writeTypes(self, fd): """write out types module to file descriptor. """ - header = '%s \n# %s.py \n# generated by %s\n%s\n\n'\ - %('#'*50, self.getTypesModuleName(), self.__module__, '#'*50) - fd.write(header) + print >>fd, '#'*50 + print >>fd, '# file: %s.py' %self.getTypesModuleName() + print >>fd, '#' + print >>fd, '# schema types generated by "%s"' %self.__class__ + print >>fd, '# %s' %' '.join(sys.argv) + print >>fd, '#' + print >>fd, '#'*50 + print >>fd, TypesHeaderContainer() self.gatherNamespaces() for l in self.usedNamespaces.values(): - sd = SchemaDescription(do_extended=self.do_extended, extPyClasses=self.extPyClasses) + sd = SchemaDescription(do_extended=self.do_extended, + extPyClasses=self.extPyClasses) for schema in l: sd.fromSchema(schema) sd.write(fd) @@ -254,20 +260,20 @@ if modulePath is not None: self.typesModuleName = '%s.%s' %(modulePath,name) - def setMessagesModuleName(self, name, modulePath=None): - '''The types module to be imported. - Parameters - name -- name of types module - modulePath -- optional path where module is located. - ''' - self.messagesModuleName = '%s' %name - if modulePath is not None: - self.messagesModuleName = '%s.%s' %(modulePath,name) +# def setMessagesModuleName(self, name, modulePath=None): +# '''The types module to be imported. +# Parameters +# name -- name of types module +# modulePath -- optional path where module is located. +# ''' +# self.messagesModuleName = '%s' %name +# if modulePath is not None: +# self.messagesModuleName = '%s.%s' %(modulePath,name) def fromWsdl(self, service, **kw): self.imports.setTypesModuleName(self.typesModuleName) - if self.separate_messages: - self.messagesImports.setMessagesModuleName(self.messagesModuleName) +# if self.separate_messages: +# self.messagesImports.setMessagesModuleName(self.messagesModuleName) self.imports.appendImport(kw.get('imports', [])) self.locator.setUp(service) @@ -284,7 +290,9 @@ while port.binding in bindings: bindings.remove(port.binding) - desc = BindingDescription(useWSA=self.wsAddressing, do_extended=self.do_extended, wsdl=self._wsdl) + desc = BindingDescription(useWSA=self.wsAddressing, + do_extended=self.do_extended, + wsdl=self._wsdl) try: desc.setUp(port.getBinding()) except Wsdl2PythonError, ex: @@ -314,22 +322,22 @@ fd -- file descriptor to write out service description. msg_fd -- optional file descriptor for messages module. """ - if msg_fd != None: - print >>fd, self.messagesImports - print >>msg_fd, self.imports - else: - print >>fd, self.imports +# if msg_fd != None: +# print >>fd, self.messagesImports +# print >>msg_fd, self.imports +# else: + print >>fd, self.imports print >>fd, self.locator for m in self.bindings: print >>fd, m - if msg_fd != None: - for m in self.messages: - print >>msg_fd, m - else: - for m in self.messages: - print >>fd, m +# if msg_fd != None: +# for m in self.messages: +# print >>msg_fd, m +# else: + for m in self.messages: + print >>fd, m class MessageWriter: Added: trunk/zsi/test/test_QName.py =================================================================== --- trunk/zsi/test/test_QName.py (rev 0) +++ trunk/zsi/test/test_QName.py 2007-07-06 22:51:32 UTC (rev 1402) @@ -0,0 +1,67 @@ +#!/usr/bin/env python +import unittest, sys, tests_good, tests_bad, time +from ZSI import * +try: + import cStringIO as StringIO +except ImportError: + import StringIO + + +"""Bug [ 1520092 ] URI Bug: urllib.quote escaping reserved chars +""" + + +class TestCase(unittest.TestCase): + def check_soapfault_faultcode(self): + """ Typecode QName when default namespace is not declared, should + specify the empty namespace. + """ + msg = """<?xml version="1.0" encoding="UTF-8"?> +<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" + xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> +<soapenv:Body> +<soapenv:Fault> + <faultcode>ServerFaultCode</faultcode> + <faultstring>Operation failed since VMware tools are not running in this virtual machine.</faultstring> + <detail> + <ToolsUnavailableFault xmlns="urn:vim2"/> + </detail> +</soapenv:Fault> +</soapenv:Body> +</soapenv:Envelope>""" + + from ZSI import ParsedSoap, FaultFromFaultMessage + ps = ParsedSoap(msg) + fault = FaultFromFaultMessage(ps) + self.failUnless(fault.code == ('','ServerFaultCode'), 'faultcode should be (namespace,name) tuple') + + +# +# Creates permutation of test options: "check", "check_any", etc +# +_SEP = '_' +for t in [i[0].split(_SEP) for i in filter(lambda i: callable(i[1]), TestCase.__dict__.items())]: + test = '' + for f in t: + test += f + if globals().has_key(test): test += _SEP; continue + def _closure(): + name = test + def _makeTestSuite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(TestCase, name)) + return suite + return _makeTestSuite + + globals()[test] = _closure() + test += _SEP + + +makeTestSuite = check +def main(): + unittest.main(defaultTest="makeTestSuite") +if __name__ == "__main__" : main() + + Modified: trunk/zsi/test/test_zsi.py =================================================================== --- trunk/zsi/test/test_zsi.py 2007-07-06 18:35:46 UTC (rev 1401) +++ trunk/zsi/test/test_zsi.py 2007-07-06 22:51:32 UTC (rev 1402) @@ -13,6 +13,7 @@ import test_TCtimes import test_URI import test_rfc2617 +import test_QName def makeTestSuite(): return unittest.TestSuite( Modified: trunk/zsi/test/test_zsi_net.py =================================================================== --- trunk/zsi/test/test_zsi_net.py 2007-07-06 18:35:46 UTC (rev 1401) +++ trunk/zsi/test/test_zsi_net.py 2007-07-06 22:51:32 UTC (rev 1402) @@ -1,24 +1,11 @@ #!/usr/bin/env python -import unittest -import test_t1 -import test_t2 -import test_t3 import test_t4 -import test_t5 -import test_t6 -import test_t7 -import test_t8 -import test_t9 -import test_union -import test_TCtimes -import test_URI -import test_list -import test_rfc2617 import test_callhome +from test_zsi import * def makeTestSuite(): return unittest.TestSuite( - map(lambda t: globals()[t].makeTestSuite(), + map(lambda t: globals()[t].makeTestSuite(), filter(lambda g: g.startswith('test_') and True, globals())) ) Modified: trunk/zsi/test/wsdl2py/test_AWSECommerceService.py =================================================================== --- trunk/zsi/test/wsdl2py/test_AWSECommerceService.py 2007-07-06 18:35:46 UTC (rev 1401) +++ trunk/zsi/test/wsdl2py/test_AWSECommerceService.py 2007-07-06 22:51:32 UTC (rev 1402) @@ -42,7 +42,7 @@ return suite -TargetNamespace = "http://webservices.amazon.com/AWSECommerceService/2007-05-14" +TargetNamespace = "http://webservices.amazon.com/AWSECommerceService/2007-06-13" class AmazonTestCase(ServiceTestCase): """Test case for Amazon ECommerce Web service """ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2007-07-11 00:09:05
|
Revision: 1407 http://svn.sourceforge.net/pywebsvcs/?rev=1407&view=rev Author: boverhof Date: 2007-07-10 17:09:00 -0700 (Tue, 10 Jul 2007) Log Message: ----------- M test/wsdl2py/config.txt A test/wsdl2py/test_Clearspace.py M ZSI/generate/commands.py M ZSI/generate/containers.py -- throw warning if missing "import" in schema, this shows up with wsdl2py --debug -- look for dependent schemas in WSDL types information item, if find it great if not throw SchemaError -- added unittest for Clearspace BlogService using WSSE:Security UsernameToken profile, uses the public sandbox Modified Paths: -------------- trunk/zsi/ZSI/generate/commands.py trunk/zsi/ZSI/generate/containers.py trunk/zsi/test/wsdl2py/config.txt Added Paths: ----------- trunk/zsi/test/wsdl2py/test_Clearspace.py Modified: trunk/zsi/ZSI/generate/commands.py =================================================================== --- trunk/zsi/ZSI/generate/commands.py 2007-07-10 20:26:11 UTC (rev 1406) +++ trunk/zsi/ZSI/generate/commands.py 2007-07-11 00:09:00 UTC (rev 1407) @@ -150,10 +150,10 @@ if isinstance(wsdl, XMLSchema.XMLSchema): wsdl.location = location - return _wsdl2py(options, wsdl) - - files = _wsdl2py(options, wsdl) - files.append(_wsdl2dispatch(options, wsdl)) + files = _wsdl2py(options, wsdl) + else: + files = _wsdl2py(options, wsdl) + files.append(_wsdl2dispatch(options, wsdl)) if getattr(options, 'pydoc', False): _writepydoc(os.path.join('docs', 'API'), *files) Modified: trunk/zsi/ZSI/generate/containers.py =================================================================== --- trunk/zsi/ZSI/generate/containers.py 2007-07-10 20:26:11 UTC (rev 1406) +++ trunk/zsi/ZSI/generate/containers.py 2007-07-11 00:09:00 UTC (rev 1407) @@ -586,10 +586,9 @@ elif self.soap_input_headers: method = [ '%s# op: %s' % (ID1, self.name), - '%sdef %s(self, request, soapheaders=()):' % (ID1, self.name), + '%sdef %s(self, request, soapheaders=(), **kw):' % (ID1, self.name), '%s%s' % (ID2, tCheck), '%sraise TypeError, "%%s incorrect request type" %% (%s)' %(ID3, 'request.__class__'), - '%s%s' % (ID2, kwstring), '%s%s' % (ID2, wsactionIn), '%s# TODO: Check soapheaders' % (ID2), '%sself.binding.Send(None, None, request, soapaction="%s", soapheaders=soapheaders, %s'\ @@ -598,10 +597,9 @@ else: method = [ '%s# op: %s' % (ID1, self.name), - '%sdef %s(self, request):' % (ID1, self.name), + '%sdef %s(self, request, **kw):' % (ID1, self.name), '%s%s' % (ID2, tCheck), '%sraise TypeError, "%%s incorrect request type" %% (%s)' %(ID3, 'request.__class__'), - '%s%s' % (ID2, kwstring), '%s%s' % (ID2, wsactionIn), '%sself.binding.Send(None, None, request, soapaction="%s", %s'\ %(ID2, self.soapaction, bindArgs), Modified: trunk/zsi/test/wsdl2py/config.txt =================================================================== --- trunk/zsi/test/wsdl2py/config.txt 2007-07-10 20:26:11 UTC (rev 1406) +++ trunk/zsi/test/wsdl2py/config.txt 2007-07-11 00:09:00 UTC (rev 1407) @@ -179,3 +179,6 @@ test_Racing = wsdl/Racing.wsdl test_NVOAdmin = wsdl/nvo-admin.wsdl +test_Clearspace = http://eval.jivesoftware.com/clearspace/rpc/soap/BlogService?wsdl + + Added: trunk/zsi/test/wsdl2py/test_Clearspace.py =================================================================== --- trunk/zsi/test/wsdl2py/test_Clearspace.py (rev 0) +++ trunk/zsi/test/wsdl2py/test_Clearspace.py 2007-07-11 00:09:00 UTC (rev 1407) @@ -0,0 +1,98 @@ +#!/usr/bin/env python +############################################################################ +# Joshua R. Boverhof, LBNL +# See LBNLCopyright for copyright notice! +########################################################################### +import os, sys, unittest +from ServiceTest import main, ServiceTestCase, ServiceTestSuite +from ZSI import FaultException + +""" +Unittest for contacting Clearspace blog webservice + +WSDL: +""" + +# General targets +def dispatch(): + """Run all dispatch tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(ServiceTest, 'test_dispatch')) + return suite + +def local(): + """Run all local tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(ServiceTest, 'test_local')) + return suite + +def net(): + """Run all network tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(ServiceTest, 'test_net')) + return suite + +def all(): + """Run all tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(ServiceTest, 'test_')) + return suite + + +# NEED TO CREATE WSSE typecodes +from ZSI.generate.commands import wsdl2py +if not os.path.isdir('stubs'): os.makedirs('stubs') +wsdl2py(['--complexType', '--schema','--output-dir=stubs', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd']) + + +class BlogServiceTest(ServiceTestCase): + """Test case for Clearspace sandbox, example how to use client WSSE:Security UsernameToken Profile + +<wsdl:Envelope xmlns:soap="..." xmlns:wsse="..." > + <wsdl:Header> + <wsse:Security> + <wsse:UsernameToken> + <wsse:Username>admin</wsse:Username> + <wsse:Password>password</wsse:Password> + </wsse:UsernameToken> + </wsse:Security> + </wsdl:Header> +</wsdl:Envelope> + + """ + name = "test_Clearspace" + client_file_name = "BlogService_client.py" + types_file_name = "BlogService_types.py" + server_file_name = "BlogService_server.py" + + def __init__(self, methodName): + ServiceTestCase.__init__(self, methodName) + self.wsdl2py_args.append('-b') + + def _get_soap_headers(self): + import oasis_200401_wss_wssecurity_secext_1_0_xsd_types + from ZSI.schema import GED + security = GED("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security").pyclass() + token = GED("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "UsernameToken").pyclass() + security.Any = [token] + token.Username = 'billy' + klass = GED("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Password").pyclass + token.Any = [klass('guest'),] + + return (security,) + + def test_net_Blogcount(self): + loc = self.client_module.BlogServiceLocator() + msg = self.client_module.getBlogCountRequest() + port = loc.getBlogServiceHttpPort(**self.getPortKWArgs()) + rsp = port.getBlogCount(msg, soapheaders=self._get_soap_headers(),) + + def test_local_(self): + import oasis_200401_wss_wssecurity_secext_1_0_xsd_types + return + +ServiceTest = BlogServiceTest + +if __name__ == "__main__" : + main() + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2007-07-17 22:40:53
|
Revision: 1409 http://svn.sourceforge.net/pywebsvcs/?rev=1409&view=rev Author: boverhof Date: 2007-07-17 15:40:51 -0700 (Tue, 17 Jul 2007) Log Message: ----------- M test/test_t1.py M ZSI/TC.py FIX BUG [ 1724481 ] Error handling of enum serialization broken Modified Paths: -------------- trunk/zsi/ZSI/TC.py trunk/zsi/test/test_t1.py Modified: trunk/zsi/ZSI/TC.py =================================================================== --- trunk/zsi/ZSI/TC.py 2007-07-17 22:26:07 UTC (rev 1408) +++ trunk/zsi/ZSI/TC.py 2007-07-17 22:40:51 UTC (rev 1409) @@ -917,7 +917,7 @@ def serialize(self, elt, sw, pyobj, name=None, orig=None, **kw): if pyobj not in self.choices: raise EvaluateException('Value not in enumeration list', - ps.Backtrace(elt)) + sw.Backtrace(elt)) String.serialize(self, elt, sw, pyobj, name=name, orig=orig, **kw) Modified: trunk/zsi/test/test_t1.py =================================================================== --- trunk/zsi/test/test_t1.py 2007-07-17 22:26:07 UTC (rev 1408) +++ trunk/zsi/test/test_t1.py 2007-07-17 22:40:51 UTC (rev 1409) @@ -27,6 +27,12 @@ self.goodTests.sort(lambda a,b: cmp(a[0], b[0])) self.badTests.sort(lambda a,b: cmp(a[0], b[0])) + def check_bug1724481(self): + # [ 1724481 ] Error handling of enum serialization broken" + enum = TC.Enumeration(['Red', 'Blue', 'Green'], 'color') + sw = SoapWriter() + self.assertRaises(EvaluateException, sw.serialize,'ddd', enum) + def checkt1(self): for key,val in self.badTests: print "\n", "." * 60, key This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2007-07-17 22:40:45
|
Revision: 1408 http://svn.sourceforge.net/pywebsvcs/?rev=1408&view=rev Author: boverhof Date: 2007-07-17 15:26:07 -0700 (Tue, 17 Jul 2007) Log Message: ----------- M test/wsdl2py/config.txt A test/wsdl2py/wsdl/vim.wsdl A test/wsdl2py/test_VIM.py M ZSI/TCcompound.py -- FIX and UNITTEST FOR BUG [ 1755740 ] Multiple calls to the same method Modified Paths: -------------- trunk/zsi/ZSI/TCcompound.py trunk/zsi/test/wsdl2py/config.txt Added Paths: ----------- trunk/zsi/test/wsdl2py/test_VIM.py trunk/zsi/test/wsdl2py/wsdl/vim.wsdl Modified: trunk/zsi/ZSI/TCcompound.py =================================================================== --- trunk/zsi/ZSI/TCcompound.py 2007-07-11 00:09:00 UTC (rev 1407) +++ trunk/zsi/ZSI/TCcompound.py 2007-07-17 22:26:07 UTC (rev 1408) @@ -19,6 +19,7 @@ from ZSI.wstools.Utility import SplitQName from ZSI.wstools.logging import getLogger as _GetLogger import re, types +from copy import copy as _copy _find_arrayoffset = lambda E: E.getAttributeNS(SOAP.ENC, "offset") _find_arrayposition = lambda E: E.getAttributeNS(SOAP.ENC, "position") @@ -74,12 +75,14 @@ 'failed to serialize substitute %s for %s, not derivation: %s' % (sub, typecode, sw.Backtrace(elt),)) - # Make our substitution type match the elements facets + # Make our substitution type match the elements facets, + # since typecode is created for a single existing pyobj + # some facets are irrelevant. + sub = _copy(sub) sub.nspname = typecode.nspname sub.pname = typecode.pname sub.aname = typecode.aname - sub.minOccurs = 1 - sub.maxOccurs = 1 + sub.minOccurs = sub.maxOccurs = 1 return sub Modified: trunk/zsi/test/wsdl2py/config.txt =================================================================== --- trunk/zsi/test/wsdl2py/config.txt 2007-07-11 00:09:00 UTC (rev 1407) +++ trunk/zsi/test/wsdl2py/config.txt 2007-07-17 22:26:07 UTC (rev 1408) @@ -119,7 +119,7 @@ document = True literal = True broke = False -tests = test_MapPoint test_Echo test_AWSECommerceService test_FinancialService test_BasicComm test_Manufacturer test_Racing test_Attributes test_Choice test_DerivedTypes test_EchoWSAddr200403 test_SubstitutionGroup +tests = test_MapPoint test_Echo test_AWSECommerceService test_FinancialService test_BasicComm test_Manufacturer test_Racing test_Attributes test_Choice test_DerivedTypes test_EchoWSAddr200403 test_SubstitutionGroup test_VIM [doc_literal_broke] document = True @@ -180,5 +180,6 @@ test_NVOAdmin = wsdl/nvo-admin.wsdl test_Clearspace = http://eval.jivesoftware.com/clearspace/rpc/soap/BlogService?wsdl +test_VIM = wsdl/vim.wsdl Added: trunk/zsi/test/wsdl2py/test_VIM.py =================================================================== --- trunk/zsi/test/wsdl2py/test_VIM.py (rev 0) +++ trunk/zsi/test/wsdl2py/test_VIM.py 2007-07-17 22:26:07 UTC (rev 1408) @@ -0,0 +1,115 @@ +#!/usr/bin/env python +############################################################################ +# Joshua R. Boverhof, LBNL +# See LBNLCopyright for copyright notice! +########################################################################### +import os, sys, unittest +from ServiceTest import main, ServiceTestCase, ServiceTestSuite +from ZSI import FaultException, ParsedSoap, SoapWriter +""" +Unittest + +WSDL: wsdl/vim.wsdl +""" + +# General targets +def dispatch(): + """Run all dispatch tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(VIMTestCase, 'test_dispatch')) + return suite + +def local(): + """Run all local tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(VIMTestCase, 'test_local')) + return suite + +def net(): + """Run all network tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(VIMTestCase, 'test_net')) + return suite + +def all(): + """Run all tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(VIMTestCase, 'test_')) + return suite + + +class VIMTestCase(ServiceTestCase): + name = "test_VIM" + client_file_name = "VIM_client.py" + types_file_name = "VIM_types.py" + server_file_name = "VIM_server.py" + + def __init__(self, methodName): + ServiceTestCase.__init__(self, methodName) + self.wsdl2py_args.append('--lazy') + self.wsdl2py_args.append('-b') + + def test_local_substitute_SessionManager(self): + # BUG [ 1755740 ] Multiple calls to the same method + MSG = """<?xml version="1.0" encoding="UTF-8"?> +<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" + xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> +<soapenv:Body> +<RetrieveServiceContentResponse xmlns="urn:vim2"> + <returnval> + <rootFolder type="Folder">group-d1</rootFolder> + <propertyCollector type="PropertyCollector">propertyCollector</propertyCollector> + <about> + <name>VMware VirtualCenter</name> + <fullName>VMware VirtualCenter 2.0.1 build-32042</fullName> + <vendor>VMware, Inc.</vendor> + <version>2.0.1</version> + <build>32042</build> + <localeVersion>INTL</localeVersion> + <localeBuild>000</localeBuild> + <osType>win32-x86</osType> + <productLineId>vpx</productLineId> + <apiType>VirtualCenter</apiType> + <apiVersion>2.0.0</apiVersion> + </about> + <setting type="OptionManager">VpxSettings</setting> + <userDirectory type="UserDirectory">UserDirectory</userDirectory> + <sessionManager type="SessionManager">SessionManager</sessionManager> + <authorizationManager type="AuthorizationManager">AuthorizationManager</authorizationManager> + <perfManager type="PerformanceManager">PerfMgr</perfManager> + <scheduledTaskManager type="ScheduledTaskManager">ScheduledTaskManager</scheduledTaskManager> + <alarmManager type="AlarmManager">AlarmManager</alarmManager> + <eventManager type="EventManager">EventManager</eventManager> + <taskManager type="TaskManager">TaskManager</taskManager> + <customizationSpecManager type="CustomizationSpecManager">CustomizationSpecManager</customizationSpecManager> + <customFieldsManager type="CustomFieldsManager">CustomFieldsManager</customFieldsManager> + <diagnosticManager type="DiagnosticManager">DiagMgr</diagnosticManager> + <licenseManager type="LicenseManager">LicenseManager</licenseManager> + <searchIndex type="SearchIndex">SearchIndex</searchIndex> + </returnval> +</RetrieveServiceContentResponse> +</soapenv:Body> +</soapenv:Envelope>""" + + # Parse it out + ps = ParsedSoap(MSG) + pyobj = ps.Parse( self.client_module.RetrieveServiceContentResponseMsg.typecode ) + sessionMgr = pyobj.Returnval.SessionManager + + # Serialize SessionManager in different context + msg = self.client_module.LogoutRequestMsg() + msg._this = sessionMgr + SoapWriter().serialize(msg) + + # Parse it out: was failing + # ZSI.EvaluateException: Element "__this" missing from complexType + # [Element trace: /soapenv:Envelope/soapenv:Body/RetrieveServiceContentResponse/returnval] + ps = ParsedSoap(MSG) + pyobj = ps.Parse( self.client_module.RetrieveServiceContentResponseMsg.typecode ) + + +if __name__ == "__main__" : + main() + Added: trunk/zsi/test/wsdl2py/wsdl/vim.wsdl =================================================================== --- trunk/zsi/test/wsdl2py/wsdl/vim.wsdl (rev 0) +++ trunk/zsi/test/wsdl2py/wsdl/vim.wsdl 2007-07-17 22:26:07 UTC (rev 1408) @@ -0,0 +1,22098 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<definitions name="VIM" targetNamespace="urn:vim2" + xmlns="http://schemas.xmlsoap.org/wsdl/" + xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:vim2="urn:vim2" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" +> + <types> + <schema + targetNamespace="urn:vim2" + xmlns="http://www.w3.org/2001/XMLSchema" + xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" + xmlns:vim2="urn:vim2" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + elementFormDefault="qualified" + > + <complexType name="DynamicArray"> + <sequence> + <element name="dynamicType" type="xsd:string" minOccurs="0" /> + <element name="val" type="xsd:anyType" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="DynamicData"> + <sequence> + <element name="dynamicType" type="xsd:string" minOccurs="0" /> + <element name="dynamicProperty" type="vim2:DynamicProperty" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="DynamicProperty"> + <sequence> + <element name="name" type="xsd:string" /> + <element name="val" type="xsd:anyType" /> + </sequence> + </complexType> + <complexType name="ArrayOfDynamicProperty"> + <sequence> + <element name="DynamicProperty" type="vim2:DynamicProperty" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="HostCommunication"> + <complexContent> + <extension base="vim2:RuntimeFault"> + <sequence> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="HostCommunicationFault" type="vim2:HostCommunication"/> + <complexType name="HostNotConnected"> + <complexContent> + <extension base="vim2:HostCommunication"> + <sequence> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="HostNotConnectedFault" type="vim2:HostNotConnected"/> + <complexType name="HostNotReachable"> + <complexContent> + <extension base="vim2:HostCommunication"> + <sequence> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="HostNotReachableFault" type="vim2:HostNotReachable"/> + <complexType name="InvalidArgument"> + <complexContent> + <extension base="vim2:RuntimeFault"> + <sequence> + <element name="invalidProperty" type="xsd:string" minOccurs="0" /> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="InvalidArgumentFault" type="vim2:InvalidArgument"/> + <complexType name="InvalidRequest"> + <complexContent> + <extension base="vim2:RuntimeFault"> + <sequence> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="InvalidRequestFault" type="vim2:InvalidRequest"/> + <complexType name="InvalidType"> + <complexContent> + <extension base="vim2:InvalidRequest"> + <sequence> + <element name="argument" type="xsd:string" minOccurs="0" /> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="InvalidTypeFault" type="vim2:InvalidType"/> + <complexType name="ManagedObjectNotFound"> + <complexContent> + <extension base="vim2:RuntimeFault"> + <sequence> + <element name="obj" type="vim2:ManagedObjectReference" /> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="ManagedObjectNotFoundFault" type="vim2:ManagedObjectNotFound"/> + <complexType name="MethodNotFound"> + <complexContent> + <extension base="vim2:InvalidRequest"> + <sequence> + <element name="receiver" type="vim2:ManagedObjectReference" /> + <element name="method" type="xsd:string" /> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="MethodNotFoundFault" type="vim2:MethodNotFound"/> + <complexType name="NotEnoughLicenses"> + <complexContent> + <extension base="vim2:RuntimeFault"> + <sequence> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="NotEnoughLicensesFault" type="vim2:NotEnoughLicenses"/> + <complexType name="NotImplemented"> + <complexContent> + <extension base="vim2:RuntimeFault"> + <sequence> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="NotImplementedFault" type="vim2:NotImplemented"/> + <complexType name="NotSupported"> + <complexContent> + <extension base="vim2:RuntimeFault"> + <sequence> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="NotSupportedFault" type="vim2:NotSupported"/> + <complexType name="RequestCanceled"> + <complexContent> + <extension base="vim2:RuntimeFault"> + <sequence> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="RequestCanceledFault" type="vim2:RequestCanceled"/> + <complexType name="SecurityError"> + <complexContent> + <extension base="vim2:RuntimeFault"> + <sequence> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="SecurityErrorFault" type="vim2:SecurityError"/> + <complexType name="SystemError"> + <complexContent> + <extension base="vim2:RuntimeFault"> + <sequence> + <element name="reason" type="xsd:string" /> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="SystemErrorFault" type="vim2:SystemError"/> + <complexType name="InvalidCollectorVersion"> + <complexContent> + <extension base="vim2:MethodFault"> + <sequence> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="InvalidCollectorVersionFault" type="vim2:InvalidCollectorVersion"/> + <complexType name="InvalidProperty"> + <complexContent> + <extension base="vim2:MethodFault"> + <sequence> + <element name="name" type="xsd:string" /> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="InvalidPropertyFault" type="vim2:InvalidProperty"/> + <complexType name="PropertyFilterSpec"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="propSet" type="vim2:PropertySpec" maxOccurs="unbounded" /> + <element name="objectSet" type="vim2:ObjectSpec" maxOccurs="unbounded" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfPropertyFilterSpec"> + <sequence> + <element name="PropertyFilterSpec" type="vim2:PropertyFilterSpec" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="PropertySpec"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="type" type="xsd:string" /> + <element name="all" type="xsd:boolean" minOccurs="0" /> + <element name="pathSet" type="xsd:string" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfPropertySpec"> + <sequence> + <element name="PropertySpec" type="vim2:PropertySpec" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="ObjectSpec"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="obj" type="vim2:ManagedObjectReference" /> + <element name="skip" type="xsd:boolean" minOccurs="0" /> + <element name="selectSet" type="vim2:SelectionSpec" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfObjectSpec"> + <sequence> + <element name="ObjectSpec" type="vim2:ObjectSpec" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="SelectionSpec"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="name" type="xsd:string" minOccurs="0" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfSelectionSpec"> + <sequence> + <element name="SelectionSpec" type="vim2:SelectionSpec" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="TraversalSpec"> + <complexContent> + <extension base="vim2:SelectionSpec"> + <sequence> + <element name="type" type="xsd:string" /> + <element name="path" type="xsd:string" /> + <element name="skip" type="xsd:boolean" minOccurs="0" /> + <element name="selectSet" type="vim2:SelectionSpec" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="DestroyPropertyFilter"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + </sequence> + </complexType> + </element> + <element name="DestroyPropertyFilterResponse"> + <complexType /> + </element> + <complexType name="ObjectContent"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="obj" type="vim2:ManagedObjectReference" /> + <element name="propSet" type="vim2:DynamicProperty" minOccurs="0" maxOccurs="unbounded" /> + <element name="missingSet" type="vim2:MissingProperty" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfObjectContent"> + <sequence> + <element name="ObjectContent" type="vim2:ObjectContent" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="UpdateSet"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="version" type="xsd:string" /> + <element name="filterSet" type="vim2:PropertyFilterUpdate" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="PropertyFilterUpdate"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="filter" type="vim2:ManagedObjectReference" /> + <element name="objectSet" type="vim2:ObjectUpdate" minOccurs="0" maxOccurs="unbounded" /> + <element name="missingSet" type="vim2:MissingObject" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfPropertyFilterUpdate"> + <sequence> + <element name="PropertyFilterUpdate" type="vim2:PropertyFilterUpdate" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <simpleType name="ObjectUpdateKind"> + <restriction base="xsd:string"> + <enumeration value="modify" /> + <enumeration value="enter" /> + <enumeration value="leave" /> + </restriction> + </simpleType> + <complexType name="ObjectUpdate"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="kind" type="vim2:ObjectUpdateKind" /> + <element name="obj" type="vim2:ManagedObjectReference" /> + <element name="changeSet" type="vim2:PropertyChange" minOccurs="0" maxOccurs="unbounded" /> + <element name="missingSet" type="vim2:MissingProperty" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfObjectUpdate"> + <sequence> + <element name="ObjectUpdate" type="vim2:ObjectUpdate" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <simpleType name="PropertyChangeOp"> + <restriction base="xsd:string"> + <enumeration value="add" /> + <enumeration value="remove" /> + <enumeration value="assign" /> + <enumeration value="indirectRemove" /> + </restriction> + </simpleType> + <complexType name="PropertyChange"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="name" type="xsd:string" /> + <element name="op" type="vim2:PropertyChangeOp" /> + <element name="val" type="xsd:anyType" minOccurs="0" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfPropertyChange"> + <sequence> + <element name="PropertyChange" type="vim2:PropertyChange" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="MissingProperty"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="path" type="xsd:string" /> + <element name="fault" type="vim2:LocalizedMethodFault" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfMissingProperty"> + <sequence> + <element name="MissingProperty" type="vim2:MissingProperty" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="MissingObject"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="obj" type="vim2:ManagedObjectReference" /> + <element name="fault" type="vim2:LocalizedMethodFault" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfMissingObject"> + <sequence> + <element name="MissingObject" type="vim2:MissingObject" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <element name="CreateFilter"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="spec" type="vim2:PropertyFilterSpec" /> + <element name="partialUpdates" type="xsd:boolean" /> + </sequence> + </complexType> + </element> + <element name="CreateFilterResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:ManagedObjectReference" /> + </sequence> + </complexType> + </element> + <element name="RetrieveProperties"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="specSet" type="vim2:PropertyFilterSpec" maxOccurs="unbounded" /> + </sequence> + </complexType> + </element> + <element name="RetrievePropertiesResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:ObjectContent" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + </element> + <element name="CheckForUpdates"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="version" type="xsd:string" minOccurs="0" /> + </sequence> + </complexType> + </element> + <element name="CheckForUpdatesResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:UpdateSet" minOccurs="0" /> + </sequence> + </complexType> + </element> + <element name="WaitForUpdates"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="version" type="xsd:string" minOccurs="0" /> + </sequence> + </complexType> + </element> + <element name="WaitForUpdatesResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:UpdateSet" /> + </sequence> + </complexType> + </element> + <element name="CancelWaitForUpdates"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + </sequence> + </complexType> + </element> + <element name="CancelWaitForUpdatesResponse"> + <complexType /> + </element> + <complexType name="LocalizedMethodFault"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="fault" type="vim2:MethodFault" /> + <element name="localizedMessage" type="xsd:string" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="MethodFault"> + <sequence> + <element name="dynamicType" type="xsd:string" minOccurs="0" /> + <element name="dynamicProperty" type="vim2:DynamicProperty" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <element name="MethodFaultFault" type="vim2:MethodFault"/> + <complexType name="RuntimeFault"> + <complexContent> + <extension base="vim2:MethodFault"> + <sequence> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="RuntimeFaultFault" type="vim2:RuntimeFault"/> + <complexType name="AboutInfo"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="name" type="xsd:string" /> + <element name="fullName" type="xsd:string" /> + <element name="vendor" type="xsd:string" /> + <element name="version" type="xsd:string" /> + <element name="build" type="xsd:string" /> + <element name="localeVersion" type="xsd:string" minOccurs="0" /> + <element name="localeBuild" type="xsd:string" minOccurs="0" /> + <element name="osType" type="xsd:string" /> + <element name="productLineId" type="xsd:string" /> + <element name="apiType" type="xsd:string" /> + <element name="apiVersion" type="xsd:string" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="AuthorizationDescription"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="privilege" type="vim2:ElementDescription" maxOccurs="unbounded" /> + <element name="privilegeGroup" type="vim2:ElementDescription" maxOccurs="unbounded" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="Permission"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="entity" type="vim2:ManagedObjectReference" minOccurs="0" /> + <element name="principal" type="xsd:string" /> + <element name="group" type="xsd:boolean" /> + <element name="roleId" type="xsd:int" /> + <element name="propagate" type="xsd:boolean" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfPermission"> + <sequence> + <element name="Permission" type="vim2:Permission" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="AuthorizationRole"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="roleId" type="xsd:int" /> + <element name="system" type="xsd:boolean" /> + <element name="name" type="xsd:string" /> + <element name="info" type="vim2:Description" /> + <element name="privilege" type="xsd:string" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfAuthorizationRole"> + <sequence> + <element name="AuthorizationRole" type="vim2:AuthorizationRole" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="AuthorizationPrivilege"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="privId" type="xsd:string" /> + <element name="onParent" type="xsd:boolean" /> + <element name="name" type="xsd:string" /> + <element name="privGroupName" type="xsd:string" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfAuthorizationPrivilege"> + <sequence> + <element name="AuthorizationPrivilege" type="vim2:AuthorizationPrivilege" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <element name="AddAuthorizationRole"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="name" type="xsd:string" /> + <element name="privIds" type="xsd:string" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + </element> + <element name="AddAuthorizationRoleResponse"> + <complexType> + <sequence> + <element name="returnval" type="xsd:int" /> + </sequence> + </complexType> + </element> + <element name="RemoveAuthorizationRole"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="roleId" type="xsd:int" /> + <element name="failIfUsed" type="xsd:boolean" /> + </sequence> + </complexType> + </element> + <element name="RemoveAuthorizationRoleResponse"> + <complexType /> + </element> + <element name="UpdateAuthorizationRole"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="roleId" type="xsd:int" /> + <element name="newName" type="xsd:string" /> + <element name="privIds" type="xsd:string" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + </element> + <element name="UpdateAuthorizationRoleResponse"> + <complexType /> + </element> + <element name="MergePermissions"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="srcRoleId" type="xsd:int" /> + <element name="dstRoleId" type="xsd:int" /> + </sequence> + </complexType> + </element> + <element name="MergePermissionsResponse"> + <complexType /> + </element> + <element name="RetrieveRolePermissions"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="roleId" type="xsd:int" /> + </sequence> + </complexType> + </element> + <element name="RetrieveRolePermissionsResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:Permission" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + </element> + <element name="RetrieveEntityPermissions"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="entity" type="vim2:ManagedObjectReference" /> + <element name="inherited" type="xsd:boolean" /> + </sequence> + </complexType> + </element> + <element name="RetrieveEntityPermissionsResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:Permission" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + </element> + <element name="RetrieveAllPermissions"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + </sequence> + </complexType> + </element> + <element name="RetrieveAllPermissionsResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:Permission" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + </element> + <element name="SetEntityPermissions"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="entity" type="vim2:ManagedObjectReference" /> + <element name="permission" type="vim2:Permission" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + </element> + <element name="SetEntityPermissionsResponse"> + <complexType /> + </element> + <element name="ResetEntityPermissions"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="entity" type="vim2:ManagedObjectReference" /> + <element name="permission" type="vim2:Permission" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + </element> + <element name="ResetEntityPermissionsResponse"> + <complexType /> + </element> + <element name="RemoveEntityPermission"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="entity" type="vim2:ManagedObjectReference" /> + <element name="user" type="xsd:string" /> + <element name="isGroup" type="xsd:boolean" /> + </sequence> + </complexType> + </element> + <element name="RemoveEntityPermissionResponse"> + <complexType /> + </element> + <complexType name="Capability"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="provisioningSupported" type="xsd:boolean" /> + <element name="multiHostSupported" type="xsd:boolean" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ClusterComputeResourceSummary"> + <complexContent> + <extension base="vim2:ComputeResourceSummary"> + <sequence> + <element name="currentFailoverLevel" type="xsd:int" /> + <element name="numVmotions" type="xsd:int" /> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="ReconfigureCluster_Task"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="spec" type="vim2:ClusterConfigSpec" /> + <element name="modify" type="xsd:boolean" /> + </sequence> + </complexType> + </element> + <element name="ReconfigureCluster_TaskResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:ManagedObjectReference" /> + </sequence> + </complexType> + </element> + <element name="ApplyRecommendation"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="key" type="xsd:string" /> + </sequence> + </complexType> + </element> + <element name="ApplyRecommendationResponse"> + <complexType /> + </element> + <element name="RecommendHostsForVm"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="vm" type="vim2:ManagedObjectReference" /> + <element name="pool" type="vim2:ManagedObjectReference" minOccurs="0" /> + </sequence> + </complexType> + </element> + <element name="RecommendHostsForVmResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:ClusterHostRecommendation" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + </element> + <element name="AddHost_Task"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="spec" type="vim2:HostConnectSpec" /> + <element name="asConnected" type="xsd:boolean" /> + <element name="resourcePool" type="vim2:ManagedObjectReference" minOccurs="0" /> + </sequence> + </complexType> + </element> + <element name="AddHost_TaskResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:ManagedObjectReference" /> + </sequence> + </complexType> + </element> + <element name="MoveInto_Task"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="host" type="vim2:ManagedObjectReference" maxOccurs="unbounded" /> + </sequence> + </complexType> + </element> + <element name="MoveInto_TaskResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:ManagedObjectReference" /> + </sequence> + </complexType> + </element> + <element name="MoveHostInto_Task"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="host" type="vim2:ManagedObjectReference" /> + <element name="resourcePool" type="vim2:ManagedObjectReference" minOccurs="0" /> + </sequence> + </complexType> + </element> + <element name="MoveHostInto_TaskResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:ManagedObjectReference" /> + </sequence> + </complexType> + </element> + <complexType name="ComputeResourceSummary"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="totalCpu" type="xsd:int" /> + <element name="totalMemory" type="xsd:long" /> + <element name="numCpuCores" type="xsd:short" /> + <element name="numCpuThreads" type="xsd:short" /> + <element name="effectiveCpu" type="xsd:int" /> + <element name="effectiveMemory" type="xsd:long" /> + <element name="numHosts" type="xsd:int" /> + <element name="numEffectiveHosts" type="xsd:int" /> + <element name="overallStatus" type="vim2:ManagedEntityStatus" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="CustomFieldDef"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="key" type="xsd:int" /> + <element name="name" type="xsd:string" /> + <element name="type" type="xsd:string" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfCustomFieldDef"> + <sequence> + <element name="CustomFieldDef" type="vim2:CustomFieldDef" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="CustomFieldValue"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="key" type="xsd:int" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfCustomFieldValue"> + <sequence> + <element name="CustomFieldValue" type="vim2:CustomFieldValue" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="CustomFieldStringValue"> + <complexContent> + <extension base="vim2:CustomFieldValue"> + <sequence> + <element name="value" type="xsd:string" /> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="AddCustomFieldDef"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="name" type="xsd:string" /> + </sequence> + </complexType> + </element> + <element name="AddCustomFieldDefResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:CustomFieldDef" /> + </sequence> + </complexType> + </element> + <element name="RemoveCustomFieldDef"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="key" type="xsd:int" /> + </sequence> + </complexType> + </element> + <element name="RemoveCustomFieldDefResponse"> + <complexType /> + </element> + <element name="RenameCustomFieldDef"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="key" type="xsd:int" /> + <element name="name" type="xsd:string" /> + </sequence> + </complexType> + </element> + <element name="RenameCustomFieldDefResponse"> + <complexType /> + </element> + <element name="SetField"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="entity" type="vim2:ManagedObjectReference" /> + <element name="key" type="xsd:int" /> + <element name="value" type="xsd:string" /> + </sequence> + </complexType> + </element> + <element name="SetFieldResponse"> + <complexType /> + </element> + <element name="DoesCustomizationSpecExist"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="name" type="xsd:string" /> + </sequence> + </complexType> + </element> + <element name="DoesCustomizationSpecExistResponse"> + <complexType> + <sequence> + <element name="returnval" type="xsd:boolean" /> + </sequence> + </complexType> + </element> + <element name="GetCustomizationSpec"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="name" type="xsd:string" /> + </sequence> + </complexType> + </element> + <element name="GetCustomizationSpecResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:CustomizationSpecItem" /> + </sequence> + </complexType> + </element> + <element name="CreateCustomizationSpec"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="item" type="vim2:CustomizationSpecItem" /> + </sequence> + </complexType> + </element> + <element name="CreateCustomizationSpecResponse"> + <complexType /> + </element> + <element name="OverwriteCustomizationSpec"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="item" type="vim2:CustomizationSpecItem" /> + </sequence> + </complexType> + </element> + <element name="OverwriteCustomizationSpecResponse"> + <complexType /> + </element> + <element name="DeleteCustomizationSpec"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="name" type="xsd:string" /> + </sequence> + </complexType> + </element> + <element name="DeleteCustomizationSpecResponse"> + <complexType /> + </element> + <element name="DuplicateCustomizationSpec"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="name" type="xsd:string" /> + <element name="newName" type="xsd:string" /> + </sequence> + </complexType> + </element> + <element name="DuplicateCustomizationSpecResponse"> + <complexType /> + </element> + <element name="RenameCustomizationSpec"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="name" type="xsd:string" /> + <element name="newName" type="xsd:string" /> + </sequence> + </complexType> + </element> + <element name="RenameCustomizationSpecResponse"> + <complexType /> + </element> + <element name="CustomizationSpecItemToXml"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="item" type="vim2:CustomizationSpecItem" /> + </sequence> + </complexType> + </element> + <element name="CustomizationSpecItemToXmlResponse"> + <complexType> + <sequence> + <element name="returnval" type="xsd:string" /> + </sequence> + </complexType> + </element> + <element name="XmlToCustomizationSpecItem"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="specItemXml" type="xsd:string" /> + </sequence> + </complexType> + </element> + <element name="XmlToCustomizationSpecItemResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:CustomizationSpecItem" /> + </sequence> + </complexType> + </element> + <element name="CheckCustomizationResources"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="guestOs" type="xsd:string" /> + </sequence> + </complexType> + </element> + <element name="CheckCustomizationResourcesResponse"> + <complexType /> + </element> + <complexType name="CustomizationSpecInfo"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="name" type="xsd:string" /> + <element name="description" type="xsd:string" /> + <element name="type" type="xsd:string" /> + <element name="changeVersion" type="xsd:string" minOccurs="0" /> + <element name="lastUpdateTime" type="xsd:dateTime" minOccurs="0" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfCustomizationSpecInfo"> + <sequence> + <element name="CustomizationSpecInfo" type="vim2:CustomizationSpecInfo" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <complexType name="CustomizationSpecItem"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="info" type="vim2:CustomizationSpecInfo" /> + <element name="spec" type="vim2:CustomizationSpec" /> + </sequence> + </extension> + </complexContent> + </complexType> + <element name="QueryConnectionInfo"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="hostname" type="xsd:string" /> + <element name="port" type="xsd:int" /> + <element name="username" type="xsd:string" /> + <element name="password" type="xsd:string" /> + </sequence> + </complexType> + </element> + <element name="QueryConnectionInfoResponse"> + <complexType> + <sequence> + <element name="returnval" type="vim2:HostConnectInfo" /> + </sequence> + </complexType> + </element> + <complexType name="DatastoreSummary"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="datastore" type="vim2:ManagedObjectReference" minOccurs="0" /> + <element name="name" type="xsd:string" /> + <element name="url" type="xsd:string" /> + <element name="capacity" type="xsd:long" /> + <element name="freeSpace" type="xsd:long" /> + <element name="accessible" type="xsd:boolean" /> + <element name="multipleHostAccess" type="xsd:boolean" minOccurs="0" /> + <element name="type" type="xsd:string" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="DatastoreInfo"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="name" type="xsd:string" /> + <element name="url" type="xsd:string" /> + <element name="freeSpace" type="xsd:long" /> + <element name="maxFileSize" type="xsd:long" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="DatastoreCapability"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="directoryHierarchySupported" type="xsd:boolean" /> + <element name="rawDiskMappingsSupported" type="xsd:boolean" /> + <element name="perFileThinProvisioningSupported" type="xsd:boolean" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="DatastoreHostMount"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="key" type="vim2:ManagedObjectReference" /> + <element name="mountInfo" type="vim2:HostMountInfo" /> + </sequence> + </extension> + </complexContent> + </complexType> + <complexType name="ArrayOfDatastoreHostMount"> + <sequence> + <element name="DatastoreHostMount" type="vim2:DatastoreHostMount" minOccurs="0" maxOccurs="unbounded" /> + </sequence> + </complexType> + <element name="RenameDatastore"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + <element name="newName" type="xsd:string" /> + </sequence> + </complexType> + </element> + <element name="RenameDatastoreResponse"> + <complexType /> + </element> + <element name="RefreshDatastore"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + </sequence> + </complexType> + </element> + <element name="RefreshDatastoreResponse"> + <complexType /> + </element> + <element name="DestroyDatastore"> + <complexType> + <sequence> + <element name="_this" type="vim2:ManagedObjectReference" /> + </sequence> + </complexType> + </element> + <element name="DestroyDatastoreResponse"> + <complexType /> + </element> + <complexType name="Description"> + <complexContent> + <extension base="vim2:DynamicData"> + <sequence> + <element name="label" type="xsd:string" /> + <element name="summary" type="xsd:string" /> + </sequence> + </extension> + </complexContent> + </complexType> + <simpleType name="DiagnosticManagerLogCreator"> + <restriction base="xsd:string"> + <enumeration value="vpxd" /> + <enumeration value="vpxa" /> + <enumeration value="hostd" /> + <enumeration value="serverd" /> + <enumeration value="install" /> + <enumeration value="vpxClient" /> + </restriction> + </simpleType> + <simpleType name="DiagnosticManagerLogFormat"> + <restriction base="xsd:string"> + <enumeration value="plain" /> + </restriction> + </simpleType> + <complexType name="DiagnosticManagerLogDescriptor"> + ... [truncated message content] |
From: <bov...@us...> - 2007-08-07 22:56:34
|
Revision: 1412 http://pywebsvcs.svn.sourceforge.net/pywebsvcs/?rev=1412&view=rev Author: boverhof Date: 2007-08-07 15:56:37 -0700 (Tue, 07 Aug 2007) Log Message: ----------- M test/wsdl2py/ServiceTest.py M test/wsdl2py/test_AWSECommerceService.py -- update targetNamespace M test/wsdl2py/servers/EchoWSAddr200403Server.py M test/wsdl2py/servers/EchoServer.py -- added some code for starting up a twisted server if we have twisted stubs -- WORKS W/TWISTED ./runTests.py local -- WORKS W/TWISTED ./runTests.py net -- FEW WORKS W/TWISTED ./runTests.py dispatch M ZSI/ServiceContainer.py M ZSI/generate/wsdl2dispatch.py M ZSI/generate/commands.py -- Added server stubs for "--twisted" to "wsdlpy" tool, -- Modified Paths: -------------- trunk/zsi/ZSI/ServiceContainer.py trunk/zsi/ZSI/generate/commands.py trunk/zsi/ZSI/generate/wsdl2dispatch.py trunk/zsi/test/wsdl2py/ServiceTest.py trunk/zsi/test/wsdl2py/servers/EchoServer.py trunk/zsi/test/wsdl2py/servers/EchoWSAddr200403Server.py trunk/zsi/test/wsdl2py/test_AWSECommerceService.py Modified: trunk/zsi/ZSI/ServiceContainer.py =================================================================== --- trunk/zsi/ZSI/ServiceContainer.py 2007-07-31 17:41:38 UTC (rev 1411) +++ trunk/zsi/ZSI/ServiceContainer.py 2007-08-07 22:56:37 UTC (rev 1412) @@ -147,9 +147,6 @@ ''' address = ('', port) sc = ServiceContainer(address, services) - #for service in services: - # path = service.getPost() - # sc.setNode(service, path) sc.serve_forever() @@ -232,7 +229,7 @@ ''' encoding = "UTF-8" - def __init__(self, post=None): + def __init__(self, post): ''' post -- POST value ''' Modified: trunk/zsi/ZSI/generate/commands.py =================================================================== --- trunk/zsi/ZSI/generate/commands.py 2007-07-31 17:41:38 UTC (rev 1411) +++ trunk/zsi/ZSI/generate/commands.py 2007-08-07 22:56:37 UTC (rev 1412) @@ -37,12 +37,6 @@ 'from %(module)s import %(metaclass)s' %kwargs ) -def SetUpTwistedClient(option, opt, value, parser, *args, **kwargs): - from ZSI.generate.containers import ServiceHeaderContainer - ServiceHeaderContainer.imports.remove('from ZSI import client') - ServiceHeaderContainer.imports.append('from ZSI.twisted import client') - - def SetUpLazyEvaluation(option, opt, value, parser, *args, **kwargs): from ZSI.generate.containers import TypecodeContainerBase TypecodeContainerBase.lazy = True @@ -101,9 +95,7 @@ # Use Twisted op.add_option("-w", "--twisted", - action="callback", callback=SetUpTwistedClient, - callback_kwargs={'module':'ZSI.generate.pyclass', - 'metaclass':'pyclass_type'}, + action="store_true", dest='twisted', default=False, help="generate a twisted.web client/server, dependencies python>=2.4, Twisted>=2.0.0, TwistedWeb>=0.5.0") op.add_option("-o", "--output-dir", @@ -164,46 +156,56 @@ return files -def wsdl2dispatch(args=None): - """Deprecated: wsdl2py now generates everything - A utility for automatically generating service skeleton code from a wsdl - definition. - """ - op = optparse.OptionParser() - op.add_option("-a", "--address", - action="store_true", dest="address", default=False, - help="ws-addressing support, must include WS-Addressing schema.") - op.add_option("-d", "--debug", - action="callback", callback=SetDebugCallback, - help="debug output") - op.add_option("-t", "--types", - action="store", dest="types", default=None, type="string", - help="Write generated files to OUTPUT_DIR") - op.add_option("-o", "--output-dir", - action="store", dest="output_dir", default=".", type="string", - help="file to load types from") - op.add_option("-s", "--simple-naming", - action="store_true", dest="simple_naming", default=False, - help="Simplify generated naming.") - - if args is None: - (options, args) = op.parse_args() - else: - (options, args) = op.parse_args(args) - - if len(args) != 1: - print>>sys.stderr, 'Expecting a file/url as argument (WSDL).' - sys.exit(os.EX_USAGE) - - reader = WSDLTools.WSDLReader() - if isfile(args[0]): - _wsdl2dispatch(options, reader.loadFromFile(args[0])) - return +#def wsdl2dispatch(args=None): +# """Deprecated: wsdl2py now generates everything +# A utility for automatically generating service skeleton code from a wsdl +# definition. +# """ +# op = optparse.OptionParser() +# op.add_option("-a", "--address", +# action="store_true", dest="address", default=False, +# help="ws-addressing support, must include WS-Addressing schema.") +# op.add_option("-d", "--debug", +# action="callback", callback=SetDebugCallback, +# help="debug output") +# op.add_option("-t", "--types", +# action="store", dest="types", default=None, type="string", +# help="Write generated files to OUTPUT_DIR") +# op.add_option("-o", "--output-dir", +# action="store", dest="output_dir", default=".", type="string", +# help="file to load types from") +# op.add_option("-s", "--simple-naming", +# action="store_true", dest="simple_naming", default=False, +# help="Simplify generated naming.") +# +# if args is None: +# (options, args) = op.parse_args() +# else: +# (options, args) = op.parse_args(args) +# +# if len(args) != 1: +# print>>sys.stderr, 'Expecting a file/url as argument (WSDL).' +# sys.exit(os.EX_USAGE) +# +# reader = WSDLTools.WSDLReader() +# if isfile(args[0]): +# _wsdl2dispatch(options, reader.loadFromFile(args[0])) +# return +# +# _wsdl2dispatch(options, reader.loadFromURL(args[0])) - _wsdl2dispatch(options, reader.loadFromURL(args[0])) +def _wsdl2py(options, wsdl): -def _wsdl2py(options, wsdl): + if options.twisted: + from ZSI.generate.containers import ServiceHeaderContainer + try: + ServiceHeaderContainer.imports.remove('from ZSI import client') + except ValueError: + pass + ServiceHeaderContainer.imports.append('from ZSI.twisted import client') + + if options.simple_naming: # Use a different client suffix # WriteServiceModule.client_module_suffix = "_client" @@ -242,17 +244,21 @@ def _wsdl2dispatch(options, wsdl): -# if options.simple_naming: -# ServiceDescription.server_module_suffix = '_interface' -# ServiceDescription.func_aname = lambda instnc,n: TextProtect(n) -# ServiceDescription.separate_messages = True -# # use module names rather than their number. -# utility.namespace_name = lambda cls, ns: utility.Namespace2ModuleName(ns) - - if options.address is True: - ss = ServiceDescriptionWSA() + """TOOD: Remove ServiceContainer stuff, and replace with WSGI. + """ + kw = dict() + if options.twisted: + from ZSI.twisted.WSresource import WSResource + kw['base'] = WSResource + ss = ServiceDescription(**kw) + if options.address is True: + raise RuntimeError, 'WS-Address w/twisted currently unsupported, edit the "factory" attribute by hand' else: - ss = ServiceDescription() + # TODO: make all this handler arch + if options.address is True: + ss = ServiceDescriptionWSA() + else: + ss = ServiceDescription(**kw) ss.fromWSDL(wsdl) file_name = ss.getServiceModuleName()+'.py' Modified: trunk/zsi/ZSI/generate/wsdl2dispatch.py =================================================================== --- trunk/zsi/ZSI/generate/wsdl2dispatch.py 2007-07-31 17:41:38 UTC (rev 1411) +++ trunk/zsi/ZSI/generate/wsdl2dispatch.py 2007-08-07 22:56:37 UTC (rev 1412) @@ -1,4 +1,5 @@ #!/usr/bin/env python +import inspect from cStringIO import StringIO import ZSI, string, sys, getopt, urlparse, types, warnings from ZSI.wstools import WSDLTools @@ -45,11 +46,16 @@ ''' parameters: base -- either a class definition, or a str representing a qualified - class name. + class name (eg. module.name.classname) prefix -- method prefix. ''' + if inspect.isclass(base): + self.base_class_name = base.__name__ + self.base_module_name = inspect.getmodule(base).__name__ + else: + self.base_module_name, self.base_class_name = base.rsplit('.', 1) + self.wsdl = None - self.base_class = base self.method_prefix = prefix self._service_class = SOAPService @@ -61,26 +67,6 @@ self.types_module_name = None self.messages_module_name = None - def _getBaseClassName(self): - '''return base class name, do not override. - ''' - if self.base_class is None: - return - if type(self.base_class) is types.ClassType: - return self.base_class.__name__ - return rsplit(self.base_class, '.')[-1] - - def _getBaseClassModule(self): - '''return base class module, do not override. - ''' - if self.base_class is None: - return - if type(self.base_class) is types.ClassType: - return self.base_class.__module__ - if self.base_class.find('.') >= 0: - return rsplit(self.base_class, '.')[0] - return - def reset(self): self.header = StringIO() self.imports = StringIO() @@ -119,16 +105,6 @@ wsm = WriteServiceModule(self.wsdl) return wsm.getTypesModuleName() -# def getMessagesModuleName(self): -# '''return module name. -# ''' -# assert self.wsdl is not None, 'initialize, call fromWSDL' -# if self.messages_module_name is not None: -# return self.messages_module_name -# -# wsm = WriteServiceModule(self.wsdl) -# return wsm.getMessagesModuleName() - def getServiceModuleName(self): '''return module name. ''' @@ -158,12 +134,9 @@ 'expecting WSDLTools.Service instance.' s = self._services[service.name].classdef - base = self._getBaseClassName() - if base is None: - print >>s, 'class %s:' %(self.getClassName(service.name)) - else: - print >>s, 'class %s(%s):' %(self.getClassName(service.name), base) + print >>s, 'class %s(%s):' %(self.getClassName(service.name), self.base_class_name) + print >>s, '%ssoapAction = {}' % self.getIndent(level=1) print >>s, '%sroot = {}' % self.getIndent(level=1) @@ -173,16 +146,6 @@ i = self.imports print >>i, 'from ZSI.schema import GED, GTD' print >>i, 'from ZSI.TCcompound import ComplexType, Struct' -# if path is None: -# if self.separate_messages: -# print >>i, 'from %s import *' %self.getMessagesModuleName() -# else: -# print >>i, 'from %s import *' %self.getClientModuleName() -# else: -# if self.separate_messages: -# print >>i, 'from %s.%s import *' %(path, self.getMessagesModuleName()) -# else: -# print >>i, 'from %s.%s import *' %(path, self.getClientModuleName()) module = self.getTypesModuleName() package = self.getTypesModulePath() @@ -191,14 +154,7 @@ print >>i, 'from %s import *' %(module) - mod = self._getBaseClassModule() - name = self._getBaseClassName() - if mod is None and name is None: - pass - elif mod is None: - print >>i, 'import %s' %name - else: - print >>i, 'from %s import %s' %(mod, name) + print >>i, 'from %s import %s' %(self.base_module_name, self.base_class_name) def setUpInitDef(self, service): '''set __init__ function @@ -215,10 +171,14 @@ else: print >>d, '%sdef __init__(self, post, **kw):' %self.getIndent(level=1) - base = self._getBaseClassName() - if base is not None: - print >>d, '%s%s.__init__(self, post)' %(self.getIndent(level=2), base) + # Require POST initialization value for test implementation + if self.base_module_name == inspect.getmodule(ServiceSOAPBinding).__name__: + print >>d, '%s%s.__init__(self, post)' %(self.getIndent(level=2), self.base_class_name) + return + # No POST initialization value, obtained from HTTP Request in twisted or wsgi + print >>d, '%s%s.__init__(self)' %(self.getIndent(level=2), self.base_class_name) + def mangle(self, name): return TextProtect(name) @@ -261,7 +221,7 @@ method_name = self.getMethodName(op.name) m = sd.newMethod() - print >>m, '%sdef %s(self, ps):' %(self.getIndent(level=1), method_name) + print >>m, '%sdef %s(self, ps, **kw):' %(self.getIndent(level=1), method_name) if msgin is not None: print >>m, '%srequest = ps.Parse(%s.typecode)' %(self.getIndent(level=2), msgin_name) else: @@ -392,8 +352,7 @@ 'expecting WSDLTools.Service instance' s = self._services[service.name].classdef - print >>s, 'class %s(%s):' %(self.getClassName(service.name), - self._getBaseClassName()) + print >>s, 'class %s(%s):' %(self.getClassName(service.name), self.base_class_name) print >>s, '%ssoapAction = {}' % self.getIndent(level=1) print >>s, '%swsAction = {}' % self.getIndent(level=1) print >>s, '%sroot = {}' % self.getIndent(level=1) Modified: trunk/zsi/test/wsdl2py/ServiceTest.py =================================================================== --- trunk/zsi/test/wsdl2py/ServiceTest.py 2007-07-31 17:41:38 UTC (rev 1411) +++ trunk/zsi/test/wsdl2py/ServiceTest.py 2007-08-07 22:56:37 UTC (rev 1412) @@ -83,7 +83,7 @@ except: print >>sys.stderr, 'error executing: %s' %cmd raise - time.sleep(1) + time.sleep(3) return process Modified: trunk/zsi/test/wsdl2py/servers/EchoServer.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/EchoServer.py 2007-07-31 17:41:38 UTC (rev 1411) +++ trunk/zsi/test/wsdl2py/servers/EchoServer.py 2007-08-07 22:56:37 UTC (rev 1412) @@ -4,24 +4,85 @@ # See LBNLCopyright for copyright notice! ########################################################################### import sys -from ZSI.ServiceContainer import AsServer +from ZSI import ServiceContainer, Fault +from ZSI.ServiceContainer import AsServer, ServiceSOAPBinding from EchoServer_server import EchoServer -""" -EchoServer example service +from ZSI.fault import Fault, ZSIFaultDetail +def WSDLFaultFromException(ex, inheader, tb=None, actor=None): + '''Return a Fault object created from a Python exception. -WSDL: ../../samples/Echo/Echo.wsdl + <SOAP-ENV:Fault> + <faultcode>SOAP-ENV:Server</faultcode> + <faultstring>Processing Failure</faultstring> + <detail> + <ZSI:FaultDetail> + <ZSI:string></ZSI:string> + <ZSI:trace></ZSI:trace> + </ZSI:FaultDetail> + </detail> + </SOAP-ENV:Fault> + ''' + tracetext = None + if tb: + try: + lines = '\n'.join(['%s:%d:%s' % (name, line, func) + for name, line, func, text in traceback.extract_tb(tb)]) + except: + pass + else: + tracetext = lines -""" + exceptionName = "" + try: + exceptionName = ":".join([ex.__module__, ex.__class__.__name__]) + except: pass + if isinstance(ex, Fault): + return ex + elt = ZSIFaultDetail(string=exceptionName + "\n" + str(ex), trace=tracetext) + if inheader: + detail, headerdetail = None, elt + else: + detail, headerdetail = elt, None + return Fault(Fault.Server, 'Processing Failure', + actor, detail, headerdetail) + +ServiceContainer.FaultFromException = WSDLFaultFromException + class Service(EchoServer): - def soap_Echo(self, ps): - request,response = EchoServer.soap_Echo(self, ps) + def soap_Echo(self, ps, **kw): + request,response = EchoServer.soap_Echo(self, ps, **kw) response.EchoResult = request.EchoIn + #return request,response + #raise RuntimeError, 'hi' + #raise Fault(911, "EMERGENCY", None, response) return request,response +def twisted_main(port): + from twisted.internet import reactor + from twisted.application import service, internet + from twisted.web.resource import Resource + from twisted.web.server import Site + + root = Resource() + root.putChild('test', Service()) + reactor.listenTCP(port, Site(root)) + +def main(): + port = int(sys.argv[1]) + if issubclass(EchoServer, ServiceSOAPBinding): + AsServer(port, (Service('test'),)) + return + + #from ZSI.twisted.WSresource import WSResource + #if issubclass(EchoServer, WSResource): + from twisted.internet import reactor + reactor.callWhenRunning(twisted_main, port) + reactor.run() + + if __name__ == "__main__" : - port = int(sys.argv[1]) - AsServer(port, (Service('test'),)) + main() Modified: trunk/zsi/test/wsdl2py/servers/EchoWSAddr200403Server.py =================================================================== --- trunk/zsi/test/wsdl2py/servers/EchoWSAddr200403Server.py 2007-07-31 17:41:38 UTC (rev 1411) +++ trunk/zsi/test/wsdl2py/servers/EchoWSAddr200403Server.py 2007-08-07 22:56:37 UTC (rev 1412) @@ -19,13 +19,13 @@ class WSAService(EchoServer): - def wsa_Echo(self, ps, addr): - request,response = EchoServer.wsa_Echo(self, ps, addr) + def wsa_Echo(self, ps, address): + request,response = EchoServer.wsa_Echo(self, ps, address) response.EchoResult = request.EchoIn if isinstance(response.EchoResult, EndpointReferenceType): addr1 = response.EchoResult - for a in addr.Any: + for a in address.Any: if a not in addr1.ReferenceProperties.Any: raise RuntimeError, 'EPRs dont match' Modified: trunk/zsi/test/wsdl2py/test_AWSECommerceService.py =================================================================== --- trunk/zsi/test/wsdl2py/test_AWSECommerceService.py 2007-07-31 17:41:38 UTC (rev 1411) +++ trunk/zsi/test/wsdl2py/test_AWSECommerceService.py 2007-08-07 22:56:37 UTC (rev 1412) @@ -42,7 +42,7 @@ return suite -TargetNamespace = "http://webservices.amazon.com/AWSECommerceService/2007-06-13" +TargetNamespace = 'http://webservices.amazon.com/AWSECommerceService/2007-07-16' class AmazonTestCase(ServiceTestCase): """Test case for Amazon ECommerce Web service """ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2007-10-03 18:21:39
|
Revision: 1419 http://pywebsvcs.svn.sourceforge.net/pywebsvcs/?rev=1419&view=rev Author: boverhof Date: 2007-10-03 11:21:41 -0700 (Wed, 03 Oct 2007) Log Message: ----------- M test/test_t6.py M test/test_t4.py M test/test_t5.py M setup.py M README M setup.cfg M doc/guide.tex M doc/c05-parse.tex M doc/zsi.tex M doc/c01-intro.tex M ZSI/parse.py M CHANGES Remove PyXML from ZSI. support request [ 1807097 ] Remove PyXML from ZSI Modified Paths: -------------- trunk/zsi/CHANGES trunk/zsi/README trunk/zsi/ZSI/parse.py trunk/zsi/doc/c01-intro.tex trunk/zsi/doc/c05-parse.tex trunk/zsi/doc/guide.tex trunk/zsi/doc/zsi.tex trunk/zsi/setup.cfg trunk/zsi/setup.py trunk/zsi/test/test_t4.py trunk/zsi/test/test_t5.py trunk/zsi/test/test_t6.py Modified: trunk/zsi/CHANGES =================================================================== --- trunk/zsi/CHANGES 2007-10-02 00:36:00 UTC (rev 1418) +++ trunk/zsi/CHANGES 2007-10-03 18:21:41 UTC (rev 1419) @@ -7,6 +7,7 @@ - Remove Send()'s kwargs out of _args list <ef...@bo...> Change for 2.1.0 released xxx: + - No PyXML Dependency, use minidom by default (much faster) Change for 2.0.0 released xxx: - no more wsdl2dispatch, wsdl2py does it all Modified: trunk/zsi/README =================================================================== --- trunk/zsi/README 2007-10-02 00:36:00 UTC (rev 1418) +++ trunk/zsi/README 2007-10-03 18:21:41 UTC (rev 1419) @@ -14,8 +14,8 @@ invocation methods are supported. There are no known bugs. It's only known limitation is that it cannot handle multi-dimensional arrays. -ZSI is built on top of DOM. It requires Python 2.3 or later, and PyXML -0.8.3 or later. It is open source. We hope you find it useful. +ZSI is built on top of DOM. It requires Python 2.3 or later. +It is open source. We hope you find it useful. The ZSI.twisted package will only be built if you're using Python >= 2.4, and in order to use it you'll need twisted >= 2.0 and twistedWeb >= 0.5.0 Modified: trunk/zsi/ZSI/parse.py =================================================================== --- trunk/zsi/ZSI/parse.py 2007-10-02 00:36:00 UTC (rev 1418) +++ trunk/zsi/ZSI/parse.py 2007-10-03 18:21:41 UTC (rev 1419) @@ -3,6 +3,7 @@ '''SOAP messaging parsing. ''' +from xml.dom import expatbuilder from ZSI import _copyright, _children, _attrs, _child_elements, _stringtypes, \ _backtrace, EvaluateException, ParseException, _valid_encoding, \ _Node, _find_attr, _resolve_prefix @@ -17,6 +18,11 @@ _find_root = lambda E: E.getAttributeNS(SOAP.ENC, "root") _find_id = lambda E: _find_attr(E, 'id') +class DefaultReader: + """ExpatReaderClass""" + fromString = staticmethod(expatbuilder.parseString) + fromStream = staticmethod(expatbuilder.parse) + class ParsedSoap: '''A Parsed SOAP object. Convert the text to a DOM tree and parse SOAP elements. @@ -32,7 +38,7 @@ data_elements -- list of non-root elements in the SOAP Body trailer_elements -- list of elements following the SOAP body ''' - defaultReaderClass = None + defaultReaderClass = DefaultReader def __init__(self, input, readerclass=None, keepdom=False, trailers=False, resolver=None, envelope=True, **kw): @@ -48,11 +54,8 @@ self.readerclass = readerclass self.keepdom = keepdom if not self.readerclass: - if self.defaultReaderClass != None: - self.readerclass = self.defaultReaderClass - else: - from xml.dom.ext.reader import PyExpat - self.readerclass = PyExpat.Reader + self.readerclass = self.defaultReaderClass + try: self.reader = self.readerclass() if type(input) in _stringtypes: Modified: trunk/zsi/doc/c01-intro.tex =================================================================== --- trunk/zsi/doc/c01-intro.tex 2007-10-02 00:36:00 UTC (rev 1418) +++ trunk/zsi/doc/c01-intro.tex 2007-10-03 18:21:41 UTC (rev 1419) @@ -6,7 +6,7 @@ In particular, \ZSI{} parses and generates SOAP messages, and converts between native Python datatypes and SOAP syntax. -\module{ZSI} requires Python 2.3 or later and PyXML version 0.8.3 or later. +\module{ZSI} requires Python 2.3 or later. The \module{ZSI} project is maintained at SourceForge, at \url{http://pywebsvcs.sf.net}. Modified: trunk/zsi/doc/c05-parse.tex =================================================================== --- trunk/zsi/doc/c05-parse.tex 2007-10-02 00:36:00 UTC (rev 1418) +++ trunk/zsi/doc/c05-parse.tex 2007-10-03 18:21:41 UTC (rev 1419) @@ -167,9 +167,8 @@ \ZSI{} supports multiple DOM implementations. The \code{readerclass} parameter specifies which one to use. -The default is to use the DOM provided with the PyXML package developed -by the Python XML SIG, provided through the \class{PyExpat.Reader} class -in the \module{xml.dom.ext.reader} module. +The default is to use minidom, provided through the \class{DefaultReader} class +in the \module{ZSI.parse} module. The specified reader class must support the following methods: Modified: trunk/zsi/doc/guide.tex =================================================================== --- trunk/zsi/doc/guide.tex 2007-10-02 00:36:00 UTC (rev 1418) +++ trunk/zsi/doc/guide.tex 2007-10-03 18:21:41 UTC (rev 1419) @@ -124,7 +124,7 @@ %As usage patterns emerge, and common application frameworks are %more understood, this may change. -%\ZSI{} requires Python 2.3 or later and PyXML version 0.8.3 or later. +%\ZSI{} requires Python 2.3 or later. %The \ZSI{} homepage is at \url{http://pywebsvcs.sf.net/}. Modified: trunk/zsi/doc/zsi.tex =================================================================== --- trunk/zsi/doc/zsi.tex 2007-10-02 00:36:00 UTC (rev 1418) +++ trunk/zsi/doc/zsi.tex 2007-10-03 18:21:41 UTC (rev 1419) @@ -84,7 +84,7 @@ As usage patterns emerge, and common application frameworks are more understood, this may change. -\ZSI{} requires Python 2.3 or later and PyXML version 0.8.3 or later. +\ZSI{} requires Python 2.3 or later. The \ZSI{} homepage is at \url{http://pywebsvcs.sf.net/}. Modified: trunk/zsi/setup.cfg =================================================================== --- trunk/zsi/setup.cfg 2007-10-02 00:36:00 UTC (rev 1418) +++ trunk/zsi/setup.cfg 2007-10-03 18:21:41 UTC (rev 1419) @@ -1,6 +1,6 @@ [bdist_rpm] release = 1 -requires = PyXML +requires = doc_files = README CHANGES doc/zsi.css doc/zsi.html [version] Modified: trunk/zsi/setup.py =================================================================== --- trunk/zsi/setup.py 2007-10-02 00:36:00 UTC (rev 1418) +++ trunk/zsi/setup.py 2007-10-03 18:21:41 UTC (rev 1419) @@ -43,7 +43,6 @@ 'wsdl2py = ZSI.generate.commands:wsdl2py', ], } - additional_params['install_requires'] = [ "PyXML >= 0.8.3", ] additional_params['setup_requires'] = [ "setuptools >= 0.6c3", ] additional_params['dependency_links'] = [ "http://sourceforge.net/project/showfiles.php?group_id=6473&package_id=6541&release_id=286213", Modified: trunk/zsi/test/test_t4.py =================================================================== --- trunk/zsi/test/test_t4.py 2007-10-02 00:36:00 UTC (rev 1418) +++ trunk/zsi/test/test_t4.py 2007-10-03 18:21:41 UTC (rev 1419) @@ -2,7 +2,6 @@ import unittest, sys from ZSI import * from ZSI import resolvers -from xml.dom.ext import PrettyPrint OUT = sys.stdout IN='''<SOAP-ENV:Envelope @@ -45,7 +44,7 @@ # Faulted while processing; now it's the body print >>OUT, FaultFromException(e, 0, sys.exc_info()[2]).AsSOAP() self.fail() - PrettyPrint(dict['xmltest']) + ##PrettyPrint(dict['xmltest']) print '**', dict['stringtest'], '**' def makeTestSuite(): Modified: trunk/zsi/test/test_t5.py =================================================================== --- trunk/zsi/test/test_t5.py 2007-10-02 00:36:00 UTC (rev 1418) +++ trunk/zsi/test/test_t5.py 2007-10-03 18:21:41 UTC (rev 1419) @@ -3,7 +3,10 @@ from ZSI import * from ZSI import resolvers from xml.dom import Node -from xml.dom.ext.reader import PyExpat +#from xml.dom.ext.reader import PyExpat +from ZSI.parse import DefaultReader as Reader + + try: import cStringIO as StringIO except ImportError: @@ -21,7 +24,7 @@ print 'xml=', xml.getvalue() for h,b in cid.parts: print h, b.read() - dom = PyExpat.Reader().fromStream(xml) + dom = Reader.fromStream(xml) print dom def makeTestSuite(): Modified: trunk/zsi/test/test_t6.py =================================================================== --- trunk/zsi/test/test_t6.py 2007-10-02 00:36:00 UTC (rev 1418) +++ trunk/zsi/test/test_t6.py 2007-10-03 18:21:41 UTC (rev 1419) @@ -1,7 +1,5 @@ #!/usr/bin/env python import unittest, sys, multifile, mimetools, base64 -from xml.dom import Node -from xml.dom.ext.reader import PyExpat from ZSI import * from ZSI import resolvers try: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2007-10-31 19:50:56
|
Revision: 1420 http://pywebsvcs.svn.sourceforge.net/pywebsvcs/?rev=1420&view=rev Author: boverhof Date: 2007-10-31 12:51:00 -0700 (Wed, 31 Oct 2007) Log Message: ----------- M ZSI/generate/containers.py [ 1549154 ] else block missing in wsdl2py generated code M test/wsdl2py/test_AWSECommerceService.py update TargetNamespace again Modified Paths: -------------- trunk/zsi/ZSI/generate/containers.py trunk/zsi/test/wsdl2py/test_AWSECommerceService.py Modified: trunk/zsi/ZSI/generate/containers.py =================================================================== --- trunk/zsi/ZSI/generate/containers.py 2007-10-03 18:21:41 UTC (rev 1419) +++ trunk/zsi/ZSI/generate/containers.py 2007-10-31 19:51:00 UTC (rev 1420) @@ -131,8 +131,10 @@ return formatted_attribute_list atd_list.append('# attribute handling code') - for a in attributes: - + idx = 0 + while(idx < len(attributes)): + a = attributes[idx] + idx += 1 if a.isWildCard() and a.isDeclaration(): atd_list.append(\ '%s[("%s","anyAttribute")] = ZSI.TC.AnyElement()'\ @@ -173,9 +175,8 @@ elif a.isReference() and a.isAttributeGroup(): # flatten 'em out.... for ga in a.getAttributeGroup().getAttributeContent(): - if not ga.isAttributeGroup(): - attributes += (ga,) - continue + attributes += (ga,) + elif a.isReference(): try: ga = a.getAttributeDeclaration() @@ -2573,9 +2574,6 @@ definition.append('%(ID3)sself.pyclass = %(pyclass)s' %kw) self.writeArray(definition) return - - for l in self.attrComponents: - definition.append('%s%s'%(ID3, l)) definition.append('%s' % self.getBasesLogic(ID3)) prefix = NAD.getAlias(self.sKlassNS) Modified: trunk/zsi/test/wsdl2py/test_AWSECommerceService.py =================================================================== --- trunk/zsi/test/wsdl2py/test_AWSECommerceService.py 2007-10-03 18:21:41 UTC (rev 1419) +++ trunk/zsi/test/wsdl2py/test_AWSECommerceService.py 2007-10-31 19:51:00 UTC (rev 1420) @@ -42,7 +42,8 @@ return suite -TargetNamespace = 'http://webservices.amazon.com/AWSECommerceService/2007-07-16' +TargetNamespace = 'http://webservices.amazon.com/AWSECommerceService/2007-10-29' + class AmazonTestCase(ServiceTestCase): """Test case for Amazon ECommerce Web service """ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2007-10-31 23:09:01
|
Revision: 1422 http://pywebsvcs.svn.sourceforge.net/pywebsvcs/?rev=1422&view=rev Author: boverhof Date: 2007-10-31 16:09:04 -0700 (Wed, 31 Oct 2007) Log Message: ----------- A samples/WSGI A samples/WSGI/SimpleEcho.wsdl A samples/WSGI/echo_client.py AM samples/WSGI/echo_setup.py A samples/WSGI/echo_server.py A samples/WSGI/README M ZSI/twisted/wsgi.py -- Provide a sample for using WSGI with ZSI. Modified Paths: -------------- trunk/zsi/ZSI/twisted/wsgi.py Added Paths: ----------- trunk/zsi/samples/WSGI/ trunk/zsi/samples/WSGI/README trunk/zsi/samples/WSGI/SimpleEcho.wsdl trunk/zsi/samples/WSGI/echo_client.py trunk/zsi/samples/WSGI/echo_server.py trunk/zsi/samples/WSGI/echo_setup.py Modified: trunk/zsi/ZSI/twisted/wsgi.py =================================================================== --- trunk/zsi/ZSI/twisted/wsgi.py 2007-10-31 20:40:35 UTC (rev 1421) +++ trunk/zsi/ZSI/twisted/wsgi.py 2007-10-31 23:09:04 UTC (rev 1422) @@ -3,7 +3,7 @@ # See Copyright for copyright notice! # $Id: __init__.py 1132 2006-02-17 01:55:41Z boverhof $ ########################################################################### -import os, sys, types +import os, sys, types, inspect from StringIO import StringIO # twisted & related imports @@ -37,6 +37,7 @@ def main(): from wsgiref.simple_server import make_server, demo_app + from ZSI.twisted.wsgi import WSGIApplication application = WSGIApplication() httpd = make_server('', 8000, application) application['echo'] = EchoService() @@ -91,10 +92,8 @@ request = kw['request'] root = _get_element_nsuri_name(ps.body_root) - for key,method in resource.__dict__: - if (callable(method) and - getattr(method, 'soapmethod', False) and - method.root == root): + for key,method in inspect.getmembers(resource, inspect.ismethod): + if (getattr(method, 'soapmethod', False) and method.root == root): break else: raise RuntimeError, 'Missing soap callback method for root "%s"' %root @@ -183,7 +182,7 @@ class SOAPApplication(WSGIApplication): """ """ - factory = DefaultHandlerChainFactory + factory = SOAPHandlerChainFactory def __init__(self, **kw): dict.__init__(self, **kw) Added: trunk/zsi/samples/WSGI/README =================================================================== --- trunk/zsi/samples/WSGI/README (rev 0) +++ trunk/zsi/samples/WSGI/README 2007-10-31 23:09:04 UTC (rev 1422) @@ -0,0 +1,37 @@ +================== +WSGI Code is unstable, and currently server-side stubs are NOT generated for you. + + +================== + python wsgi example + run the SimpleEcho service out of python's wsgi + +================== + +% ./echo_setup.sh +% python echo_server.py >& server.log & +[1] 3455 +% python echo_client.py +INTEGER: 1 +STRING: HI +FLOAT: 1.1 +DICT: {'milk': {'cost': 3.1499999999999999, 'unit': 'gal'}} + + +================== + twisted.web2.wsgi example + run the SimpleEcho service out of twisted's web2 wsgi + +================== +% ./echo_setup.sh +% python echo_server.py twisted >& server.log & +[1] 3459 +% python echo_client.py +INTEGER: 1 +STRING: HI +FLOAT: 1.1 +DICT: {'milk': {'cost': 3.1499999999999999, 'unit': 'gal'}} + + + + Added: trunk/zsi/samples/WSGI/SimpleEcho.wsdl =================================================================== --- trunk/zsi/samples/WSGI/SimpleEcho.wsdl (rev 0) +++ trunk/zsi/samples/WSGI/SimpleEcho.wsdl 2007-10-31 23:09:04 UTC (rev 1422) @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<definitions + xmlns="http://schemas.xmlsoap.org/wsdl/" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" + xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:tns="urn:ZSI" + targetNamespace="urn:ZSI" > + <types> + <xsd:schema elementFormDefault="qualified" targetNamespace="urn:ZSI"> + <xsd:element name="Echo"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:anyType"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + </xsd:schema> + </types> + + <message name="EchoRequest"> + <part name="parameters" element="tns:Echo" /> + </message> + <message name="EchoResponse"> + <part name="parameters" element="tns:Echo"/> + </message> + + <portType name="EchoServer"> + <operation name="Echo"> + <input message="tns:EchoRequest"/> + <output message="tns:EchoResponse"/> + </operation> + </portType> + + <binding name="EchoServer" type="tns:EchoServer"> + <soap:binding style="document" + transport="http://schemas.xmlsoap.org/soap/http"/> + <operation name="Echo"> + <soap:operation soapAction="Echo"/> + <input> + <soap:body use="literal"/> + </input> + <output> + <soap:body use="literal"/> + </output> + </operation> + </binding> + + <service name="EchoServer"> + <port name="EchoServer" binding="tns:EchoServer"> + <soap:address location="http://localhost:7000"/> + </port> + </service> + +</definitions> Added: trunk/zsi/samples/WSGI/echo_client.py =================================================================== --- trunk/zsi/samples/WSGI/echo_client.py (rev 0) +++ trunk/zsi/samples/WSGI/echo_client.py 2007-10-31 23:09:04 UTC (rev 1422) @@ -0,0 +1,28 @@ +# +# +# + +from EchoServer_client import * +import sys, time + +TRACE=None +loc = EchoServerLocator() +port = loc.getEchoServer(url='http://localhost:8000/echo', tracefile=TRACE) + +msg = EchoRequest() +msg.Value = 1 +rsp = port.Echo(msg) +print "INTEGER: ", rsp.Value + +msg.Value = "HI" +rsp = port.Echo(msg) +print "STRING: ", rsp.Value + +msg.Value = 1.10000 +rsp = port.Echo(msg) +print "FLOAT: ", rsp.Value + + +msg.Value = dict(milk=dict(cost=3.15, unit="gal")) +rsp = port.Echo(msg) +print "DICT: ", rsp.Value Added: trunk/zsi/samples/WSGI/echo_server.py =================================================================== --- trunk/zsi/samples/WSGI/echo_server.py (rev 0) +++ trunk/zsi/samples/WSGI/echo_server.py 2007-10-31 23:09:04 UTC (rev 1422) @@ -0,0 +1,43 @@ +############################################################################ +# Joshua R. Boverhof, LBNL +# See Copyright for copyright notice! +# $Id: __init__.py 1132 2006-02-17 01:55:41Z boverhof $ +########################################################################### +import sys +from EchoServer_client import * +from ZSI.twisted.wsgi import SOAPApplication, soapmethod, SOAPHandlerChainFactory + +class EchoService(SOAPApplication): + factory = SOAPHandlerChainFactory + wsdl_content = dict(name='Echo', targetNamespace='urn:echo', imports=(), portType='') + + @soapmethod(EchoRequest.typecode, EchoResponse.typecode, operation='Echo', soapaction='Echo') + def soap_Echo(self, request, response, **kw): + response = request + return request,response + + +def main(): + from wsgiref.simple_server import make_server, demo_app + from ZSI.twisted.wsgi import WSGIApplication + application = WSGIApplication() + httpd = make_server('', 8000, application) + application['echo'] = EchoService() + httpd.serve_forever() + +def main_twisted(): + from ZSI.twisted.wsgi import test, WSGIApplication + app = WSGIApplication() + app['echo'] = EchoService() + test(app, port=8000) + +if __name__ == '__main__': + if len(sys.argv) == 1: + main() + else: + var = sys.argv[1] + try: + getattr(sys.modules[__name__], 'main_%s' %var)(*sys.argv[2:]) + except Exception, ex: + print>>sys.stderr, ex + sys.exit(1) Added: trunk/zsi/samples/WSGI/echo_setup.py =================================================================== --- trunk/zsi/samples/WSGI/echo_setup.py (rev 0) +++ trunk/zsi/samples/WSGI/echo_setup.py 2007-10-31 23:09:04 UTC (rev 1422) @@ -0,0 +1,2 @@ +#!/bin/sh +wsdl2py -b SimpleEcho.wsdl Property changes on: trunk/zsi/samples/WSGI/echo_setup.py ___________________________________________________________________ Name: svn:executable + * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2007-11-01 20:33:35
|
Revision: 1423 http://pywebsvcs.svn.sourceforge.net/pywebsvcs/?rev=1423&view=rev Author: boverhof Date: 2007-11-01 13:33:33 -0700 (Thu, 01 Nov 2007) Log Message: ----------- M RELEASE M setup.py M setup.cfg M doc/Makefile M ZSI/twisted/wsgi.py M ZSI/twisted/reverse.py M ZSI/twisted/__init__.py M ZSI/twisted/WSresource.py M ZSI/twisted/interfaces.py M CHANGES M MANIFEST.in --- release stuff, moving around for WSGI stuff Modified Paths: -------------- trunk/zsi/CHANGES trunk/zsi/MANIFEST.in trunk/zsi/RELEASE trunk/zsi/ZSI/twisted/WSresource.py trunk/zsi/ZSI/twisted/__init__.py trunk/zsi/ZSI/twisted/interfaces.py trunk/zsi/ZSI/twisted/reverse.py trunk/zsi/ZSI/twisted/wsgi.py trunk/zsi/doc/Makefile trunk/zsi/setup.cfg trunk/zsi/setup.py Modified: trunk/zsi/CHANGES =================================================================== --- trunk/zsi/CHANGES 2007-10-31 23:09:04 UTC (rev 1422) +++ trunk/zsi/CHANGES 2007-11-01 20:33:33 UTC (rev 1423) @@ -6,8 +6,9 @@ - Record facets (restrictions) in XMLSchema.py <vc...@da...> - Remove Send()'s kwargs out of _args list <ef...@bo...> -Change for 2.1.0 released xxx: +Change for 2.1.0_a1 released 31-Oct-2007: - No PyXML Dependency, use minidom by default (much faster) + - samples/WSGI, server and client examples using python wsgi and twisted.web2.wsgi Change for 2.0.0 released xxx: - no more wsdl2dispatch, wsdl2py does it all Modified: trunk/zsi/MANIFEST.in =================================================================== --- trunk/zsi/MANIFEST.in 2007-10-31 23:09:04 UTC (rev 1422) +++ trunk/zsi/MANIFEST.in 2007-11-01 20:33:33 UTC (rev 1423) @@ -1,7 +1,12 @@ include CHANGES recursive-include ZSI *.py recursive-include scripts * -recursive-include doc * -recursive-include samples * +recursive-include samples WSGI recursive-include test *.py README -recursive-include interop *.py README *.wsdl + +recursive-exclude doc *.tex +recursive-exclude samples poly.py +global-exclude *.pyc +exclude RELEASE newver.py MANIFEST.in +prune samples/Echo +prune interop Modified: trunk/zsi/RELEASE =================================================================== --- trunk/zsi/RELEASE 2007-10-31 23:09:04 UTC (rev 1422) +++ trunk/zsi/RELEASE 2007-11-01 20:33:33 UTC (rev 1423) @@ -127,7 +127,7 @@ symlink to the .../Doc/tools/mkhowto script in that. If not, then you only need to check out the Doc/ tree:: - svn co http://svn.python.org/projects/python/trunk/Doc python-Do + svn co http://svn.python.org/projects/python/tags/r25/Doc python-Doc The symlink can then be made to .../someplace/tools/mkhowto. Modified: trunk/zsi/ZSI/twisted/WSresource.py =================================================================== --- trunk/zsi/ZSI/twisted/WSresource.py 2007-10-31 23:09:04 UTC (rev 1422) +++ trunk/zsi/ZSI/twisted/WSresource.py 2007-11-01 20:33:33 UTC (rev 1423) @@ -25,9 +25,44 @@ from ZSI.ServiceContainer import WSActionException from interfaces import CheckInputArgs, HandlerChainInterface, CallbackChainInterface,\ - DataHandler, DefaultHandlerChain + DataHandler +class LoggingHandlerChain: + + @CheckInputArgs(CallbackChainInterface, HandlerChainInterface) + def __init__(self, cb, *handlers): + self.handlercb = cb + self.handlers = handlers + self.debug = len(log.theLogPublisher.observers) > 0 + + def processRequest(self, arg, **kw): + debug = self.debug + if debug: log.msg('--->PROCESS REQUEST: %s' %arg, debug=1) + + for h in self.handlers: + if debug: log.msg('\t%s handler: %s' %(arg, h), debug=1) + arg = h.processRequest(arg, **kw) + + return self.handlercb.processRequest(arg, **kw) + + def processResponse(self, arg, **kw): + debug = self.debug + if debug: log.msg('===>PROCESS RESPONSE: %s' %str(arg), debug=1) + + if arg is None: + return + + for h in self.handlers: + if debug: log.msg('\t%s handler: %s' %(arg, h), debug=1) + arg = h.processResponse(arg, **kw) + + s = str(arg) + if debug: log.msg(s, debug=1) + + return s + + # # Stability: Unstable # @@ -211,7 +246,7 @@ class DefaultHandlerChainFactory: - protocol = DefaultHandlerChain + protocol = LoggingHandlerChain @classmethod def newInstance(cls): @@ -287,3 +322,39 @@ + + +class DefaultHandlerChain: + + @CheckInputArgs(CallbackChainInterface, HandlerChainInterface) + def __init__(self, cb, *handlers): + self.handlercb = cb + self.handlers = handlers + self.debug = len(log.theLogPublisher.observers) > 0 + + def processRequest(self, arg, **kw): + debug = self.debug + if debug: log.msg('--->PROCESS REQUEST: %s' %arg, debug=1) + + for h in self.handlers: + if debug: log.msg('\t%s handler: %s' %(arg, h), debug=1) + arg = h.processRequest(arg, **kw) + + return self.handlercb.processRequest(arg, **kw) + + def processResponse(self, arg, **kw): + debug = self.debug + if debug: log.msg('===>PROCESS RESPONSE: %s' %str(arg), debug=1) + + if arg is None: + return + + for h in self.handlers: + if debug: log.msg('\t%s handler: %s' %(arg, h), debug=1) + arg = h.processResponse(arg, **kw) + + s = str(arg) + if debug: log.msg(s, debug=1) + + return s + Modified: trunk/zsi/ZSI/twisted/__init__.py =================================================================== --- trunk/zsi/ZSI/twisted/__init__.py 2007-10-31 23:09:04 UTC (rev 1422) +++ trunk/zsi/ZSI/twisted/__init__.py 2007-11-01 20:33:33 UTC (rev 1423) @@ -5,4 +5,4 @@ ########################################################################### __all__=['interfaces', 'client', 'WSresource', 'WSsecurity'] -import interfaces \ No newline at end of file +import interfaces Modified: trunk/zsi/ZSI/twisted/interfaces.py =================================================================== --- trunk/zsi/ZSI/twisted/interfaces.py 2007-10-31 23:09:04 UTC (rev 1422) +++ trunk/zsi/ZSI/twisted/interfaces.py 2007-11-01 20:33:33 UTC (rev 1423) @@ -1,14 +1,13 @@ ########################################################################### # Joshua R. Boverhof, LBNL # See Copyright for copyright notice! -# $Id: WSresource.py 1287 2006-10-30 23:04:17Z feanor420 $ +# $Id: $ ########################################################################### import sys, warnings # twisted & related imports from zope.interface import classProvides, implements, Interface -from twisted.python import log # ZSI imports from ZSI import EvaluateException, ParseException, ParsedSoap, SoapWriter @@ -94,31 +93,23 @@ def __init__(self, cb, *handlers): self.handlercb = cb self.handlers = handlers - self.debug = len(log.theLogPublisher.observers) > 0 def processRequest(self, arg, **kw): - debug = self.debug - if debug: log.msg('--->PROCESS REQUEST: %s' %arg, debug=1) for h in self.handlers: - if debug: log.msg('\t%s handler: %s' %(arg, h), debug=1) arg = h.processRequest(arg, **kw) return self.handlercb.processRequest(arg, **kw) def processResponse(self, arg, **kw): - debug = self.debug - if debug: log.msg('===>PROCESS RESPONSE: %s' %str(arg), debug=1) if arg is None: return for h in self.handlers: - if debug: log.msg('\t%s handler: %s' %(arg, h), debug=1) arg = h.processResponse(arg, **kw) s = str(arg) - if debug: log.msg(s, debug=1) return s Modified: trunk/zsi/ZSI/twisted/reverse.py =================================================================== --- trunk/zsi/ZSI/twisted/reverse.py 2007-10-31 23:09:04 UTC (rev 1422) +++ trunk/zsi/ZSI/twisted/reverse.py 2007-11-01 20:33:33 UTC (rev 1423) @@ -1,5 +1,10 @@ +########################################################################### +# Joshua R. Boverhof, LBNL +# See Copyright for copyright notice! +# $Id: $ +########################################################################### from ZSI import _get_element_nsuri_name, SoapWriter, ParsedSoap -from ZSI.twisted.interfaces import HandlerChainInterface +from interfaces import HandlerChainInterface from zope.interface import classProvides, implements, Interface Modified: trunk/zsi/ZSI/twisted/wsgi.py =================================================================== --- trunk/zsi/ZSI/twisted/wsgi.py 2007-10-31 23:09:04 UTC (rev 1422) +++ trunk/zsi/ZSI/twisted/wsgi.py 2007-11-01 20:33:33 UTC (rev 1423) @@ -1,7 +1,7 @@ ############################################################################ # Joshua R. Boverhof, LBNL # See Copyright for copyright notice! -# $Id: __init__.py 1132 2006-02-17 01:55:41Z boverhof $ +# $Id: $ ########################################################################### import os, sys, types, inspect from StringIO import StringIO @@ -16,46 +16,13 @@ HandlerChainInterface """ -WSGI Module -unstable +EXAMPLES: + See zsi/samples/WSGI -EXAMPLE APPLICATION: -# -from EchoServer_client import * -from ZSI.twisted.wsgi import SOAPApplication, soapmethod, SOAPHandlerChainFactory -class EchoService(SOAPApplication): - factory = SOAPHandlerChainFactory - wsdl_content = dict(name='', targetNamespace='', imports=(), portType='') - - @soapmethod(EchoRequest.typecode, EchoResponse.typecode, operation='Echo', soapaction='Echo') - def soap_Echo(self, request, response, **kw): - response.EchoResult = request.EchoIn - return request,response - - -def main(): - from wsgiref.simple_server import make_server, demo_app - from ZSI.twisted.wsgi import WSGIApplication - application = WSGIApplication() - httpd = make_server('', 8000, application) - application['echo'] = EchoService() - httpd.serve_forever() - -def main_twisted(): - from ZSI.twisted.wsgi import test, WSGIApplication - app = WSGIApplication() - app['echo'] = EchoService() - test(app) - -if __name__ == '__main__': - main_twisted() - """ - - def soapmethod(requesttypecode, responsetypecode, soapaction='', operation=None, **kw): """@soapmethod Modified: trunk/zsi/doc/Makefile =================================================================== --- trunk/zsi/doc/Makefile 2007-10-31 23:09:04 UTC (rev 1422) +++ trunk/zsi/doc/Makefile 2007-11-01 20:33:33 UTC (rev 1423) @@ -3,7 +3,7 @@ # put the path to where the Python source was untar'd here (not where it # is installed) PYSRCDIR= /Library/Frameworks/Python.framework/Versions/2.4 -MKHOWTO= PATH=$$PATH:$(HOME)/Desktop/Python/PythonDocTools/tools/ mkhowto +MKHOWTO= PATH=$$PATH mkhowto #PAPER= a4 PAPER= letter Modified: trunk/zsi/setup.cfg =================================================================== --- trunk/zsi/setup.cfg 2007-10-31 23:09:04 UTC (rev 1422) +++ trunk/zsi/setup.cfg 2007-11-01 20:33:33 UTC (rev 1423) @@ -7,9 +7,10 @@ major = 2 minor = 1 patchlevel = 0 -#candidate = 3 candidate = 0 +alpha = 1 +beta = 0 [egg_info] -tag_build = .dev -tag_svn_revision = 1 +tag_build = +tag_svn_revision = 0 Modified: trunk/zsi/setup.py =================================================================== --- trunk/zsi/setup.py 2007-10-31 23:09:04 UTC (rev 1422) +++ trunk/zsi/setup.py 2007-11-01 20:33:33 UTC (rev 1423) @@ -17,12 +17,18 @@ minor = cf.getint('version', 'minor') patchlevel = cf.getint('version', 'patchlevel') candidate = cf.getint('version', 'candidate') +alpha = cf.getint('version', 'alpha') +beta = cf.getint('version', 'beta') _version = "%d.%d" % ( major, minor ) if patchlevel: _version += '.%d' % patchlevel if candidate: _version += '_rc%d' % candidate +elif alpha: + _version += '_a%d' % alpha +elif beta: + _version += '_b%d' % beta try: open('ZSI/version.py', 'r').close() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2007-11-01 21:06:54
|
Revision: 1424 http://pywebsvcs.svn.sourceforge.net/pywebsvcs/?rev=1424&view=rev Author: boverhof Date: 2007-11-01 14:06:59 -0700 (Thu, 01 Nov 2007) Log Message: ----------- M MANIFEST.in M Makefile -- Release stuff, new targets for kit, eggs and sdist Modified Paths: -------------- trunk/zsi/MANIFEST.in trunk/zsi/Makefile Modified: trunk/zsi/MANIFEST.in =================================================================== --- trunk/zsi/MANIFEST.in 2007-11-01 20:33:33 UTC (rev 1423) +++ trunk/zsi/MANIFEST.in 2007-11-01 21:06:59 UTC (rev 1424) @@ -3,10 +3,11 @@ recursive-include scripts * recursive-include samples WSGI recursive-include test *.py README +recursive-include doc * recursive-exclude doc *.tex recursive-exclude samples poly.py -global-exclude *.pyc +global-exclude *.pyc Makefile exclude RELEASE newver.py MANIFEST.in prune samples/Echo prune interop Modified: trunk/zsi/Makefile =================================================================== --- trunk/zsi/Makefile 2007-11-01 20:33:33 UTC (rev 1423) +++ trunk/zsi/Makefile 2007-11-01 21:06:59 UTC (rev 1424) @@ -1,7 +1,9 @@ # # Change this to point to your Python2 exectuable -PYTHON = python +PYTHON24 = python2.4 +PYTHON25 = python2.5 +PYTHON = python2.5 # This should be the Python that generated RPMs depend on and install # into; this may be different from the Python used to build the RPM. @@ -13,12 +15,20 @@ ins: soup $(PYTHON) setup.py install -kit: doc rpm # make a kit +kit: doc sdist eggs # make a kit -rpm: ZSI/version.py - rm -f dist/* - $(PYTHON) setup.py bdist_rpm --python=$(RPM_TARGET_PYTHON) +#rpm: ZSI/version.py +# rm -f dist/* +# #$(PYTHON) setup.py bdist_rpm --python=$(RPM_TARGET_PYTHON) +sdist: ZSI/version.py + rm -rf dist/* + $(PYTHON) setup.py sdist + +eggs: ZSI/version.py + $(PYTHON24) setup.py bdist_egg + $(PYTHON25) setup.py bdist_egg + doc: doc/version.tex # build the docs $(MAKE) -C doc This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2007-11-01 22:29:09
|
Revision: 1433 http://pywebsvcs.svn.sourceforge.net/pywebsvcs/?rev=1433&view=rev Author: boverhof Date: 2007-11-01 15:29:14 -0700 (Thu, 01 Nov 2007) Log Message: ----------- M RELEASE M MANIFEST.in -- update to release, need to get license in dist Modified Paths: -------------- trunk/zsi/MANIFEST.in trunk/zsi/RELEASE Modified: trunk/zsi/MANIFEST.in =================================================================== --- trunk/zsi/MANIFEST.in 2007-11-01 22:28:41 UTC (rev 1432) +++ trunk/zsi/MANIFEST.in 2007-11-01 22:29:14 UTC (rev 1433) @@ -1,8 +1,8 @@ include CHANGES -recursive-include ZSI *.py +recursive-include ZSI * recursive-include scripts * recursive-include samples WSGI -recursive-include test *.py README +recursive-include test * recursive-include doc * recursive-exclude doc *.tex Modified: trunk/zsi/RELEASE =================================================================== --- trunk/zsi/RELEASE 2007-11-01 22:28:41 UTC (rev 1432) +++ trunk/zsi/RELEASE 2007-11-01 22:29:14 UTC (rev 1433) @@ -69,9 +69,9 @@ 9. Build the release from the export. Switch to the export directory (the one containing setup.py) and run **make kit**. - Create eggs for supported python versions: + Create eggs and tarball for supported python versions: - python setup.py bdist_egg + % make kit 10. Rename the PDF documentation. If the patchlevel from setug.cfg is This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2008-01-11 00:47:11
|
Revision: 1439 http://pywebsvcs.svn.sourceforge.net/pywebsvcs/?rev=1439&view=rev Author: boverhof Date: 2008-01-10 16:47:15 -0800 (Thu, 10 Jan 2008) Log Message: ----------- M test/wsdl2py/config.txt A test/wsdl2py/wsdl/test_Unqualified.xsd A test/wsdl2py/test_Unqualified.py M ZSI/twisted/WSresource.py -- [ 1853368 ] "elementFormDefault='unqualified'" mishandled unittest for this bug, currently fails Modified Paths: -------------- trunk/zsi/ZSI/twisted/WSresource.py trunk/zsi/test/wsdl2py/config.txt Added Paths: ----------- trunk/zsi/test/wsdl2py/test_Unqualified.py trunk/zsi/test/wsdl2py/wsdl/test_Unqualified.xsd Modified: trunk/zsi/ZSI/twisted/WSresource.py =================================================================== --- trunk/zsi/ZSI/twisted/WSresource.py 2007-11-01 22:58:39 UTC (rev 1438) +++ trunk/zsi/ZSI/twisted/WSresource.py 2008-01-11 00:47:15 UTC (rev 1439) @@ -253,6 +253,41 @@ return cls.protocol(DefaultCallbackHandler, DataHandler) +class DefaultHandlerChain: + + @CheckInputArgs(CallbackChainInterface, HandlerChainInterface) + def __init__(self, cb, *handlers): + self.handlercb = cb + self.handlers = handlers + self.debug = len(log.theLogPublisher.observers) > 0 + + def processRequest(self, arg, **kw): + debug = self.debug + if debug: log.msg('--->PROCESS REQUEST: %s' %arg, debug=1) + + for h in self.handlers: + if debug: log.msg('\t%s handler: %s' %(arg, h), debug=1) + arg = h.processRequest(arg, **kw) + + return self.handlercb.processRequest(arg, **kw) + + def processResponse(self, arg, **kw): + debug = self.debug + if debug: log.msg('===>PROCESS RESPONSE: %s' %str(arg), debug=1) + + if arg is None: + return + + for h in self.handlers: + if debug: log.msg('\t%s handler: %s' %(arg, h), debug=1) + arg = h.processResponse(arg, **kw) + + s = str(arg) + if debug: log.msg(s, debug=1) + + return s + + class WSAddressHandlerChainFactory: protocol = DefaultHandlerChain @@ -321,40 +356,3 @@ return NOT_DONE_YET - - - -class DefaultHandlerChain: - - @CheckInputArgs(CallbackChainInterface, HandlerChainInterface) - def __init__(self, cb, *handlers): - self.handlercb = cb - self.handlers = handlers - self.debug = len(log.theLogPublisher.observers) > 0 - - def processRequest(self, arg, **kw): - debug = self.debug - if debug: log.msg('--->PROCESS REQUEST: %s' %arg, debug=1) - - for h in self.handlers: - if debug: log.msg('\t%s handler: %s' %(arg, h), debug=1) - arg = h.processRequest(arg, **kw) - - return self.handlercb.processRequest(arg, **kw) - - def processResponse(self, arg, **kw): - debug = self.debug - if debug: log.msg('===>PROCESS RESPONSE: %s' %str(arg), debug=1) - - if arg is None: - return - - for h in self.handlers: - if debug: log.msg('\t%s handler: %s' %(arg, h), debug=1) - arg = h.processResponse(arg, **kw) - - s = str(arg) - if debug: log.msg(s, debug=1) - - return s - Modified: trunk/zsi/test/wsdl2py/config.txt =================================================================== --- trunk/zsi/test/wsdl2py/config.txt 2007-11-01 22:58:39 UTC (rev 1438) +++ trunk/zsi/test/wsdl2py/config.txt 2008-01-11 00:47:15 UTC (rev 1439) @@ -159,6 +159,7 @@ test_DerivedTypes = wsdl/test_DerivedTypes.xsd test_SubstitutionGroup = wsdl/test_SubstitutionGroup.xsd test_WSDLImport = wsdl/test_WSDLImport.wsdl +test_Unqualified = wsdl/test_Unqualified.xsd test_SquareService = wsdl/SquareService.wsdl test_DateService = wsdl/DateService.wsdl @@ -183,5 +184,3 @@ test_NVOAdmin = wsdl/nvo-admin.wsdl test_Clearspace = http://eval.jivesoftware.com/clearspace/rpc/soap/BlogService?wsdl test_VIM = wsdl/vim.wsdl - - Added: trunk/zsi/test/wsdl2py/test_Unqualified.py =================================================================== --- trunk/zsi/test/wsdl2py/test_Unqualified.py (rev 0) +++ trunk/zsi/test/wsdl2py/test_Unqualified.py 2008-01-11 00:47:15 UTC (rev 1439) @@ -0,0 +1,101 @@ +#!/usr/bin/env python +############################################################################ +# Joshua R. Boverhof, LBNL +# See LBNLCopyright for copyright notice! +########################################################################### +import os, sys, unittest +from ServiceTest import main, ServiceTestCase, ServiceTestSuite +from ZSI import FaultException +from ZSI.TC import _get_global_element_declaration as GED +from ZSI.writer import SoapWriter + +from xml.etree import ElementTree + +""" +Unittest for Bug Report +[ 1853368 ] "elementFormDefault='unqualified'" mishandled + +WSDL: +""" + +# General targets +def dispatch(): + """Run all dispatch tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(UnqualifiedTestCase, 'test_dispatch')) + return suite + +def local(): + """Run all local tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(UnqualifiedTestCase, 'test_local')) + return suite + +def net(): + """Run all network tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(UnqualifiedTestCase, 'test_net')) + return suite + +def all(): + """Run all tests""" + suite = ServiceTestSuite() + suite.addTest(unittest.makeSuite(UnqualifiedTestCase, 'test_')) + return suite + + +class UnqualifiedTestCase(ServiceTestCase): + name = "test_Unqualified" + types_file_name = "test_Unqualified_xsd_types.py" + + def __init__(self, methodName): + ServiceTestCase.__init__(self, methodName) + self.wsdl2py_args.append('-b') + self.wsdl2py_args.append('-x') + + def test_local_serialize1(self): + _test_local_serialize1() + +def _test_local_serialize1(): + """ + <element name="GlobalElementLocalType"> + <complexType> + <sequence> + <element name="Unqualified1"> + <complexType/> + </element> + <element name="Unqualified2" type="xsd:int"/> + <element name="Unqualified3" type="tns:GlobalType"/> + </sequence> + </complexType> + </element> + """ + tns = "urn:test" + pyobj = GED(tns, "GlobalElementLocalType").pyclass() + pyobj.Unqualified1 = pyobj.new_Unqualified1() + pyobj.Unqualified2 = 2 + + pyobj.Unqualified3 = pyobj.new_Unqualified3() + pyobj.Unqualified3.Unqualified1 = pyobj.Unqualified3.new_Unqualified1() + pyobj.Unqualified3.Unqualified2 = 32 + + sw = SoapWriter(envelope=False) + sw.serialize(pyobj) + xml = str(sw) + print xml + + et = ElementTree.fromstring(xml) + + # GlobalElementLocalType + assert(et.tag == '{urn:test}GlobalElementLocalType'), "root GED" + + for i,j in zip([ 'Unqualified1', 'Unqualified2', 'Unqualified3',], + map(lambda c: c.tag, et.getchildren())): + + assert(i == j), 'Match Failed: expected "%s" not "%s"' %(i,j) + + + +if __name__ == "__main__" : + main() + Added: trunk/zsi/test/wsdl2py/wsdl/test_Unqualified.xsd =================================================================== --- trunk/zsi/test/wsdl2py/wsdl/test_Unqualified.xsd (rev 0) +++ trunk/zsi/test/wsdl2py/wsdl/test_Unqualified.xsd 2008-01-11 00:47:15 UTC (rev 1439) @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<xsd:schema targetNamespace="urn:test" + xmlns:tns="urn:test" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns="http://www.w3.org/2001/XMLSchema"> + + <element name="GlobalElementLocalType"> + <complexType> + <sequence> + <element name="Unqualified1"> + <complexType/> + </element> + <element name="Unqualified2" type="xsd:int"/> + <element name="Unqualified3" type="tns:GlobalType"/> + </sequence> + </complexType> + </element> + + <element name="GlobalElementGlobalType" type="tns:GlobalType"/> + + <complexType name="GlobalType"> + <sequence> + <element name="Unqualified1"> + <complexType/> + </element> + <element name="Unqualified2" type="xsd:int"/> + </sequence> + </complexType> + +</xsd:schema> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bov...@us...> - 2008-01-11 01:26:39
|
Revision: 1440 http://pywebsvcs.svn.sourceforge.net/pywebsvcs/?rev=1440&view=rev Author: boverhof Date: 2008-01-10 17:26:39 -0800 (Thu, 10 Jan 2008) Log Message: ----------- M test/wsdl2py/config.txt M test/wsdl2py/wsdl/test_Unqualified.xsd M test/wsdl2py/test_Unqualified.py M ZSI/generate/containers.py -- [ 1853368 ] "elementFormDefault='unqualified'" mishandled This bug caused local element declarations to be incorrectly namespaced. Appears to belimited to local element declarations with local type definitions (both simpleType and complexType), both these scenarios are fixed now with unittests. Modified Paths: -------------- trunk/zsi/ZSI/generate/containers.py trunk/zsi/test/wsdl2py/config.txt trunk/zsi/test/wsdl2py/test_Unqualified.py trunk/zsi/test/wsdl2py/wsdl/test_Unqualified.xsd Modified: trunk/zsi/ZSI/generate/containers.py =================================================================== --- trunk/zsi/ZSI/generate/containers.py 2008-01-11 00:47:15 UTC (rev 1439) +++ trunk/zsi/ZSI/generate/containers.py 2008-01-11 01:26:39 UTC (rev 1440) @@ -1984,20 +1984,27 @@ if pyclass == 'bool': pyclass = 'int' kw = KW.copy() kw.update(dict(aname=aname, ns=self.ns, name=self.name, + pname=(self.ns,self.name), substitutionGroup=self._substitutionGroupTag(), subclass=self.sKlass,literal=self.literalTag(), schema=self.schemaTag(), init=self.simpleConstructor(), klass=self.getClassName(), element="ElementDeclaration")) + # + # TODO: What does this local check do???? relevant for + # [ 1853368 ] "elementFormDefault='unqualified'" mishandled + # + if self.local: kw['element'] = 'LocalElementDeclaration' + kw['pname'] = '"%s"' %self.name element = map(lambda i: i %kw, [ '%(ID1)sclass %(klass)s(%(subclass)s, %(element)s):', '%(ID2)s%(literal)s', '%(ID2)s%(schema)s', '%(ID2)s%(init)s', - '%(ID3)skw["pname"] = ("%(ns)s","%(name)s")', + '%(ID3)skw["pname"] = %(pname)s', '%(ID3)skw["aname"] = "%(aname)s"', ] ) @@ -2053,20 +2060,27 @@ def _setContent(self): kw = KW.copy() kw.update(dict(aname=self.getAttributeName(self.name), ns=self.ns, name=self.name, + pname=(self.ns,self.name), subclass=self.sKlass,literal=self.literalTag(), schema=self.schemaTag(), init=self.simpleConstructor(), klass=self.getClassName(), element="ElementDeclaration", baseinit=self.simpleConstructor(self.sKlass))) + # + # TODO: What does this local check do???? relevant for + # [ 1853368 ] "elementFormDefault='unqualified'" mishandled + # + if self.local: kw['element'] = 'LocalElementDeclaration' + kw['pname'] = '"%s"' %self.name element = map(lambda i: i %kw, [ '%(ID1)sclass %(klass)s(%(subclass)s, %(element)s):', '%(ID2)s%(literal)s', '%(ID2)s%(schema)s', '%(ID2)s%(init)s', - '%(ID3)skw["pname"] = ("%(ns)s","%(name)s")', + '%(ID3)skw["pname"] = %(pname)s', '%(ID3)skw["aname"] = "%(aname)s"', '%(ID3)s%(baseinit)s', ] @@ -2154,6 +2168,7 @@ schema=self.schemaTag(), init=self.simpleConstructor(), ns=self.ns, name=self.name, + pname=(self.ns,self.name), aname=self.getAttributeName(self.name), nsurilogic=self.nsuriLogic(), ofwhat=self.getTypecodeList(), @@ -2167,8 +2182,14 @@ ex.args = tuple(args) raise + # + # TODO: What does this local check do???? relevant for + # [ 1853368 ] "elementFormDefault='unqualified'" mishandled + # + if self.local: kw['element'] = 'LocalElementDeclaration' + kw['pname'] = '"%s"' %self.name element = [ '%(ID1)sclass %(klass)s(%(subclass)s, %(element)s):', @@ -2177,7 +2198,7 @@ '%(ID2)s%(init)s', '%(ID3)s%(nsurilogic)s', '%(ID3)sTClist = [%(ofwhat)s]', - '%(ID3)skw["pname"] = ("%(ns)s","%(name)s")', + '%(ID3)skw["pname"] = %(pname)s', '%(ID3)skw["aname"] = "%(aname)s"', '%(ID3)s%(atypecode)s = {}', '%(ID3)sZSI.TCcompound.ComplexType.__init__(self,None,TClist,inorder=0,**kw)', @@ -2303,6 +2324,7 @@ schema=self.schemaTag(), init=self.simpleConstructor(), ns=self.ns, name=self.name, + pname=(self.ns,self.name), aname=self.getAttributeName(self.name), baseslogic=self.getBasesLogic(ID3), #ofwhat=self.getTypecodeList(), @@ -2317,9 +2339,15 @@ args += ex.args ex.args = tuple(args) raise - + + # + # TODO: What does this local check do???? relevant for + # [ 1853368 ] "elementFormDefault='unqualified'" mishandled + # + if self.local: kw['element'] = 'LocalElementDeclaration' + kw['pname'] = '"%s"' %self.name element = [ '%(ID1)sclass %(klass)s(%(element)s):', @@ -2327,7 +2355,7 @@ '%(ID2)s%(schema)s', '%(ID2)s%(substitutionGroup)s', '%(ID2)s%(init)s', - '%(ID3)skw["pname"] = ("%(ns)s","%(name)s")', + '%(ID3)skw["pname"] = %(pname)s', '%(ID3)skw["aname"] = "%(aname)s"', '%(baseslogic)s', '%(ID3)s%(alias)s.%(subclass)s.__init__(self, **kw)', Modified: trunk/zsi/test/wsdl2py/config.txt =================================================================== --- trunk/zsi/test/wsdl2py/config.txt 2008-01-11 00:47:15 UTC (rev 1439) +++ trunk/zsi/test/wsdl2py/config.txt 2008-01-11 01:26:39 UTC (rev 1440) @@ -119,7 +119,7 @@ document = True literal = True broke = False -tests = test_MapPoint test_Echo test_AWSECommerceService test_FinancialService test_BasicComm test_Manufacturer test_Racing test_Attributes test_Choice test_DerivedTypes test_EchoWSAddr200403 test_SubstitutionGroup test_VIM +tests = test_MapPoint test_Echo test_AWSECommerceService test_FinancialService test_BasicComm test_Manufacturer test_Racing test_Attributes test_Choice test_DerivedTypes test_EchoWSAddr200403 test_SubstitutionGroup test_VIM test_Unqualified [doc_literal_broke] document = True Modified: trunk/zsi/test/wsdl2py/test_Unqualified.py =================================================================== --- trunk/zsi/test/wsdl2py/test_Unqualified.py 2008-01-11 00:47:15 UTC (rev 1439) +++ trunk/zsi/test/wsdl2py/test_Unqualified.py 2008-01-11 01:26:39 UTC (rev 1440) @@ -66,6 +66,13 @@ </element> <element name="Unqualified2" type="xsd:int"/> <element name="Unqualified3" type="tns:GlobalType"/> + + <element name="Unqualified4"> + <simpleType> + <restriction base="xsd:string"/> + </simpleType> + </element> + </sequence> </complexType> </element> @@ -79,6 +86,8 @@ pyobj.Unqualified3.Unqualified1 = pyobj.Unqualified3.new_Unqualified1() pyobj.Unqualified3.Unqualified2 = 32 + pyobj.Unqualified4 = "whatever" + sw = SoapWriter(envelope=False) sw.serialize(pyobj) xml = str(sw) @@ -89,7 +98,7 @@ # GlobalElementLocalType assert(et.tag == '{urn:test}GlobalElementLocalType'), "root GED" - for i,j in zip([ 'Unqualified1', 'Unqualified2', 'Unqualified3',], + for i,j in zip([ 'Unqualified1', 'Unqualified2', 'Unqualified3', 'Unqualified4'], map(lambda c: c.tag, et.getchildren())): assert(i == j), 'Match Failed: expected "%s" not "%s"' %(i,j) Modified: trunk/zsi/test/wsdl2py/wsdl/test_Unqualified.xsd =================================================================== --- trunk/zsi/test/wsdl2py/wsdl/test_Unqualified.xsd 2008-01-11 00:47:15 UTC (rev 1439) +++ trunk/zsi/test/wsdl2py/wsdl/test_Unqualified.xsd 2008-01-11 01:26:39 UTC (rev 1440) @@ -12,6 +12,13 @@ </element> <element name="Unqualified2" type="xsd:int"/> <element name="Unqualified3" type="tns:GlobalType"/> + + <element name="Unqualified4"> + <simpleType> + <restriction base="xsd:string"/> + </simpleType> + </element> + </sequence> </complexType> </element> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |