<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <title>Invoking a service using
a mail</title>
</head>
<body>
<h1>Invoking
a service using a mail</h1>
<h2>Prologue</h2>
<p>Most of the web services that we
interact with are synchronous and request-response in nature. However,
we see that the synchronous request-response type of interaction is
only a part of the messaging scenarios we encounter in real life.
Asynchronous messaging is very important in constructing loosely
coupled systems. Take for an instance a chain of stores, at the end of
the day all the stores all over can send a mail to the central system
telling it what that days business activity was and in the morning when
the store opens there will be a reply to that mail with new
instructions and updates. It is a lot like the way the old business
worked but with a modern touch. Similarly Axis2 mail transport can be
used to implement SETI@HOME through mail.</p>
<h2>Introduction</h2>
<p>To get things started you will
first need to go through the Mail Transport <a
 href="mail-configuration.html">configuration document</a>. It will give you all
the information you need about how to configure Axis2 to get the mail
transport working.</p>
<p>Broadly speaking there are 3
ways of calling a service through mail.
</p>
<blockquote>1. Using the simple
mail server included in Axis2.<br>
2. Using a generic mail server.<br>
3. Using mailets.<br>
</blockquote>
<p></p>
<p>Option number 1 and 2 are
fairly simple and easy to implement, whereas option 3 is somewhat
harder [unless of course you are one of those guys who see mails going
around in your dreams.]. However the mailet scenario provides a more robust and useful
solution in a production environment.</p>
<p>If you are not a guru in mail
related issues you should probably get started on the simple mail server
that has been provided with Axis2. Once you get the hang of the Axis2
related issues then you can move onto tackle the mail beast. Please do
keep in mind that the mail server we have implemented is ONLY FOR
DEMONSTRATION/TESTING PURPOSES.</p>
<h3>1. Using the simple mail
server included in Axis2</h3>
<p>Before we start I want to
reiterate the fact that the mail server included with Axis2 is ONLY FOR
DEMONSTRATION/TESTING PURPOSES.</p>
<p>The SMTP/POP server that we
have included has the ability to function as a standalone SMTP/POP
server and also has the ability to work as a mailet. All this is done
through a small filter that keeps watch for certain pre-configured
email addresses. These pre-configured email addresses can be changed by
doing a simple edit of the filter class
org.apache.axis2.transport.mail.server.Sorter.</p>
<p>Now that we have the
environment set up, let us start pumping out some code to get the mail
functionality off the ground. First we'll have a look at it from the
mail server side. <br>
</p>
<source><pre>
        // Start the mail server using the default configurations.
        ConfigurationContext configContext = UtilsMailServer.start();

        // Start the default mail listener. It will starting poling for mail
        // using the configuration from the XML file.
        SimpleMailListener ml = new SimpleMailListener();
        ml.init(configContext, configContext.getAxisConfiguration()
                .getTransportIn(new QName(Constants.TRANSPORT_MAIL)));
        ml.start();

        // Setup a service that will echo what we send to the server.
        ServiceDescription service = Utils.createSimpleService(serviceName,
                Echo.class.getName(), new QName("echoOMElement"));
        configContext.getAxisConfiguration().addService(service);
        Utils.resolvePhases(configContext.getAxisConfiguration(), service);
        ServiceContext serviceContext = configContext
                .createServiceContext(new QName("EchoXMLService"));
</pre></source>
<p>This code sets up your Axis2
server working through mail, with a single service. If you need to
have a look under the hood have a look at the MailServer and
UtilsMailServer classes.</p>
<p>Moving onto the client side
have a look at the code listing below. It will call the service that
was setup on the previous code listing.</p>
<source><pre>
        ConfigurationContext configContext = UtilsMailServer
                .createClientConfigurationContext();
        ServiceDescription service = new ServiceDescription(serviceName);
        OperationDescription operation = new OperationDescription(operationName);
        operation.setMessageReceiver(new MessageReceiver() {
                public void receive(MessageContext messgeCtx) throws AxisFault {
                        envelope = messgeCtx.getEnvelope();
                }
        });
        service.addOperation(operation);
        configContext.getAxisConfiguration().addService(service);
        Utils.resolvePhases(configContext.getAxisConfiguration(), service);
        ServiceContext serviceContext = configContext
                .createServiceContext(serviceName);
        org.apache.axis2.clientapi.Call call = new org.apache.axis2.clientapi.Call(
                serviceContext);
        call.setTo(targetEPR);
        call.setTransportInfo(Constants.TRANSPORT_MAIL,
                Constants.TRANSPORT_MAIL, true);
        // Create a callback to set to the service invocation.
        Callback callback = new Callback() {
                public void onComplete(AsyncResult result) {
                        try {
                                result.getResponseEnvelope().serialize(
                                        XMLOutputFactory.newInstance()
                                                .createXMLStreamWriter(System.out));
                        } catch (XMLStreamException e) {
                                reportError(e);
                        } finally {
                                finish = true;
                        }
                }
                public void reportError(Exception e) {
                        log.info(e.getMessage());
                        finish = true;
                }
         };

        // Call the service and start poling for the reply from the server.
        call.invokeNonBlocking(operationName.getLocalPart(), createEnvelope(),
                callback);
        int index = 0;
        while (!finish) {
                Thread.sleep(1000);
                index++;
                if (index &gt; 10) {
                        throw new AxisFault(
                                "Server is being shutdown as the Async response is taking too long.");
                }
        }
        call.close();
