Forum Discussion

Michel_van_der_'s avatar
Michel_van_der_
Icon for Nimbostratus rankNimbostratus
Nov 01, 2005

Debug tools for XML SOAP messages

I'm struggling a bit with some of the more complex call to iControl using perl and SOAP::Lite. At times I want

 

to look at the XML messages and see if they are compliant with the API. I'm using 'tidy -xml -indent' which is

 

not great. Any other tools I may want to use?

 

 

Michel
  • Loc_Pham_101863's avatar
    Loc_Pham_101863
    Historic F5 Account
    You can set iControl.loglevel to "trace" to see the actual incoming SOAP/XML messages in /var/log/ltm.

     

     

    Alternatively, you can also use something like TCPTrace to look at the XML payloads.

     

    Loc
  • The easiest way is to use the built-in tracing features in SOAP::Lite. At the top of each sample application is the following module declaration for SOAP::Lite

    use SOAP::Lite + trace => qw(method debug);
    use SOAP::Lite;

    Switch those comments around and all the XML traffic will be spit out to the console

    use SOAP::Lite + trace => qw(method debug);
    use SOAP::Lite;

    Alternately, you can use a client proxy trace utility (I use tcptrace personally) but you will need to enable clear text HTTP on your BIG-IP admin port for it to work. Not advisable for a production system.

    -Joe
  • What I'm getting back is an error from iControl.cgi, so

    I'm looking at the trace data to see what the SOAP XML looks

    like. But off course that something like this:

                       xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
                       xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                       xmlns:xsd="http://www.w3.org/1999/XMLSchema"
                       SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      
        
                SOAP-ENC:arrayType="SOAP-ENC:Array[1]">
                    SOAP-ENC:arrayType="xsd:ur-type[2]">
              SnatAutoMap
                        SOAP-ENC:arrayType="xsd:ur-type[2]">
                SNAT_TYPE_AUTOMAP
                
              
            
          
                SOAP-ENC:arrayType="SOAP-ENC:Array[1]">
                    SOAP-ENC:arrayType="xsd:string[1]">
              0.0.0.0
            
          
                SOAP-ENC:arrayType="SOAP-ENC:Array[1]">
                    SOAP-ENC:arrayType="xsd:ur-type[0]" />
          
        
      

    I'd like to turn that into something more readable, given I'm

    no SOAP expert. I.e. I would think that if I could compare

    the XML with the API, I'd see what I'm doing wrong...

  • I don't know of any tool out there that will convert the SOAP message back into readable format. I'm sure you could do it with a XSLT style sheet but I don't know of one that exists.

     

     

    Here's how I interpret the code when debugging.

     

     

    Here is the method signature for LocalLB::SNAT::create():

     

     

    
    struct Translation {
        SnatType type;
        String translation_object;
    };
    struct SNATDefinition {
        String name;
        Translation target;
    };
    struct SNATOriginalAddress {
        String original_address;
        String wildmask;
    };
    struct VLANFilterList {
        EnabledState state;
        String []vlans;
    };
    void LocalLB::SNAT::create(
        in SNATDefinition[] snats,
        in SNATOriginalAddress[][] original_addresses,
        in VLANFilterList[] vlans
    );

     

     

    First, let's look and make sure the namespace and method are correct

     

     

                       xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
                       xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                       xmlns:xsd="http://www.w3.org/1999/XMLSchema"
                       SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      
        create xmlns:namesp2="urn:iControl:LocalLB/SNAT">

     

     

    Looks like this is going to iControl:LocalLB/SNATcreate which is what we want.

     

     

    Next look at the parameters.

     

     

    The first parameter is a 1-D SNATDefinition array named stats. What looks odd here is that item 1 (type SNATDefinition) in the array is declared as an array of size 2 but it doesn't have any items in it. It does have the correct members (type and translation_object) but translation_object you have defined as null which will likely cause you problems. You should at declare these as empty strings, not nulls.

     

     

          
            
              SnatAutoMap
              
                SNAT_TYPE_AUTOMAP
                
              
            
          

     

     

    Now, on to parameter 2 which is of type SNATOriginalAddress[][] named original_addresses. Your code declares it as a single dimensional array with a single item which will cause problems. You'll need to declare this as a 2-D array. The first dimension references the associated entry in the snats variable and the second dimension is a list of original addresses for that snat.

     

     

          
            
              0.0.0.0
            
          

     

     

    Lastly, parameter 3 is of type VLANFilterList[] named vlans. You passed in an array of size 0 which is ok as long as don't want to add any VLANs to be filtered.

     

     

          
            
          

     

     

        
      

     

     

    I wish debugging the perl interfaces was easier but the dynamic nature of perl can sometimes be it's downside as well.

     

     

    Good luck!

     

     

    -Joe
  • Loc_Pham_101863's avatar
    Loc_Pham_101863
    Historic F5 Account
    Also, if you're writing a Perl client, make sure you have the correct typecasts for the SnatType enumeration, or any enum for that matter. Was the error you saw something about the SnatType? If so, that's likely the reason. You can use the iControlTypeCast.pm module from the SDK to get around this.

     

     

    Loc
  • Thanks for your help, but off course I was trying to avoid exactly

     

    what happened there. I did not really want you to debug the code, it's just that trying to get SOAP::Lite to do what I want is a

     

    struggle... You're right some sort of XSLT makes sense,

     

    I'll look around.

     

     

    BTW, it's not necessarily perl, but really, the SOAP:Lite module.

     

    Powerful but completely opaque IMHO.

     

     

  • There actually is a wsdl parser in the SOAP::Lite distribution but it is somewhat limited and only seems to work for simple method calls (no arrays, structures, etc).

     

     

    -Joe
  • Well, I tried something like that, but I kept getting 500 errors back. However, I think that was because iControl was not happy with the undef I had originally. So, let me go back and code it like you did, which I agree is much more elegant.

     

     

    BTW, I spent a fair bit of time with the SOAP::Lite serializer and it is clear that's not an easy nut to crack!

     

     

    As an aside, it may be worthwhile to add an example like that to the SDK. I don't think I saw an example of a 'complex structure' call using perl, but I may have missed it.

     

     

    Michel
  • Could you elaborate on how to 'set iControl.loglevel to "trace"'? Is this a line that goes into bigip.conf or another config file?

     

     

    Alternatively, how do I configure the iControl portal to run on port 80 so I can just trace it with a proxy (this is a dev system only so no security worries)?

     

     

    Thanks,

     

    Keith
  • Loc_Pham_101863's avatar
    Loc_Pham_101863
    Historic F5 Account
    To set iControl log level:

     

     

    b db icontrol.loglevel none|debug|trace

     

    bigstart restart httpd

     

     

    If you're on 9.2, you might have to check /etc/syslog-ng/syslog-ng.conf, look at local4 to make sure it has debug. If you changed this file, make sure to HUP syslogd to make the new config take effect.

     

     

    To make Apache run on port 80: (disclaimer: do NOT do this unless you're sure of what you're doing, and this is NOT for a production system)

     

     

     

    - Edit /config/httpd/conf/httpd.conf

     

    - Change the "Listen" directive to just "Listen 80"

     

    - bigstart restart httpd

     

     

    Regards,

     

    Loc