Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

mod_python, ZSI and wsdl2py generated code

Helmut S.
2009-03-09
2013-05-02
  • Helmut S.
    Helmut S.
    2009-03-09

    Hello all,

    new to this board, I've a question anyway. :)

    Since several days I try to figure out how to use wsdl2py-generated server code in mod_python.
    Environment is:
    Server: Apache/2.2.8 (Ubuntu) mod_python/3.3.1 Python/2.5.2 PHP/5.2.4-2ubuntu5 with Suhosin-Patch
    ZSI: debian package python-zsi 2.1~a1-2 (from lenny)

    I'm using a WSDL file which defines several complex types, with instances of them being used either as operation input and output messages. The standalone server and client work well, even if communicating with their gSoap C++ counterparts (I use gSoap to check for inter-language compatibility as well).

    With mod_python integration I've been successful enough to be able to call a very simple service method (only atomic input and output messages), using a hand-written dispatcher consisting of code I've duplicated and adapted from 'dispatch.py' and 'ServiceContainer.py'. This code uses either SOAPAction to determine the operation name (which, as far as I get, is all but a desirable strategy), or the name of the soap body toplevel element, and probably is all but fool-proof, but is all I could figure out so far (well, at least a bit of API documentation would be a great thing here ... it's really no fun to dig through code full of super-dynamic on-the-fly method creation and shtuff).

    When I try to make the service method send back complex type instances however, I run into a strange problem: the factory and accessor methods for complex types, available in the standalone server environment, are missing in the mod_python environment. As far as I understand, these methods are usually being created on the fly in the Holder-classes of the element declaration descriptors. Why does that step obviously not happen, if mod_python is used?
    Btw., my workaround to this problem failed miserably just at the first step, as I was not able to figure out how to create instances of the suitable complex types by hand (heck, where is the description how to achieve such a trivial task with ZSI?!? It can't really be the idea one has to read the ZSI source to find out how, can it? ;) ). I assumend it could just be a 'xyz_instance = nsW.XYZ_Dec()', but this did throw nothing but an exception.

    Here is the mod_python handler function containing the dispatch code:
    [code]
    def SendXML(req, text, code=200, **kw):
        req.content_type = 'text/xml'
        req.content_length = len(text)
        req.send_http_header()
        req.write(text)

    def SendFault(req, f, **kw):
        SendXML(req, f.AsSOAP(), 500, **kw)

    def handler(req):
        service = gws()
        ps = ParsedSoap(req)
        try:
            #
            # Determine action:
            # - check, if header has SOAPAction field set, and value is
            #   not empty.
            # - second option: get the soap body element name, and use that one
            # Not implemented: wsAction-based dispatch.
            #
            if req.headers_in.has_key('SOAPAction_'):
                action = req.headers_in['SOAPAction'].strip('\'"')
                action = service.soapAction[action]
            else:
                ns = str(ps.body_root.namespaceURI)
                what = str(ps.body_root.localName)
                action = service.root[(ns,what)]
            try:
                method = getattr(service,action)
            except Exception, e:
                raise TypeError("Unknown method " + action)
            if not callable(method):
                raise TypeError("Unimplemented method " + action)
        except Exception, e:
            raise e
            #SendFault(req,FaultFromException(e, 0, sys.exc_info()[2]))
            #return apache.OK
        request,result = method(ps)
       
           # If No response just return.
        if result is None:
            SendXML(req,'')
            return apache.OK
        sw = SoapWriter()
        try:
            sw.serialize(result)
        except Exception, e:
            SendFault(req,FaultFromException(e, 0, sys.exc_info()[2]))
            return apache.OK
        try:
            soapdata = str(sw)
            SendXML(req,soapdata,request=req)
            return apache.OK
        except Exception, e:
            SendFault(req,FaultFromException(e, 0, sys.exc_info()[2]))
            return apache.OK

    [/code]

    So, summarizing my questions:
    1) What is the current state of ZSI/mod_python interoperability?
    2) How should dispatch be done properly in that environment?
    3) Why are the accessor- and factory methods for complex types unavailable in the mod_python environment?
    4) How does one create complex type instances by hand?

    Regards, and thanks a lot in advance!
    Helmut

     
    • Helmut S.
      Helmut S.
      2009-03-09

      PS.: Ah, my apologies for posting that unformatted mess. My newbie guess was I could use bbcode to paste preformatted code. :(

       
    • Helmut S.
      Helmut S.
      2009-03-11

      Good grief ... it seems all I wrote is crap.
      This evening, I restarted apache, and since then, it works. I'm such a moron ...

      I've cleaned the code (the SOAPAction shtuff went away ...). It now looks rather simple, and seems to do what it ought to do, at least concerning my two test cases.

      http://www.thalion-graphics.de/download/modpy_dispatch.py

      Am I on the right path here?

      Best Regards,
      Helmut