| <!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 > 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> |