</pre></source>
<p>This will call the service that
was setup on the server and will poll the mail server till the response
is received. Well that is all there is to it.</p>
<p></p>
<h3>2. Using a generic mail server</h3>
<p>First you need two email
accounts that works with POP/SMTP. One will act as a server and the
other will act as the client. For the time being we will use
server@somewhere.org and client@somewhere.org as the server and the
client email addresses. Now that we have the email addresses you will
have to set up the client and the server looking at the Mail Transport <a
 href="http://ws.apache.org/axis2/mail-transport.html">introduction
document</a>.</p>
<p>When calling the generic mail
server the client side code will remain the same and there will be some
modification to the server-side code.</p>
<p>
</p>
<source><pre>
        // Create a configuration context. This will also load the details about the mail
        // address to listen to from the configuration file.
        File file = new File(MAIL_TRANSPORT_SERVER_ENABLED_REPO_PATH);
        ConfigurationContextFactory builder = new ConfigurationContextFactory();
        ConfigurationContext configContextbuilder
                .buildConfigurationContext(file.getAbsolutePath());

        // Startup the default mail server and start listening to a 
        // mail address.
        SimpleMailListener ml = new SimpleMailListener();
        ml.init(configContext, configContext.getAxisConfiguration()
                .getTransportIn(new QName(Constants.TRANSPORT_MAIL)));
        ml.start();

        // Setup a simple service.
        ServiceDescription service = Utils.createSimpleService(serviceName,
                Echo.class.getName(), operationName);
        configContext.getAxisConfiguration().addService(service);
        Utils.resolvePhases(configContext.getAxisConfiguration(), service);
        ServiceContext serviceContext = configContext.createServiceContext(serviceName);
</pre></source>
<p>We have to create a separate ConfigurationContext and then use that. We are done; wasn't that simple?</p>
<h3>3. Calling Axis through a
James mailet</h3>
<p>This process will be a bit more
challenging than the other two methods but will provide a really
elegant way to use the mail transport. Before we get started you will
have to go though the James documents <a
 href="http://james.apache.org/custom_matcher_2_1.html">Writing
a Custom Matcher</a> and <a
 href="http://james.apache.org/custom_mailet_2_1.html">Writing
a Custom Mailet</a>.</p>
<p>Now that we know the James part of it lets dive into to the Axis2 part of the code. Once you have set up the James side of business we just need to use the same functionality that is used in the above code. Have a look at the code listing below for more details</p>
<source><pre>
    public void processMail(ConfigurationContext confContext, MimeMessage mimeMessage) {
        // create an Axis server
        AxisEngine engine = new AxisEngine(confContext);
        MessageContext msgContext = null;
        // create and initialize a message context
        try {
            // Create a message context with mail as in and out transports.
            msgContext =
                    new MessageContext(confContext,
                            confContext.getAxisConfiguration().getTransportIn(new QName(Constants.TRANSPORT_MAIL)),
                            confContext.getAxisConfiguration().getTransportOut(new QName(Constants.TRANSPORT_MAIL)));
            msgContext.setServerSide(true);

            msgContext.setProperty(MailConstants.CONTENT_TYPE, mimeMessage.getContentType());
            msgContext.setWSAAction(getMailHeader(MailConstants.HEADER_SOAP_ACTION, mimeMessage));

            // The service path is in the subject of the mail.
            String serviceURL = mimeMessage.getSubject();
            if (serviceURL == null) {
                serviceURL = "";
            }

            String replyTo = ((InternetAddress) mimeMessage.getReplyTo()[0]).getAddress();
            if (replyTo != null) {
                msgContext.setReplyTo(new EndpointReference(replyTo));
            }

            String recipients = ((InternetAddress) mimeMessage.getAllRecipients()[0]).getAddress();

            if (recipients != null) {
                msgContext.setTo(new EndpointReference(recipients + "/" + serviceURL));
            }

            // add the SOAPEnvelope
            String message = mimeMessage.getContent().toString();
            ByteArrayInputStream bais = new ByteArrayInputStream(message.getBytes());
            XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(bais);

            // This is just in place to work with SOAP 1.1 and 1.2.
            String soapNamespaceURI = "";
            if (mimeMessage.getContentType().indexOf(SOAP12Constants.SOAP_12_CONTENT_TYPE) > -1) {
                soapNamespaceURI = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
            } else if (mimeMessage.getContentType().indexOf(SOAP11Constants.SOAP_11_CONTENT_TYPE) > -1) {
                soapNamespaceURI = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;

            }
            StAXBuilder builder = new StAXSOAPModelBuilder(reader, soapNamespaceURI);

            SOAPEnvelope envelope = (SOAPEnvelope) builder.getDocumentElement();
            msgContext.setEnvelope(envelope);
            if (envelope.getBody().hasFault()) {
                engine.receiveFault(msgContext);
            } else {
                engine.receive(msgContext);
            }
        } catch (Exception e) {
            try {
                if (msgContext != null) {
                    MessageContext faultContext = engine.createFaultMessageContext(msgContext, e);
                    engine.sendFault(faultContext);
                }
            } catch (Exception e1) {
                log.error(e);
            }
        }
    }
</pre>
</source>
<p>If you don't happen to have a ConfigurationContext lying around to call this method you can use the following bit of code to get one. Once you create one you can store that on the mailet and keep using it.
</p>
<source><pre>
        File file = new File(MAIL_TRANSPORT_SERVER_ENABLED_REPO_PATH);
        ConfigurationContextFactory builder = new ConfigurationContextFactory();
        ConfigurationContext configContextbuilder
                .buildConfigurationContext(file.getAbsolutePath());
</pre>
</source>
<p>Well that seems to be all from the wonderful world of mail for now. :)</p>
</body>
</html>
