Making Apache SOAP Invocations using SMTP

Making Apache SOAP Invocations using SMTP

Jonathan Chawke, 9th March 2001.

Introduction

This document provides an explanation of:
  1. How Apache provides it's SMTP transport for SOAP
  2. How to set up Apache SOAP on a server so that it can service requests via SMTP.
  3. How to write a client that makes a SOAP invocation using e-mail (a combination of SMTP and POP).

Assumptions

This document assumes that you have already installed Apache SOAP [http://xml.apache.org/soap/index.html] onto a Tomcat [http://jakarta.apache.org/tomcat/index.html] 3.2 JSP/Servlet container.
Before attempting to service SMTP SOAP messages, ensure that your installation is correctly configured for HTTP SOAP (i.e. the SOAP sample applications work over HTTP!).

SOAP Over SMTP

SOAP: a Transport-independent Protocol

The writers of the SOAP 1.1 protocol [http://www.w3.org/TR/SOAP/] note that: 'SOAP can potentially be used in combination with a variety of other protocols; however, the only bindings defined in this document describe how to use SOAP in combination with HTTP and HTTP Extension Framework'.
One of the nice things about SOAP is that it isn't restricted to a particular transport layer. Most - if not all - implementations are currently using HTTP to transport SOAP messages, but there is no reason why you can’t use other layers, such as SMTP.

Apache SOAP Provides an SMTP Transport

The Apache SOAP distribution includes classes which permit the servicing of SOAP requests using e-mail. It does this using a combination of SMTP [http://www.freesoft.org/CIE/RFC/821/] and POP [http://www.freesoft.org/CIE/RFC/1725/]. A class called SMTP2HTTPBridge must be running in a separate JVM on the server. As the name suggests, this class operates as a bridge, mapping requests between HTTP and SMTP. Strictly speaking, this is not an independent SMTP transport - what it really does is convert e-mail SOAP messages to and from HTTP SOAP messages.

Running the Apache SOAP SMTP Bridge (Server)

  1. Ensure that the machine you are using is running POP3 and SMTP services (or can access another machine that provides them). Note that the scripts shown below assume that a POP3 service is running locally.
  2. Download the POP3 and SMTP jar files from the Apache SOAP web site (currently they are here: http://www.apache.org/dyn/closer.cgi/ws/soap/). Note that these are IBM (and not Sun) jars, and they are also available from IBM at http://www.alphaworks.ibm.com/ab.nsf/techreqs/SMTP and http://www.alphaworks.ibm.com/ab.nsf/techreqs/POP3, respectively. The SMTP bridge software uses these classes to send and receive e-mail messages.
  3. Ensure that the POP3 and SMTP jar files (pop3.jar and smtp.jar) are included in your classpath.
  4. Create a new account (e.g. soaprouter) under which the SOAP bridge will execute. This makes life easier in the long term, and avoids filling your mail box with loads of XML messages!
  5. The Apache SOAP distribution includes a class that maps requests between HTTP and SMTP. Login to the new account and launch this Java class - it’s called org.apache.soap.server.SMTP2HTTPBridge. Don’t forget to include the pop3.jar and smtp.jar in your classpath or it won’t work! A sample (Unix) shell script to launch the class is provided here:
  6. #!/bin/sh
    
    #
    # Launch Apache SOAP SMTP Bridge
    #
    
    # classpath to use for soap smtp
    SOAPCP="/usr/local/jakarta/jars/xerces.jar:/usr/local/jakarta/jars/soap.jar"
    # add mail libs that the bridge requires
    SOAPCP="/usr/local/jakarta/soap/lib/pop3.jar:/usr/local/jakarta/soap/lib/smtp.jar:$SOAPCP"
    
     
    # Usage: java org.apache.soap.server.SMTP2HTTPBridge polldelay \
    #                 pop3host pop3login pop3passwd httpurl smtphostname
    #    polldelay    number of millisec to sleep between polls
    #    pop3host     hostname of the POP3 server
    #    pop3login    login ID of POP3 account
    #    pop3passwd   POP3 account password
    #    routerURL    http URL of SOAP router to bridge to
    #    smtphostname SMTP server host name
    
    polldelay=30000    # run every 30 seconds (for testing)
    pop3host=localhost # assume pop3 server is running on local host
    pop3login=$USER    # assume we are running in a dedicated soap bridge account
    pop3passwd=secret  # pop3 password for soap bridge goes here
    #  soap server url goes here (we assume its local)
    routerURL=http://localhost:8080/soap/servlet/rpcrouter
    smtphostname=yourmailserver    # your outgoing mail server's name goes here
    
    # run the bridge! echo Running the SOAP Bridge using classpath: $SOAPCP java -classpath $SOAPCP org.apache.soap.server.SMTP2HTTPBridge $polldelay $pop3host $pop3login $pop3passwd $routerURL $smtphostname
  7. If all goes well, you should (periodically) see something like this:
  8. SMTP2HTTPBridge: Polling for messages ..
    Status update:  Contacting host: localhost...
    Status update: Host contacted, sending login information..
    Status update: No new messages on server.
     

Running an Apache SOAP Client using SMTP

  1. Setup a new e-mail account on a server that provides a POP3 service. This account will be used to retrieve responses to SOAP requests. You could use an existing e-mail account, but it’s probably better to use a dedicated account.
  2. Find an existing SOAP client that makes invocations over HTTP, and make a copy of the code. We’ll modify the client to use SMTP instead of HTTP.
  3. The first modification is the transport; instead of using the ‘standard’ HTTP transport (org.apache.soap.transport.SOAPHTTPConnection), we need to use an SMTP one.
  4. We need a number of new parameters so that we can (i) send our SOAP request to the appropriate location as an e-mail message and (ii) check our e-mail account for a response to our request:
  5. // name of out-going mailserver
    String smtpserver = "outgoingmailserver";	
    String popserver = "popservername";	// name of incoming mail server
    // pop account to use for From field and to check for response 
    String poplogin = "soapresponse";   
    String poppasswd = "secret";		// password
    String fromaddress = poplogin + "@" + popserver;
    			
    SOAPTransport ss = new org.apache.soap.transport.smtp.SOAPSMTPConnection(
    			/* from/replyto address */ fromaddress,
    			/* subject */ "SOAP SMTP Request (TEST)",
    			/* smtpServer */ smtpserver,
    			/* popPollDelay in millis */ 30000,
    			/* popServer */ popserver,
    			/* popLogin */ poplogin,
    			/* popPassword */ poppasswd
    );
    
  6. The next modification we make is to the URL that is used for the request. Instead of creating a http:// URL, we create a mailto: URL (warning: the mailto: protocol handler is not directly supported by the Microsoft Java SDK - you need some classes that are in Sun’s JDK). The address used in the URL should be the name of the account used by the SOAP SMTP bridge application (e.g. the soaprouter account described in the previous section):
  7. 	URL url = new URL("mailto:soaprouter@soapserver.yourdomain.com");	
  8. Setup a new call and tell it to use our SMTP transport instead of HTTP:
	// build the call
	org.apache.soap.rpc.Call call = new Call();
	call.setSOAPTransport(ss);	// use smtp transport instead of http
The rest of the SMTP SOAP client code should be the same as HTTP SOAP client code. Note that there is a sample application called GetQuoteSMTP.java in samples/stockquote which demonstrates a SOAP SMTP client.

Further Information

SOAP

Post Office Protocol (POP)