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.

Tuesday, September 16, 2008

Running WSO2 WSAS on WebLogic

WSO2 WSAS can be used not only as a standalone application but also as an web application for a servlet container. Many people find latter very useful since that let them run the WSO2 WSAS within their favorite Servlet Container along with the other applications.

I recently had some experiments with the WebLogic server using the 10 Minute Guide to Installing WSO2 WSAS on WebLogic Tutorial written by Afkham Azzez. Every thing worked fine in the installation process.

Then I tried to do more experiments with some WSO2 Mercury samples. By doing this I found that the response messages are not serialized properly. Further looking into that I found when running on Weblogic Axiom uses the underline stax implementation of the WebLogic and that causes some problems of serializing the namespaces and namespace prefixes.

This made me surprised since Axiom supposed to work with any stax implementation. Then I looked into the Axiom serialization logic and found that it works on two different ways.

  1. For some stax implementations it first writes the prefix for a new namespace

  2. For some stax implementations it writes the prefix after start Element

For wstx (default for Axis2) and sun stax implementations it works on the later mode and that has done by specifying these names at the serializing logic. I specified the weblogic also as a later mode implementation and that made every thing worked fine.

I have made these changes already to Axiom and any one having problems working in weblogic can try with Axiom nightly builds.