Changeset f8582c9 for fedd/fedd_util.py


Ignore:
Timestamp:
Nov 18, 2008 8:32:05 PM (15 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:
dab4d56
Parents:
fd729b9
Message:

Resource allocation and deallocation really working
Access handler selects allocation ID
Fedid allocation IDs work
Revamp of util code for maodifying messages (e.g. binaries)
Handlers now see fedids as objects in messages
Fedid bug in handlers in fedd_util

This should have been multiple commits

File:
1 edited

Legend:

Unmodified
Added
Removed
  • fedd/fedd_util.py

    rfd729b9 rf8582c9  
    192192        if attr: obj = attr()
    193193        else:
    194             print dir(container)
    195194            raise TypeError("%s does not have a new_%s attribute" % \
    196195                    (container, name))
     
    233232    else:
    234233        return element
     234def apply_to_tags(e, map):
     235    """
     236    Map is an iterable of ordered pairs (tuples) that map a key to a function.
     237    This function walks the given message and replaces any object with a key in
     238    the map with the result of applying that function to the object.
     239    """
     240    dict_type = type(dict())
     241    list_type = type(list())
     242    str_type = type(str())
     243
     244    if isinstance(e, dict_type):
     245        for k in e.keys():
     246            for tag, fcn in map:
     247                if k == tag:
     248                    if isinstance(e[k], list_type):
     249                        e[k] = [ fcn(b) for b in e[k]]
     250                    else:
     251                        e[k] = fcn(e[k])
     252                elif isinstance(e[k], dict_type):
     253                    apply_to_tags(e[k], map)
     254                elif isinstance(e[k], list_type):
     255                    for ee in e[k]:
     256                        apply_to_tags(ee, map)
     257    # Other types end the recursion - they should be leaves
     258    return e
     259
     260# These are all just specializations of apply_to_tags
     261def fedids_to_obj(e, tags=('fedid',)):
     262    """
     263    Turn the fedids in a message that are encoded as bitstrings into fedid
     264    objects.
     265    """
     266    map = [ (t, lambda x: fedid(bits=x)) for t in tags]
     267    return apply_to_tags(e, map)
    235268
    236269def encapsulate_binaries(e, tags):
    237270    """Walk through a message and encapsulate any dictionary entries in
    238271    tags into a binary object."""
    239     dict_type = type(dict())
    240     list_type = type(list())
    241     str_type = type(str())
    242 
    243     if isinstance(e, dict_type):
    244         for k in e.keys():
    245             if k in tags:
    246                 if isinstance(e[k], list_type):
    247                     bin_list = []
    248                     for ee in e[k]:
    249                         if getattr(ee, 'pack_xmlrpc', None):
    250                             bin_list.append(Binary(ee.pack_xmlrpc()))
    251                         else:
    252                             bin_list.append(Binary(ee))
    253                     e[k] = bin_list
    254                 elif getattr(e[k],'pack_xmlrpc', None):
    255                     e[k] = Binary(e[k].pack_xmlrpc())
    256                 else:
    257                     e[k] = Binary(e[k])
    258             elif isinstance(e[k], dict_type):
    259                 encapsulate_binaries(e[k], tags)
    260             elif isinstance(e[k], list_type):
    261                 for ee in e[k]:
    262                     encapsulate_binaries(ee, tags)
    263     # Other types end the recursion - they should be leaves
    264     return e
     272
     273    def to_binary(o):
     274        pack = getattr(o, 'pack_xmlrpc', None)
     275        if callable(pack): return Binary(pack())
     276        else: return Binary(o)
     277
     278    map = [ (t, to_binary) for t in tags]
     279    return apply_to_tags(e, map)
    265280
    266281def decapsulate_binaries(e, tags):
    267282    """Walk through a message and encapsulate any dictionary entries in
    268283    tags into a binary object."""
    269     dict_type = type(dict())
    270     list_type = type(list())
    271     str_type = type(str())
    272 
    273     if isinstance(e, dict_type):
    274         for k in e.keys():
    275             if k in tags:
    276                 if isinstance(e[k], list_type):
    277                     e[k] = [ b.data for b in e[k]]
    278                 else:
    279                     e[k] = e[k].data
    280             elif isinstance(e[k], dict_type):
    281                 decapsulate_binaries(e[k], tags)
    282             elif isinstance(e[k], list_type):
    283                 for ee in e[k]:
    284                     decapsulate_binaries(ee, tags)
    285     # Other types end the recursion - they should be leaves
    286     return e
    287 
     284
     285    map = [ (t, lambda x: x.data) for t in tags]
     286    return apply_to_tags(e, map)
     287#end of tag specializations
    288288
    289289def strip_unicode(obj):
     
    318318    Create a new certificate and derive a fedid from it.
    319319
    320     The fedid and the certificte are returned as a tuple.
     320    The fedid and the certificate are returned as a tuple.
    321321    """
    322322
     
    340340            if trace: call_out = trace
    341341            else:
    342                 log.debug("set to dev/null")
    343342                call_out = open("/dev/null", "w")
    344343
     
    382381        req = ps.Parse(typecode)
    383382
    384         msg = method(unpack_soap(req), fedid)
     383        msg = method(fedids_to_obj(unpack_soap(req)), fid)
    385384
    386385        resp = constructor()
     
    397396    return handler
    398397
    399 def make_xmlrpc_handler(method, body_name, input_binaries=('fedid',),
    400         output_binaries=('fedid',)):
     398def make_xmlrpc_handler(method, body_name):
    401399    """
    402400    Generate the handler code to unpack and pack SOAP requests and responses
     
    405403    The code to marshall and unmarshall XMLRPC parameters to and from a fedd
    406404    service is largely the same.  This helper creates such a handler.  The
    407     parameters are the method name, the name of the body struct that contains
    408     the response asn the list of fields that are encoded as Binary objects in
    409     the input and in the output.  A handler is created that takes the params
    410     response from an xm,lrpclib.loads on the incoming rpc and a fedid and
    411     responds with a hash representing the struct ro be returned to the other
    412     side.  On error None is returned.
     405    parameters are the method name, and the name of the body struct that
     406    contains the response.  A handler is created that takes the params response
     407    from an xmlrpclib.loads on the incoming rpc and a fedid and responds with
     408    a hash representing the struct ro be returned to the other side.  On error
     409    None is returned.  Fedid fields are decapsulated from binary and converted
     410    to fedid objects on input and encapsulated as Binaries on output.
    413411    """
    414412    def handler(params, fid):
    415         p = decapsulate_binaries(params[0], input_binaries)
    416         msg = method(p, fedid)
     413        decap_fedids = (('fedid', lambda x: fedid(bits=x.data)),)
     414
     415        #p = decapsulate_binaries(params[0], input_binaries)
     416        p = apply_to_tags(params[0], decap_fedids)
     417        msg = method(p, fid)
    417418
    418419        if msg != None:
    419             return encapsulate_binaries({ body_name: msg }, output_binaries)
     420            return encapsulate_binaries({ body_name: msg }, ('fedid',))
    420421        else:
    421422            return None
Note: See TracChangeset for help on using the changeset viewer.