<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta http-equiv="content-type" content="">
  <title>Invoking a service using mail</title>
  <link href="../css/axis-docs.css" rel="stylesheet" type="text/css"
  media="all">
</head>

<body>
<h1>Invoking a Service Using a Mail Transport</h1>

<p>This document explains how to invoke a service through Mail transports.</p>

<p><i>Send your feedback or questions to: <a
href="mailto:axis-dev@ws.apache.org?subject=[Axis2]">axis-dev@ws.apache.org</a></i>.
(Subscription details are available on the <a
href="http://ws.apache.org/axis2/mail-lists.html">Axis2 site</a>.) Kindly
prefix subject with [Axis2].</p>

<h2>Content</h2>
<ul>
  <li><a href="#prologue">Prologue</a></li>
  <li><a href="#intro">Introduction</a></li>
  <li><a href="#axis2">Using Simple Mail Server Included in Axis2</a></li>
  <li><a href="#generic">Using a Generic Mail Server</a></li>
  <!--li><a href="#mailet">Calling Axis Through a James Mailet</a></li-->
</ul>
<a name="prologue"></a>

<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 instance a chain of stores.
At the end of the day, all the stores can send a mail to the central system
telling it about that day's business activities, and when the store opens in
the morning, there will be a reply to that mail with new instructions and
updates. It is a lot like the way old businesses worked, but with a modern
touch. Similarly, the Axis2 mail transport can be used to implement
asynchronous messaging through mail.</p>
<a name="intro"></a>

<h2>Introduction</h2>

<p>First, you need to go through the <a href="mail-configuration.html"
target="_blank">Mail Transport Configuration</a> document. It provides first
hand experience in setting up the mail transports to operate with Axis2.</p>

<p>Broadly speaking, there are three ways of calling a service through
mail.</p>

<blockquote>
  1. Using the simple mail server included in Axis2 (not recommended in
  production).<br>
  2. Using a generic mail server.<br>
  3. Using mailets.<br>
</blockquote>

<p>Options 1 and 2 are fairly simple and easy to implement, whereas option 3
is somewhat harder. The mailet scenario however does provide a more robust
and useful solution in a production environment.</p>

<p>It is very easy to start learning the workings of mail transports with the
aid of the Simple Mail Server that is provided with Axis2. Once you get the
hang of Axis2 related issues, then you can move on to tackle the mail beast.
Please do note that the Simple Mail Server provided with Axis2 is not graded
for production use.</p>
<a name="axis2"></a>

<h2>1. Using the Simple Mail Server Included in Axis2</h2>

<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, we can use the code below to get
the mail functionality started. 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 polling 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();

        private QName serviceName = new QName("EchoXMLService");
        private QName operationName = new QName("echoOMElement");
    
        // Setup a service that will echo what we send to the server.
        AxisService service = Utils.createSimpleService(serviceName, Echo.class
                .getName(), operationName);
        serverConfigContext.getAxisConfiguration().addService(service);</pre>
</source>
<p>This code sets up your Axis2 server which uses a single service to work
through the mail. If you want to have a look under the hood, check out the
MailServer and UtilsMailServer classes.</p>

<p>Moving onto the client side, have a look at the code listing below. It
will call the axisService that was setup in the previous code listing.</p>
<source><pre>        ConfigurationContext configContext = UtilsMailServer
                .createClientConfigurationContext();
        AxisService service = new AxisService(serviceName.getLocalPart());
        AxisOperation axisOperation = new OutInAxisOperation();
        axisOperation.setName(operationName);
        axisOperation.setMessageReceiver(new MessageReceiver() {
            public void receive(MessageContext messageCtx) {
                envelope = messageCtx.getEnvelope();
            }
        });
        service.addOperation(axisOperation);
        configContext.getAxisConfiguration().addService(service);
        ServiceContext serviceContext = new ServiceGroupContext(configContext,
                        (AxisServiceGroup) service.getParent()).getServiceContext(service);

        Options options = new Options();
        options.setTo(targetEPR);
        options.setAction(operationName.getLocalPart());
        options.setTransportInProtocol(Constants.TRANSPORT_MAIL);
        options.setUseSeparateListener(true);

        Callback callback = new Callback() {
            public void onComplete(AsyncResult result) {
                try {
                    result.getResponseEnvelope().serializeAndConsume(
                            XMLOutputFactory.newInstance()
                                    .createXMLStreamWriter(System.out));
                } catch (XMLStreamException e) {
                    onError(e);
                } finally {
                    finish = true;
                }
            }

            public void onError(Exception e) {
                log.info(e.getMessage());
                finish = true;
            }
        };

        ServiceClient sender = new ServiceClient(configContext, service);
        sender.setOptions(options);
        //options.setTo(targetEPR);
        sender.sendReceiveNonBlocking(operationName, createEnvelope(), callback);

        int index = 0;
        while (!finish) {
            Thread.sleep(1000);
            index++;
            if (index &gt; 10) {
                throw new AxisFault(
                        "Server was shutdown as the async response is taking too long to complete.");
            }
        }

    }</pre>
</source>
<p>This will call the service that was setup on the server, and will poll the
mail server until the response is received. Please note that the serviceName
and operationName need to be QNames.</p>
<a name="generic"></a>

<h2>2. Using a Generic Mail Server</h2>

<p>First you will need two email accounts that work 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 using the Mail Transport <a
href="mail-configuration.html" target="_blank">configuration document</a>.</p>

<p>When you call 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 configContext = configContextbuilder
                .buildConfigurationContext(file.getAbsolutePath());

        // 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();

        private QName serviceName = new QName("EchoXMLService");
        private QName operationName = new QName("echoOMElement");
    
        // Setup a service that will echo what we send to the server.
        AxisService service = Utils.createSimpleService(serviceName, Echo.class
                .getName(), operationName);
        serverConfigContext.getAxisConfiguration().addService(service);</pre>
</source>
<p>Note that a separate ConfigurationContext needs to be created and used.</p>

<h2>Resources</h2>

<p>For more information on Mail client invocation, see
AXIS2_HOME\samples\userguide\src\userguide\clients\MailClient.java</p>
<!--a name="mailet"></a>

<h3>3. Calling Axis2 Through a Mailet</h3-->

<p></p>
</body>
</html>
