Soap

Discussion in 'OT Technology' started by Peyomp, May 27, 2006.

  1. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    Anyone ever written web services using SOAP?

    I've played around with this lately, using perl and SOAP::Lite, and XML::XPath and DBI (god bless the CPAN), and I've got a working client and server that accepts XML through soap, parses it and logs it to MySQL. Its about 50 lines of code. I've still got to create working clients in Java, C++ and .NET and then add teh logic and stuff. I might do WSDL, and I might not.

    Anyone monkied with SOAP? I thought about creating a simple REST protocol, but perl's SOAP libraries were so simple that I went with that.
     
  2. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    I got the Java client working last night using the Apache Java SOAP library. Had to download xerces.jar, mail.jar and activate.jar, but once I did it worked like a charm.

    Now I've got to get a C++ version working. I'll be using gSOAP to generate the client code from a .h file I hand make, as gSOAP generates the a header file from a WSDL and client code from a header file... but I'm not fucking with WSDL right now.

    Some people have said, "Why are you encapsulating XML in SOAP? Why not just use a socket?" Well, the answer is that it is much simpler to instantiate a SOAP object residing on an Apache web server via https and then call sendPacket() than to mess with sockets and OpenSSL. Compared to doing that, sending SOAP packets with an xml datatype is very, very easy.

    SOAP is neat. It is very, very slow on my iBook G4 800mhz, with MySQL, Apache, perl and Java and the SOAP libs running at the same time just to test a client but... speed should be acceptable on a server. And there are things I can do to optimize speed.
     
  3. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    So, I used gSOAP to generate a C++ client library but... I didn't get it to run cause... I don't know C++ and it pissed me off and I started having flashbacks about spending all day chasing through library after library to find out what is wrong and forgetting a type mid-way through diving into a library and having to back step and start over from the beginning of the trace like 4 times in a row until I got it.

    I hate C.
     
  4. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    Behold the power of perl:

    PHP:
    #!/usr/bin/perl

    use SOAP::Lite;
    use 
    SOAP::Transport::HTTP;
    use 
    XML::XPath;
    use 
    XML::XPath::XMLParser;
    use 
    DBI;
    use 
    DBD::mysql;

    SOAP::Transport::HTTP::CGI   
        
    -> dispatch_to('SOAPServer')     
        -> 
    handle;

    package SOAPServer;

    my %AcmeInfo = (      Origin => '',    
                    
    Time_Stamp => '',
                    
    SeqNumber => '',
                );
                    

    sub readPacket {
           
    shift# object/class reference
        
    my $packet SOAP::Data->name('packet' => shift())->type('xml');

        
    # Read the XML packet in to our XPath thingie    
        
    my $xpath XML::XPath->newxml => $packet->value );

        
    # Now fill out out AcmeInfo hash
        
    $AcmeInfo{'Origin'} = $xpath->findvalue("/AcmeInfo/AcmeHeader/Origin");
           
    $AcmeInfo{'Time_Stamp'} = $xpath->findvalue("/AcmeInfo/AcmeHeader/Time_Stamp");
           
    $AcmeInfo{'SeqNumber'} = $xpath->findvalue("/AcmeInfo/AcmeRCMsg/SeqNumber");
           
      ....

                                         
          
    # Now send it to the database... this needs to be done in another object or something, it can't be initialized every time.                               
         # database information
        
    my $db="acme";
        
    my $host="localhost";
        
    my $port="3306";
        
    my $userid="hooker";
        
    my $passwd="";
        
    my $connectionInfo="DBI:mysql:database=$db;$host:$port";

        
    # make connection to database
        
    my $dbh DBI->connect($connectionInfo,$userid,$passwd)
            or die 
    "Cannot connect to database: $connectionInfo$db because:" $DBI::errstr;

        
    # Prepare and execure our insert for this packet
        
    my $insert_handle $dbh->prepare_cached('INSERT INTO PacketLog VALUES (?,?,?,?,?,?,?,?,?,?)'); 
        
    $insert_handle->execute(values(%AcmeInfo)) or return 0;

        
    # Finish up the query. 
         
    $insert_handle->finish();
        
        
    # disconnect from database
        
    $dbh->disconnect;    
        
        
        
    # Now lets send back a AcmeAck response
        
    my $responseXML "<AcmeAck><Acmeblah>FUCK_JOO!</Acmeblah></AcmeAck>          
        return 
    $responseXML;
    }
     
  5. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    Behold the verbosity of a Java client:

    PHP:
    package OffTopic;

    import java.net.URL;
    import java.util.Vector;
    import org.apache.soap.Fault;
    import org.apache.soap.Constants;
    import org.apache.soap.rpc.Call;
    import org.apache.soap.rpc.Parameter;
    import org.apache.soap.rpc.Response;

    public class 
    testClient {
       public static 
    void main(String[ ] argsthrows Exception {
     
          
    // For simplicity, hard code the URL.
          
    URL url 
           new 
    URL("http://127.0.0.1/cgi-bin/SOAPServer.cgi");

          
    // Set up the RPC.
          
    Call call = new Call();
          
    call.setTargetObjectURI("http://127.0.0.1/SOAPServer");
          
    call.setMethodName("readPacket");
          
    call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
          
    String c = new String("<AcmeInfo><AcmeBlah>blah lbah</AcmeBlah></AcmeInfo>");

          
    Vector params = new Vector();
          
    params.addElement(new Parameter("c"String.class, c
                                          
    Constants.NS_URI_SOAP_ENC)); 
          
    call.setParams(params);

          
    // Invoke and get response.
          
    Response resp call.invoke(url"");
          if (
    resp.generatedFault()) {
            
    Fault fault resp.getFault ();
            
    System.out.println("Code:  " fault.getFaultCode() +
                               
    "Error: " fault.getFaultString());
          }
          else {
            
    Parameter converted resp.getReturnValue();
            
    System.out.println(converted.getValue());
          }
       }
    }

     

Share This Page