Monday, September 29, 2008

Using WS-commons mail transport with Axis2

Axis2 and Synapse (an ESB which uses Axis2) were using separate set of codes for transports while keeping them in Axis2 and Synapse code repositories. Recently we moved then into a common place under the ws_commons project called transports. As a result of this now Axis2 uses the mail transport which was originally there with the Synapse and have removed its own mail transport.
Compared to earlier Axis2 mail transport Synapse mail transport configure a mail box parameters per service and do not use ?x-service-path to specify the service.

I recently had some tests with this transport and here is how this mail transport can be used with Axis2 for inonly and inout message operations.

First here is how to use it with a in only operation.
For in only operations we need to set the mail message receiver at the server (for service) and sender at the client. To configure the mail message receiver at server side first it is required to declare the Mail transport receiver at the Axis2 xml file and it should be looked like this,

<transportReceiver name="mailto" class="org.apache.axis2.transport.mail.MailTransportListener">

</transportReceiver>



Note that there are no parameters specified here as in with the previous Axis2 mail transports. then where we specify them? it should be done at services.xml as entry per service.

<service name="TestInService">
<description>Test In Service</description>
<parameter name="transport.mail.Address">mail address to listen</parameter>
<parameter name="transport.mail.Protocol">pop3</parameter>
<parameter name="transport.PollInterval">2</parameter>
<parameter name="mail.pop3.host">pop3 mail account</parameter>
<parameter name="mail.pop3.user">username</parameter>
<parameter name="mail.pop3.password">password</parameter>
<messageReceivers>
<messageReceiver
mep="http://www.w3.org/2004/08/wsdl/in-only"
class="com.test.transports.service.TestInOnlyMessageReceiver"/>
</messageReceivers>
<operation name="TestInOperation" mep="http://www.w3.org/ns/wsdl/in-only">
<actionMapping>urn:TestInOperation</actionMapping>
</operation>
</service>

These are the only steps to follow to mail transport at server side.
At the client side we need to first declare a mail sender.

<transportSender name="mailto"
class="org.apache.axis2.transport.mail.MailTransportSender">
<parameter name="mail.smtp.from">from address this is added to from header</parameter>
<parameter name="mail.smtp.user">user name</parameter>
<parameter name="mail.smtp.password">password</parameter>
<parameter name="mail.smtp.host">smtp host</parameter>
</transportSender>

Sender configuration is almost similar to earlier Axis2 sender configuration. Now we can use this code to send the message using mail transport.


ConfigurationContext configurationContext =
ConfigurationContextFactory.createConfigurationContextFromFileSystem(
AXIS2_REPOSITORY_LOCATION, AXIS2_CLIENT_CONFIG_FILE);
ServiceClient serviceClient = new ServiceClient(configurationContext, null);
serviceClient.setTargetEPR(new EndpointReference("mailto:test@wso2.com"));
serviceClient.getOptions().setAction("urn:TestInOperation");
serviceClient.fireAndForget(getTestOMElement("org"));


Note here that it is enough to specify the email address of the server. Since there is a particular receiver for this service, it will pick the message from there.

Now lets see how we can use mail transport for an inout operation. The smtp transport does not have an implicit back channel. Therefore response should come as a separate mail message. The request message will go to the server as in the inonly scenario. So now lets see how to configure to receive the response message.
First a mail sender should be configured at the Axis2 xml in the server side as given above. So that the server can send the response using this transport sender. Server picks the sending address either using WSA reply to header if given or SMTP reply to header.
To configure the receiver at the client side first we need to add the mail transport receiver at the client Axis2 xml file as given above. Then the there is a question of how to set the other parameters since there is no any services.xml file at the client side. Actually mail transport receiver gets these parameters from the Axis2 service and hence we can set them at the client code itself like this.

ConfigurationContext configurationContext =
ConfigurationContextFactory.createConfigurationContextFromFileSystem(
AXIS2_REPOSITORY_LOCATION, AXIS2_CLIENT_CONFIG_FILE);
ServiceClient serviceClient = new ServiceClient(configurationContext, null);
serviceClient.setTargetEPR(new EndpointReference("mailto:oiositest2@wso2.com"));
serviceClient.getOptions().setAction("urn:TestInOutOperation");

// these two lines are needed only if it is required to use addressing
serviceClient.getOptions().setUseSeparateListener(true);
serviceClient.engageModule("addressing");

serviceClient.getAxisService().addParameter("transport.mail.Address","test@wso2.com");
serviceClient.getAxisService().addParameter("transport.mail.Protocol","pop3");
serviceClient.getAxisService().addParameter("transport.PollInterval","2");
serviceClient.getAxisService().addParameter("mail.pop3.host","pop 3 address");
serviceClient.getAxisService().addParameter("mail.pop3.user","username");
serviceClient.getAxisService().addParameter("mail.pop3.password",”password");

OMElement result = serviceClient.sendReceive(getTestOMElement("org"));
System.out.println("Result ==> " + result);

There will be a separate listener for the given mail address and that receives the response.

No comments: