<!--
  ~ Licensed to the Apache Software Foundation (ASF) under one
  ~ or more contributor license agreements. See the NOTICE file
  ~ distributed with this work for additional information
  ~ regarding copyright ownership. The ASF licenses this file
  ~ to you under the Apache License, Version 2.0 (the
  ~ "License"); you may not use this file except in compliance
  ~ with the License. You may obtain a copy of the License at
  ~
  ~ http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing,
  ~ software distributed under the License is distributed on an
  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  ~ KIND, either express or implied. See the License for the
  ~ specific language governing permissions and limitations
  ~ under the License.
  -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<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>
