Introduction

This is advanced level documentation for those who wish to understand the details of the interactions with an InstantSOAP service at the underlying SOAP level. In general, there is no need to use code at this low a level.

Preparation

Firstly, you should ensure that the echotest application is installed as described in the Getting Started documentation. The instructions in this document assume that it is running on the local machine (http://localhost:8080 )

Next, we need a miminal client to interact with the InstantSOAP application. Compile the following Java class:

import java.net.*;
import java.io.*;




public class RawClient
{

    public static void main( String[] args ) throws Exception{
        
        InputStream in = new BufferedInputStream
            ( new FileInputStream( new File( args [ 0 ] ) ) );
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        
        int b;
        while( (b = in.read()) != -1 ){
            bout.write( b );
        }
        processRequest( bout.toByteArray() );
        
    }
    
    public static void processRequest( byte[] b ) throws Exception{

        
        URL url = new URL("http://localhost:8080/instantsoap-ws-echotest-1.0/services/instantsoap/applications");
    
        // prepare the connection, with headers and such like. 
        URLConnection connection = url.openConnection();
        HttpURLConnection httpConn = (HttpURLConnection) connection;
    
        httpConn.setRequestProperty( "Content-Length",
                                     String.valueOf( b.length ) );
        httpConn.setRequestProperty("Content-Type","text/xml; charset=utf-8");
        httpConn.setRequestProperty("SOAPAction", "" );
        httpConn.setRequestMethod( "POST" );
        httpConn.setDoOutput(true);
        httpConn.setDoInput(true);

        // dump the request to the server
        OutputStream out = httpConn.getOutputStream();
        out.write( b );    
        out.close();

        
        // read the results and dump to screen. 
        BufferedReader in = new BufferedReader
            ( new InputStreamReader
              ( httpConn.getInputStream() ) );


        String inputLine;

        while ((inputLine = in.readLine()) != null)
            System.out.println(inputLine);
    
        in.close();
    }


}

This class performs an HTTP POST request against the InstantSOAP service.

Invoking Methods

By default all InstantSOAP services have identical service interfaces, which use parameters to perform their different functions. One of the these methods listApplications returns the list of all applications. Save the following XML into a file called "listApplications.xml" in the same directory as RawClient.class, and then run RawClient with the following command: java RawClient listApplications.xml.

<soapenv:Envelope 
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:wsap="http://wsapi.instantsoap.cs.ncl.ac.uk/">
  <soapenv:Header/>
  <soapenv:Body>
    <wsap:listApplications/>
  </soapenv:Body>
</soapenv:Envelope>

The listApplications method has a single function. It returns the response shown below. Hidden within the message, you should see the applications available. It is shown more clearly below.

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ns3:listApplicationsResponse 
      xmlns:ns2="http://cs.ncl.ac.uk/instantsoap/service" 
      xmlns:ns3="http://wsapi.instantsoap.cs.ncl.ac.uk/">
      <applications>echoBook</applications>
      <applications>stringEcho</applications>
      <applications>echoMap</applications>
      <applications>cat</applications>
    </ns3:listApplicationsResponse>
  </soap:Body>
</soap:Envelope>

The describeApplications method provides information about the functionality of the method. In this case, it is parameterised by the name of one of the applications discovered by listApplications. The request and response are shown below, in this case investigating the echoMap application.

<soapenv:Envelope 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:wsap="http://wsapi.instantsoap.cs.ncl.ac.uk/">
   <soapenv:Header/>
   <soapenv:Body>
      <wsap:describeApplication>
         <arg0>echoMap</arg0>
      </wsap:describeApplication>
   </soapenv:Body>
</soapenv:Envelope>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns3:describeApplicationResponse 
          xmlns:ns2="http://cs.ncl.ac.uk/instantsoap/service" 
          xmlns:ns3="http://wsapi.instantsoap.cs.ncl.ac.uk/">
         <description>
            <description>Echo all inputs to outputs</description>
            <name>echoMap</name>
         </description>
      </ns3:describeApplicationResponse>
   </soap:Body>
</soap:Envelope>

The getInputs method provides information about the kinds of inputs that are expected. As before, it is parameterised for an individual service. The request and response are shown below. In this case, two inputs are expected, one called "age" and one called "name".

<soapenv:Envelope 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:wsap="http://wsapi.instantsoap.cs.ncl.ac.uk/">
   <soapenv:Header/>
   <soapenv:Body>
      <wsap:getInputs>
         <arg0>echoMap</arg0>
      </wsap:getInputs>
   </soapenv:Body>
</soapenv:Envelope>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns3:getInputsResponse 
          xmlns:ns2="http://cs.ncl.ac.uk/instantsoap/service" 
          xmlns:ns3="http://wsapi.instantsoap.cs.ncl.ac.uk/">
         <inputs>
            <description>your age (in years</description>
            <name>age</name>
         </inputs>
         <inputs>
            <description>your name</description>
            <name>name</name>
         </inputs>
      </ns3:getInputsResponse>
   </soap:Body>
</soap:Envelope>

Finally, we shall invoke the service, in this case using invokeAndBlock. This is the simpler of the methods as it does not involve passing an input and then polling for a response. Long running processes are liable to time-out however. In this case, the name of the author and an lie about his age are passed; the response is just echoed back.

<soapenv:Envelope 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:wsap="http://wsapi.instantsoap.cs.ncl.ac.uk/">
  <soapenv:Header/>
  <soapenv:Body>
    <wsap:invokeAndBlock>
      <jobSpecification>
        <application>echoMap</application>
        <inputs>
          <entry>
            <key>name</key>
            <value>Phil</value>
          </entry>
          <entry>
            <key>age</key>
            <value>21</value>
          </entry>
        </inputs>
      </jobSpecification>
    </wsap:invokeAndBlock>
  </soapenv:Body>
</soapenv:Envelope>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns3:invokeAndBlockResponse 
          xmlns:ns2="http://cs.ncl.ac.uk/instantsoap/service" 
          xmlns:ns3="http://wsapi.instantsoap.cs.ncl.ac.uk/">
         <blockedInvocationResponse>
            <results>
               <entry>
                  <key>name</key>
                  <value>Phil</value>
               </entry>
               <entry>
                  <key>age</key>
                  <value>21</value>
               </entry>
            </results>
            <uuid>12c4fdce-655e-45ff-a1cd-3370e21231a5</uuid>
         </blockedInvocationResponse>
      </ns3:invokeAndBlockResponse>
   </soap:Body>
</soap:Envelope>

Conclusion

While this would not be a generally recommended approach for invoking InstantSOAP services, it is relatively simple and straight-forward. In practice, once the client knows the details of the service, only the last method, invokeAndBlock would be needed. This low-level code is also freely translatable into most other languages and has few dependencies.