Changeset 0a47d52 for fedd/fedd_proj.py


Ignore:
Timestamp:
Jul 1, 2008 10:39:43 AM (16 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master, version-1.30, version-2.00, version-3.01, version-3.02
Children:
bb3769a
Parents:
329f61d
Message:

XMLRPC proxy from SOAP and XML

File:
1 edited

Legend:

Unmodified
Added
Removed
  • fedd/fedd_proj.py

    r329f61d r0a47d52  
    66from ZSI import *
    77from M2Crypto import SSL
     8from M2Crypto.m2xmlrpclib import SSL_Transport
    89from M2Crypto.SSL.SSLServer import SSLServer
    910import M2Crypto.httpslib
     
    1516import subprocess
    1617import tempfile
     18import copy
    1719
    1820from fedd_services import *
     
    228230        os.unlink(projfile)
    229231
    230     def proxy_request(self, dt, req):
    231         """
    232         Send req on to the real destination in dt and return the response
    233 
    234         Req is just the requestType object.  This function re-wraps it.  It
    235         also rethrows any faults.
    236         """
     232   
     233    def strip_unicode(self, obj):
     234        """Loosly de-unicode an object"""
     235        if isinstance(obj, dict):
     236            for k in obj.keys():
     237                obj[k] = self.strip_unicode(obj[k])
     238            return obj
     239        elif isinstance(obj, basestring):
     240            return str(obj)
     241        elif getattr(obj, "__iter__", None):
     242            return [ self.strip_unicode(x) for x in obj]
     243        else:
     244            return obj
     245
     246    def proxy_xmlrpc_request(self, dt, req):
     247        """Send an XMLRPC proxy request.  Called if the SOAP RPC fails"""
    237248        tc = self.proxy_trusted_certs or self.trusted_certs
    238249
     
    244255            raise Fault(Fault.Server, "Server certificates misconfigured")
    245256
     257        # Of all the dumbass things.  The XMLRPC library in use here won't
     258        # properly encode unicode strings, so we make a copy of req with the
     259        # unicode objects converted.  We also convert the destination testbed
     260        # to a basic string if it isn't one already.
     261        if isinstance(dt, str): url = dt
     262        else: url = str(dt)
     263
     264        r = copy.deepcopy(req)
     265        self.strip_unicode(r)
     266       
     267        transport = SSL_Transport(ctx)
     268        port = xmlrpclib.ServerProxy(url, transport=transport)
     269
     270        # Reconstruct the full request message
     271        try:
     272            resp = port.RequestAccess(
     273                    { "RequestAccessRequestBody": r})
     274            resp, method = xmlrpclib.loads(resp)
     275        except xmlrpclib.Error, e:
     276            raise Fault(Fault.Server, "Remote XMLRPC Fault: %s" % e)
     277       
     278        if resp[0].has_key('RequestAccessResponseBody'):
     279            return resp[0]['RequestAccessResponseBody']
     280        else:
     281            raise Fault(Fault.Server, "Bad proxy response")
     282
     283    def proxy_request(self, dt, req):
     284        """
     285        Send req on to the real destination in dt and return the response
     286
     287        Req is just the requestType object.  This function re-wraps it.  It
     288        also rethrows any faults.
     289        """
     290        tc = self.proxy_trusted_certs or self.trusted_certs
     291
     292        # No retry loop here.  Proxy servers must correctly authenticate
     293        # themselves without help
     294        try:
     295            ctx = fedd_ssl_context(self.cert_file, tc, password=self.cert_pwd)
     296        except SSL.SSLError:
     297            raise Fault(Fault.Server, "Server certificates misconfigured")
     298
    246299        loc = feddServiceLocator();
    247300        port = loc.getfeddPortType(dt,
     
    255308        try:
    256309            resp = port.RequestAccess(msg)
     310        except ZSI.ParseException, e:
     311            raise Fault(Fault.Server, "Bad format message (XMLRPC??): %s" %
     312                    str(e))
    257313        except ZSI.FaultException, e:
    258314            raise e.fault
     
    423479            dt = unpack_id(req['destinationTestbed'])
    424480       
    425         print dt
    426 
    427481        if dt == None or dt == self.testbed:
    428482            # Request for this fedd
     
    454508            return resp
    455509        else:
    456             # Proxy the request
    457             return self.proxy_request(dt, req)
     510            p_fault = None      # Any SOAP failure (sent unless XMLRPC works)
     511            try:
     512                # Proxy the request using SOAP
     513                return self.proxy_request(dt, req)
     514            except Fault, f:
     515                p_fault = f
     516         
     517           
     518            # This runs if SOAP failed
     519            try:
     520                return self.proxy_xmlrpc_request(dt, req)
     521            except Fault:
     522                # Both failed, return the SOAP error.  If somehow that
     523                # exception is gone, return the XMLRPC one
     524                if p_fault != None: raise p_fault
     525                else: raise
    458526
    459527    def soap_RequestAccess(self, ps, fid):
Note: See TracChangeset for help on using the changeset viewer.