Showing posts with label Axis2. Show all posts
Showing posts with label Axis2. Show all posts

Saturday, February 16, 2013

How to connect WSO2 ESB to Apache ActiveMQ using simple authentication

There are different types of pluggable authentication mechanisms provided by Apache ActiveMQ message broker. One of the quickest and easiest mechanisms is to use simple authentication. As the name implies, it is as simple as adding authentication details to ACTIVEMQ_HOME/conf/activemq-security.xml


 <plugins>
<!-- Configure authentication; Username, passwords and groups -->
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="system" password="${activemq.password}"
groups="users,admins"/>
<authenticationUser username="user" password="${guest.password}"
groups="users"/>
<authenticationUser username="guest" password="${guest.password}" groups="guests"/>
</users>
</simpleAuthenticationPlugin>


In this simple configuration, passwords of each user is defined in ACTIVEMQ_HOME/apache-activemq-5.7.0/conf/credential.properties file.


You can find more details about ActiveMQ simple authentication plugin in this blog.

Suppose, you have started Apache ActiveMQ with simple authentication. Then, any consumer of the destinations defined in your ActiveMQ broker should connect using the credentials defined under simple authentication plugin.

If WSO2 ESB needs to connect to ActiveMQ configured with simple authentication, we can simply update the broker configuration details in ESB_HOME/repository/conf/axis2/axis2.xml as shown below.

 <transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
<parameter name="myTopicConnectionFactory" locked="false">
<parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
<parameter name="transport.jms.UserName">system</parameter>
<parameter name="transport.jms.Password">manager</parameter>

<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">TopicConnectionFactory</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">topic</parameter>
</parameter>

<parameter name="myQueueConnectionFactory" locked="false">
<parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
<parameter name="transport.jms.UserName">system</parameter>
<parameter name="transport.jms.Password">manager</parameter>

<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
</parameter>

<parameter name="default" locked="false">
<parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
<parameter name="transport.jms.UserName">system</parameter>
<parameter name="transport.jms.Password">manager</parameter>

<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
</parameter>
</transportReceiver>

Note that highlighted parameters (transport.jms.UserName and transport.jms.Password) which are used to connect to the broker using simple authentication.

The above configuration can be used to connect any Apache Axis2 based server (Apache Axis2, WSO2 Application Server etc..) to ActiveMQ using simple authentication.

Saturday, January 21, 2012

SOAP with HTTP basic auth using Apache JMeter

SOAP/XML-RPC request sampler of Apache Jmeter can be used to send SOAP requests to a web service. We looked into the details of SOAP/XML-RPC sampler in a previous blog post.
If the web service is secured, we cannot directly send messages using the above sampler. This post will help you to use Jmeter in web service testing if the service is secured using HTTP basic authorization.

If a web service is secured using HTTP basic authorization, the authorization credentials are carried over HTTP headers of the message. The security information is not coupled with the SOAP envelope. Therefore, the same procedure which we are going to discuss below can be applied to any other sampler in Jmeter.

Step 1:

Have a web service secured with HTTP basic authentication. I use Apache Axis2 as the web service container and deploy it on Apache Tomcat. Then use the tomcat authorization to secure any service hosted in Axis2 As explained by Prabath in here.
If the service is secured with HTTP basic auth, the service can only be invoked if you send the request with Authorization header as follows.

Authorization: Basic Y2hhcml0aGE6Y2hhcml0aGE=

Step 2:

We need to insert this header into SOAP messages which transmits over HTTP channel. In other words, we need Jmeter to add this header for all requests which are sent to the above web service. Lets see how we can do this.

Start to create a new Jmeter test plan. Add a thread group and add SOAP/XML-RPC request sampler. Add SOAP envelope and specify the endpoint URL.



Step 3

We need to insert authorization HTTP header to each SOAP request. Therefore, we need to use one of the Config Elements included in Jmeter. HTTP Authorization Manager config element comes in handy in this situation. Authorization manager can be used to specify login information when you access websites, web services or any other HTTP accessible resource which secured with basic authorization.

Select the thread group and select Config Element --> Authorization Manager
HTTP authorization manager config element will be added to your thread group as shown below.



Step 4

Specify the following properties in HTTP Authorization manager.

Base URL = http://localhost:8080/axis2
username = charitha
password = charitha

Here, Base URL is a part or complete URL of the web service you are going to access.
User name and password are the credentials which we specified in tomcat-users.xml file

Step 5

Add a listener and run the test. You will see the SOAP request with the following HTTP headers.

Content-Type: text/xml
SOAPAction: "urn:echoString"
Connection: close
Authorization: Basic Y2hhcml0aGE6Y2hhcml0aGE=
User-Agent: Jakarta Commons-HttpClient/3.1
Host: localhost:8080
Content-Length: 268

Tuesday, January 25, 2011

How to enable child-first class loading in WSO2 Application Server or Axis2

By default, WSO2 Application Server (or Axis2) uses parent-first class loading mechanism.
If you deploy an AAR service, which can load classes from the following locations.


  • CARBON_HOME/lib (CARBON_HOME is the location where you installed WSO2 Application Server)
  • CARBON_HOME/repository/deployment/server/axis2services/lib
  • AAR service/lib (lib directory under your service archive)


If your service implementation class has a package import for a class, which is available in both CARBON_HOME/repository/deployment/server/axis2services/lib and the lib directory under service archive, the class placed under CARBON_HOME/repository/deployment/server/axis2services/lib will get loaded.
Which means, the parent class always get loaded first.
The class loading sequence is CARBON_HOME/lib ---> CARBON_HOME/repository/deployment/server/axis2services/lib -----> AAR service/lib


Sometimes, we want to load the class from service archive lib first without loading the class which is available either one of above parent locations. In other words, child-first class loading will be required for some instances.
child-first class loading can be enabled simply by adding the following parameter in to services.xml in your service archive.


<parameter name="EnableChildFirstClassLoading">true</parameter>


If you set this parameter in axis2.xml of your WSO2 Application Server (or Axis2) instance, all services will use child-first class loading mechanism.


Sunday, February 14, 2010

How to invoke a secured web service without maintaining a policy at the client side

When we call a secure web service, the most common way of invocation is to use a policy which is compliant with the service policy at the client side. Usually, the client side policy is placed at the client file system. We have observed how this is done in few posts which published earlier.
However, there is a major drawback in this method, user has to change the client policy whenever the service policy is changed.
In order to overcome this limitation, we can use Axis2 DynamicClient to derive client policy by referring to the service WSDL which essentially keeps the service policy.

Lets see how this can be done using WSO2 WSAS-3.1.*

Pre-requisite:

Download and install WSO2 WSAS-3.1.*

Step 1

We are going to secure the default HelloService shipped with WSAS. We configure HelloService with "Sign and Encrypt - X509 Authentication" policy. In order to do that, first start WSO2 WSAS server by running wso2server.sh which is located at WSO2WSAS_HOME/bin directory.
Then, log in to the management console by accessing https://localhost:9443/carbon

Select the default HelloService and navigate to the service dashboard. Click on Security and configure Sign and Encrypt - X509 Authentication security scenario as shown below. Make sure to use wso2carbon.jks as trusted key store and private key store.



Thats all we have to do at the server side. Lets write a client to invoke the service.

Step 2

Here we are going to use Axis2 Dynamic Client which is an extension of the ServiceClient class.
First, instantiate a dynamicClient object using RPCServiceClient by passing ConfigurationContext, WSDL Url of the service, the QName of the service and the port name as parameters.

RPCServiceClient dynamicClient = new RPCServiceClient(null, new URL("http://localhost:9763/services/HelloService?wsdl"),
new QName("http://www.wso2.org/types", "HelloService"), "HelloServiceHttpSoap12Endpoint");

Then, we can engage rampart module as follows.
dynamicClient.engageModule("rampart");
Now we should update the client side policy with the rampart-config programatically.


RampartConfig rc = new RampartConfig();

rc.setUserCertAlias("wso2carbon");
rc.setEncryptionUser("wso2carbon");
rc.setPwCbClass(SecureClient.class.getName());

CryptoConfig sigCryptoConfig = new CryptoConfig();

sigCryptoConfig.setProvider("org.apache.ws.security.components.crypto.Merlin");

Properties prop1 = new Properties();
prop1.put("org.apache.ws.security.crypto.merlin.keystore.type", "JKS");
prop1.put("org.apache.ws.security.crypto.merlin.file", "/home/charitha/products/wsas/wso2wsas-3.1.3/resources/security/wso2carbon.jks");
prop1.put("org.apache.ws.security.crypto.merlin.keystore.password", "wso2carbon");
sigCryptoConfig.setProp(prop1);

CryptoConfig encrCryptoConfig = new CryptoConfig();
encrCryptoConfig.setProvider("org.apache.ws.security.components.crypto.Merlin");

Properties prop2 = new Properties();

prop2.put("org.apache.ws.security.crypto.merlin.keystore.type", "JKS");
prop2.put("org.apache.ws.security.crypto.merlin.file", "/home/charitha/products/wsas/wso2wsas-3.1.3/resources/security/wso2carbon.jks");
prop2.put("org.apache.ws.security.crypto.merlin.keystore.password", "wso2carbon");
encrCryptoConfig.setProp(prop2);

rc.setSigCryptoConfig(sigCryptoConfig);
rc.setEncrCryptoConfig(encrCryptoConfig);

Next, we can add the above rampartConfig to the service policy derived from the wsdl as follows.


Map endPoints = dynamicClient.getAxisService().getEndpoints();
AxisBinding axisBinding = ((AxisEndpoint) endPoints.values().iterator().next()).getBinding();
Policy policy = axisBinding.getEffectivePolicy();
policy.addAssertion(rc);
axisBinding.applyPolicy(policy);
Now, we can invoke the service using dynamicClient by passing the parameters as an object array and return types as an class array.


Object[] returnArray = dynamicClient.invokeBlocking(new QName("http://www.wso2.org/types", "greet"),
new Object[]{"hello"}, new Class[]{String.class});

System.out.println(returnArray[0]);


Thats all! To complete our scenario, make sure to have callback handler method similar to the one below.



public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

WSPasswordCallback pwcb = (WSPasswordCallback) callbacks[0];
String id = pwcb.getIdentifer();
if ("wso2carbon".equals(id)) {
pwcb.setPassword("wso2carbon");
}

Sunday, January 3, 2010

Enabling hotupdate in Apache Axis2

This is for some of the readers of this blog who requested me numerous times a simple post on how to enable hotupdate in Axis2.

Hot Update refers to the ability to make changes to an existing Web Service without even shutting down the system. This is very important when you test your web services. However, it is not advisable to use hot update in production servers, because it may lead a system into an unknown state. Because of that, Axis2 comes with the hot update parameter set to FALSE by default.

In order to enable hotupdate, you could simple edit the following parameter in AXIS2_HOME/conf/axis2.xml



<parameter name="hotupdate">true</parameter>



If you use WSO2 Carbon based product such as WSO2 WSAS, WSO2 ESB or WSO2 BPS, you can follow the same procedure.

Thursday, April 23, 2009

How to preserve the original WSDL when requesting ?wsdl of an Axis2 web service

I have noticed a lot of queries in Axis2 forums on keeping the WSDL unchanged when issuing ?wsdl of a particular Axis2 web service. This can easily be achieved by setting useOriginalwsdl parameter to true in services.xml. Then Axis2 shows the wsdl file placed at the META-INF directory of service archive when requesting ?wsdl

Suppose your Axis2 service archive (*.aar) includes a test.wsdl in the META-INF directory. Now, you deploy your Axis2 service and issue http://<host>:<port>/services/?wsdl.
Then, Axis2 generates a wsdl instead of your own wsdl placed in your service archive. How do you avoid this behavior?

Open your services.xml and add the following parameter.

<parameter name="useOriginalwsdl">true</parameter>

Now you will get the original wsdl when requesting ?wsdl of your service.
Simple.. isn't it?


Sunday, January 11, 2009

Get your Axis2 service or module archives validated using WSO2 tools

When creating Axis2 service archives (AARs) or module archives (MARs), it is important to adhere to the defined archive structure and standards. With the help of automated tools, you can validate these archives. WSO2 service and module validators can be used to validate your service or module archives freely in an efficient manner.
These tools are shipped as components inside WSO2 WSAS and hosted in WSO2 Oxygen tank developers portal as well.

If you have WSO2 WSAS binary distribution, validating aar or mar files is a simple process as given below.

1. Access WSAS management console using http://localhost:9443/carbon
2. Select Service Validator in the left menu



3. Select your axis2 service archive (aar file) and click on Validate AAR
4. Validation report will be shown as given below.



If WSAS binary distribution is not available, you can get your service or module validated using the online validator hosted in WSO2 Oxygen tank.

1. Go to http://wso2.org/tools
2. Click on Service Validator link under Validators section

you will be directed to the above AAR validator UI where the service archive can be validated.

Similarly, module archives (MARs) as well as service and module descriptors (services.xml. modules.xml) can be validated.

Sunday, November 2, 2008

Axis2 java2wsdl maven plugin

I demonstrated the usage of Maven2 WSDL2Code plugin in a previous post. Apache Axis2 provides with a Java2WSDL maven2 plugin as well. Maven2 Java2Wsdl plugin can be used to generate WSDL from a java class. The following steps will help you to create a wsdl from a java class using Axis2 java2wsdl maven plugin.

Step 1
Create a mavan project (See step 1 of ).
Create a java class in the source directory of your maven project. (i.e:- Create Calculator.java class at \src\main\java\com\test directory)


Step 2

Update the pom.xml of your maven project as follows.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>calculator</artifactId>
<version>1.0-SNAPSHOT</version>
<name>calculator</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-java2wsdl-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>java2wsdl</goal>
</goals>
</execution>
</executions>
<configuration>
<className>com.test.Calculator</className>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
</project>

Note the highlighted elements in the above pom. First we added a new <plugin> to use java2wsdl goal. This goal accepts a set of parameters as explained in Axis2 online documentation.
In this example we used the simplest configuration parameter, <className>, which defines the fully qualified name of class from which the WSDL is generated.

Also, make sure to add a dependency to Axis2 jars in your pom.xml.

Step 3

Go to the root directory of your project structure and run the following command.

mvn clean axis2-java2wsdl:java2wsdl

You could find the generated wsdl at target\generated-resources\java2wsdl\ directory.

Tuesday, October 21, 2008

How to use Maven2 WSDL2Code plugin in Axis2

Apache Axis2 ships with a lot of useful tools to make web service developer's life easier. Maven2 WSDL2Code plugin is one of them which can be used to generate server side skeletons or client stubs from a given WSDL using a maven pom.xml.
Lets see how this plugin can be used.

Pre-requistes:
Apache Maven2

Step1

Create a maven project using maven archetype template (You may ignore this step and use an existing project if you are familiar with maven)

mvn archetype:create -DgroupId=com.test -DartifactId=calculator

This will create a maven project structure as follows.



Step 2

Create a directory (i.e:- resources) at src\main and copy your WSDL file there.
Now, remove the existing contents of the auto-generated pom.xml (calculator\pom.xml) and add the following configuration.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>calculator</artifactId>
<version>1.0-SNAPSHOT</version>
<name>calculator</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-wsdl2code-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<goals>
<goal>wsdl2code</goal>
</goals>
</execution>
</executions>
<configuration>
<packageName>org.charitha</packageName>
<wsdlFile>src/main/resources/calculator.wsdl</wsdlFile>
<databindingName>adb</databindingName>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
</project>

Note the highlighted elements in the above pom. First we added a new <plugin> to use wsdl2code goal. The WSDL2Code goal takes a set of input parameters as explained here.
In this example, we use 3 configuration parameters.
<packageName> - The generated source will be added to this package
<wsdlFile> - The location of the input wsdl file
<databindingName> - Databinding mechanism used for code generation

Also, we need to add a dependency to Axis2 jars.

Step 3

Go to the root directory of your project structure (i.e:- calculator directory where pom.xml exists) and run the following command.

mvn clean axis2-wsdl2code:wsdl2code

You could find the generated classes at target\generated-sources\axis2\wsdl2code directory.

Note: The sample wsdl used for the above example can be found at http://ww2.wso2.org/~charitha/calculator.wsdl

Monday, October 13, 2008

Reading a property of Axis2 services.xml from service Implementation class

There have been questions raised in Axis2 user list about reading some properties defined in services.xml from service implementation class.
An easy way of doing that is as follows.

1. Suppose your services.xml is as follows and it has a parameter named, TestProperty.

<service name="ParameterService">
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass">org.test.MyParameterService</parameter>
<parameter name="TestProperty">This is a test property</parameter>

</service>

2. We need to read the value of "TestProperty" parameter from service implementation class.
It can be done using MessageContext as follows.

import org.apache.axis2.context.MessageContext;

public class MyParameterService {
public void readProperty(){
MessageContext mc = MessageContext.getCurrentMessageContext();
String prop = mc.getCurrentMessageContext().getAxisService().getParameter("TestProperty").getParameterElement().getText();
System.out.println(prop);
}

}

Now you can create a service archive with this class and copy it to AXIS2_HOME/repository/services directory. Then start axis2server.bat and go to http://localhost:8080
You will notice that the service will be deployed there. Then invoke the service by sending HTTP GET request as follows
http://localhost:8070/axis2/services/ParameterService/readProperty

Look at the Axis2server console. You will see "This is a test property" message is printed there.

Sunday, October 12, 2008

How to add a custom SOAP header to the request using AXIOM

Suppose you want to add the following SOAP header block to your web service request message.
<myNS:header xmlns:myNS="http://ws.org">
This is a custom soap header
</myNS:header >

There are different approaches to add user defined headers to the request soap messages. Lets see how it could be done using AXIOM in simpler way.
In this example we are going to invoke Axi2 default version service with adding a custom soap header in to the request.

Pre-requisites
Download and install Apache Axis2
Install Apache Tcpmon

Step 1

Start Axis2 server by running AXIS2_HOME/bin/axis2server.bat{sh}
Go to http://localhost:8080. You will see that the default version service is deployed there.

Step 2

Now, we need to generate client stubs. Go to AXIS2_HOME/bin and run wsdl2java.bat{sh} with the following parameters.
WSDL2Java -uri http://localhost:8080/axis2/services/Version?wsdl -o out -uw

The client stubs will be generated in a directory called "out".

Now, write a client importing the generated stub classes as follows(You can easily create a project in Eclipse using the generated Build.xml)

import java.rmi.RemoteException;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import sample.axisversion.ExceptionException0;
import sample.axisversion.VersionStub;


public class CustomSoapHeaderClient {

public static void main(String[] args) throws AxisFault{

String url = "http://localhost:8090/axis2/services/Version";
VersionStub stub = new VersionStub(url);

OMFactory omFactory =OMAbstractFactory.getOMFactory();
OMNamespace omNamespace = omFactory.createOMNamespace("http://ws.org", "myNS");
OMElement header = omFactory.createOMElement("header", omNamespace);
header.setText("This is a custom soap header");
stub._getServiceClient().addHeader(header);

try {
System.out.println(stub.getVersion());
} catch (RemoteException e) {
e.printStackTrace();
} catch (ExceptionException0 e) {
e.printStackTrace();
}
}


}

Note the highlighted code which creates the custom soap header.

Step 3

We can visualize the soap request using Tcpmon. Therefore open tcpmon and configure listen port in 8090 and target port 8080.
Compile and run the above client. You will see the following message in request pane of Tcpmon.

<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Header>
<myNS:header xmlns:myNS="http://ws.org">This is a custom soap header</myNS:header>


Monday, October 6, 2008

SOAP over JMS with Axis2

Axis2 provides a JMS transport implementation which can be used to send SOAP messages over JMS. This post will help you to -
  • Configure JMS transport in Axis2
  • Generate Axis2 client
  • Invoke default version service by sending request SOAP message over JMS
  • Monitoring messages via JConsole
I assume Apache ActiveMQ is used as our JMS implementation. However, you are free to use any other stack.

Pre-requisites
1. Install the latest version of Apache Axis2 binary distribution
2. Install Apache ActiveMQ 5.0.0

Step 1
First, we need to start ActiveMQ message broker. Go to ActiveMQ_Install_dir/bin and run activemq.bat



Step 2
In order to configure the JMSListener in axis2.xml, uncomment the following section.
<transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
<parameter name="myTopicConnectionFactory">
<parameter name="java.naming.factory.initial">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
<parameter name="java.naming.provider.url">tcp://localhost:61616 </parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName">TopicConnectionFactory </parameter>
</parameter>

<parameter name="myQueueConnectionFactory">
<parameter name="java.naming.factory.initial">org.apache.activemq.jndi.ActiveMQInitialContextFactory </parameter>
<parameter name="java.naming.provider.url">tcp://localhost:61616 </parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName">QueueConnectionFactory </parameter>
</parameter>

<parameter name="default">
<parameter name="java.naming.factory.initial">org.apache.activemq.jndi.ActiveMQInitialContextFactory </parameter>
<parameter name="java.naming.provider.url">tcp://localhost:61616 </parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName">QueueConnectionFactory </parameter>
</parameter>
</transportReceiver>

Also, uncomment the transport Sender which is in the Transport-outs section of axis2.xml.

<transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender"/>

Step3
The following ActiveMQ libraries must be copied to the Axis2 lib directory (AXIS2_HOME/lib).
  • activeio-core-3.1-SNAPSHOT.jar (ActiveMQ_Install_dir\lib\optional)
  • activemq-core-5.0.0.jar (ActiveMQ_Install_dir\lib\)
  • geronimo-j2ee-management_1.0_spec-1.0.jar (ActiveMQ_Install_dir\lib\)
  • geronimo-jms_1.1_spec-1.0.jar (ActiveMQ_Install_dir\lib\)
Step 4
Start Axis2server and go to http://localhost:8080
Then select the default version service.
The WSDL of the Version service will be displayed. You will notice the following port.

<wsdl:port name="VersionJmsSoap11Endpoint" binding="ns:VersionSoap11Binding">
<soap:address location="jms:/Version?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616"/>
</wsdl:port>

This implies that the Version service is now exposed over JMS transport as well. Lets write a client and send SOAP requests through JMS.

Step 5

Generate Client stubs with the following command.
AXIS2_HOME/bin/WSDL2Java -uri http://localhost:8070/axis2/services/Version?wsdl -o out -uw

The client stubs will be generated in a directory called "out".

Now, write a client importing the generated stub classes as follows(You can easily create a project in Eclipse using the generated Build.xml)

import java.rmi.RemoteException;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import sample.axisversion.ExceptionException0;
import sample.axisversion.VersionStub;


public class JMSClient {

public static void main(String[] args) throws AxisFault{
ConfigurationContext cc = ConfigurationContextFactory.createConfigurationContextFromFileSystem(null,"D:\\axis2\\axis2-client\\conf\\axis2.xml");
String url = "jms:/Version?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616";
VersionStub stub = new VersionStub(cc,url);

try {
System.out.println(stub.getVersion());
} catch (RemoteException e) {
e.printStackTrace();
} catch (ExceptionException0 e) {
e.printStackTrace();
}
}

}

We need to enable JMS in client side too. Therefore, create a client repository (Just create a directory and copy the axis2.xml in there). Make sure to enable JMS transportReceiver and TransportSender in client's axis2.xml.

Step 6

Run the client. You will get the response back with axis2 version.
Now we need to look at the messages transmitted through JMS channel. Open a command prompt and type 'jconsole' and hit enter.
Connect to ActiveMQ agent.
Click on MBeans and select org.apache.activemq mbean.
Select localhost --> Queue

Run the client few times and note the queue size.

How to deploy JSR181 annotated class in Apache Axis2

JAX-WS (Java API for XML Web Services) provides support for annotating Java classes with metadata to indicate that the Java class is a Web service. With the annotations, you can expose java classes as web services with minimum effort.
Apache Axis2 ships with JAX-WS support since its 1.4 release. This post explains the simplest possible scenario of JAX-WS support, how you can deploy an annotated class in Axis2.

Pre-requisites
Apache Axis2-1.4 or later
JDK1.5 or above

Step 1
Write an annotated class as follows.

package org.apache.axis2;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
public class Calculator {
@WebMethod
public double Add(double x, double y){
return x+y;
}
}

Here, the @WebService annotation tells the server runtime to expose all public methods on the above class as a Web service. Also, with the @WebMethod annotation, you can specifically denotes the methods which are exposed in the web service.

Step 2
Package the above class as a JAR (i.e:- Calculator.jar).
You need to create a directory in Axis2 binary distribution where the annotated jars are placed.
Therefore go to AXIS2_HOME/repository (AXIS2_HOME is where you extracted the binary distro) and create a new directory called, servicejars.

cd AXIS2_HOME/repository
mkdir servicejars

Step 3
Copy the annotated jar file to the servicejars directory. Then, start Axis2server (AXIS2_HOME/bin/axis2server.bat{sh})

Step 4
Go to http://localhost:8080
You will see that the calculator class will be exposed as a web service. Click on the service name.
You will be directed to the following URL and the WSDL of the service can be viewed there.
http://localhost:8080/axis2/services/CalculatorService.CalculatorPort?wsdl

Step 5
Service Deployement is over by now. Lets invoke this service using a client. I will use SOAPUI for the demonstration, you may choose any of the available mechanisms.

Open SOAPUI and start to create a new WSDL project.
Enter the above WSDL path(http://localhost:8080/axis2/services/CalculatorService.CalculatorPort?wsdl) as the initial WSDL.
Select the request, provide inputs and submit. You will get the expected results back.



You can find more information about Axis2 JAX-WS API from here.

Friday, August 8, 2008

How to deploy Apache Axis2 on GlassFish Application Server

I have demonstrated the steps to deploy Apache Axis2 on BEA WebLogic, IBM WebSphere, JBoss and Resin application servers in my previous posts. This series is not complete unless the steps to deploy Axis2 on GlassFish server are explained.
Lets see how Axis2 can be deployed on GlassFish server. It is quite straightforward and similar to the other application servers we have discussed so far.

Pre-requisites:
Download and install the latest version of GlassFish server from here.

Step 1

Start GlassFish server.
i.e:- Go to GlassFish_Home/bin and run asadmin script as follows.
asadmin start-domain domain1

This will start GlassFish server in domain1.

Step 2

Download Axis2.war from here

Step 3

Access GlassFish administration console (In a browser, access http://localhost:4848).
Log in to administration console (Default username=admin, password=adminadmin).

Step 4

In the left navigation menu of the GlassFish admin console, select Enterprise Applications and click on Deploy.
You will be directed to the following screen.



Select 'Web Application(*.war)' as the Type from the drop down list.
Enter the location of the downloaded axis2.war.
Leave the other settings intact and click OK.

You will be directed to the "Web Applications" page.



Select Axis2 from the table and click on Launch.
Axis2 administration page will be displayed.

Step 5

Verify the status of installation. Click on 'Validate' link of Axis2 admin page. You should see the following 'Axis2 Happiness' page.



Now you can log in to Axis2 administration page and start deploying services.

Monday, July 21, 2008

How to deploy Apache Axis2 on WebLogic 10

I have already discussed the steps to deploy Apache Axis2 on IBM WebSphere, JBoss and Resin application servers. In this post, I'm going to explain the procedure to deploy Axis2 on BEA Weblogic 10 server.

Pre-requisites:
Download and install BEA Weblogic 10.

Step1

Create a new weblogic domain by running config.sh located at WebLogic_HOME/wlserver_10.0/common/bin directory.
Lets assume the new domain is axis2.

Access your weblogic domain direcrtory and start weblogic (Go to WebLogic_HOME/user_projects/domains/axis2/bin and run startWebLogic.sh)

Step 2

Download Axis2.war from here

Step 3

Create a directory in your file system (i.e:- /opt/axis2) and copy axis2.war to that directory. Extract axis2.war file (unzip axis2.war)

Step 4

Access WebLogic administration console (In a browser, access http://localhost:7001/console)

Log in to administration console (You should have configured username and password for admin console when creating your WebLogic domain)

Step 5

In the left navigation menu of the WebLogic administrative console, select Lock and Edit and click on Deployments.
Click on Install and Select the path of axis2 directory where we have extracted axis2.war file.



Click on Next.

Select the default option, Install this deployment as an application and click Next.

Accept the default settings in Optional Settings page and click on Next.

Click on Finish in the last page of the wizard.

Click Activate Changes in the left menu.

Step 6

Select Lock and Edit again and click on Deployments in weblogic admin console. You will see axis2 listed in the Deployments table.
Select axis2 and click on Start-->Servicing all requests.

In Start Deployments page, click on Yes.

Thats all for deploying Axis2 on Weblogic. Lets access axis2 admin console and validate the installation

Step 7

Now open a browser and go to http://localhost:7001/axis2
Axis2 welcome page will be displayed.

Step 8

Verify the status of installation. Click on 'Validate' link. You should see the following 'Axis2 Happiness' page.



Now you can log in to Axis2 administration page and start deploying services.

If you encounter any class loading issues with some of your services, configure the <prefer-web-inf-classes> element in WEB-INF/weblogic.xml as specified in Axis2 Application Server Specific Configuration Guide.

Saturday, July 19, 2008

How to use Axis2 codegen ANT task

Apache Axis2 code generator tool provides a very useful custom ANT task. All of the command line code generation options are available with the ANT task as well.
Lets see how a simple client side code generation is done using the ANT task.

Pre-requisites:
Install Apache Axis2 -1.3 or higher
Install Apache ANT-1.7 or higher

Step 1

Create a directory and start to create a build.xml inside that as given below. (eg:- C:\temp\build.xml)

<project name="CodegenExample" default="codegen" basedir=".">

<path id="axis2.classpath">
<fileset dir="C:\axis2\axis2-1.4\lib">
<include name="**/*.jar" />
</fileset>
</path>

<target name="codegen">

<taskdef name="axis2-wsdl2java"
classname="org.apache.axis2.tool.ant.AntCodegenTask"
classpathref="axis2.classpath"/>

<axis2-wsdl2java
wsdlfilename="C:\test\your.wsdl"
output="C:\output" />
</target>

</project>

If you are familiar with ANT, you should be able to understand this simple build script easily. We use the path referenced as "axis2.classpath" to add Axis2 library jars which are placed at AXIS2_HOME/lib (In our example, C:\Axis2\Axis2-1.4\lib)

Axis2 codegen ant task is implemented by the org.apache.axis2.tool.ant.AntCodegenTask class. Therefore we refer to that inside a taskdef as given in "taskdef name="axis2-wsdl2java"

wsdlfilename attribute is equivalent to the -uri option in wsdl2 java command line tool and output is similar to -o option.

Replace the values of wsdlfilename according to your wsdl location.

Step 2
Open a command prompt and go to the directory where you saved the above build.xml.
Type 'ant'

The generated stub classes will be saved in the specified out put directory.

Monday, July 14, 2008

How to access HTTP headers from an Axis2 service implementation class

I have seen some users in axis user mailing list ask the question on how to access HTTP headers of the request SOAP message using the service implementation class.
It's easy and straightforward with messageContext class.
Lets see with an example.

1. Create a service implementation class as follows

import javax.servlet.http.HttpServletRequest;

import org.apache.axis2.context.MessageContext;

public class TestService {

public String MyOperation(String s){

MessageContext msgCtx = MessageContext.getCurrentMessageContext();
HttpServletRequest obj =(HttpServletRequest)msgCtx.getProperty("transport.http.servletRequest");
System.out.println("Acceptable Encoding type: "+obj.getHeader("Accept-Encoding"));
System.out.println("Acceptable character set: " +obj.getHeader("Accept-Charset"));
System.out.println("Acceptable Media Type: "+obj.getHeader("Accept"));
return s;

}
}

As you can see in the highlighted statements, first we need to get the current messageContext. Then from the messageContext, we can get the HTTPServletRequest object from which we can get whatever HTTP headers we want.

2. Write service descriptor(services.xml) for the above service class and deploy the service in Axis2 (If you are not familiar with Axis2 deployment, please read Axis2 user's guide )

3. Invoke the service in RESTful manner
http://:/services/TestService/MyOperation?s=hi

You will see the following in Axis2 run time console.

Acceptable Encoding type: gzip,deflate
Acceptable character set: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Acceptable Media Type: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Saturday, July 12, 2008

How to monitor messages using tcpmon in Axis2 dual channel web service invocation

Apache Axis2 client API provides the necessary methods to utilize a service using two transport channels. You can even send request through one transport (e.g:- HTTP) and get the response back via a different transport such as TCP.

setUseSeperateListener(boolean) method of org.apache.axis2.client.Options
class can be used to utilize a separate listener for your response.
If two separate HTTP transport channels are used for request and response, Axis2 starts a new HTTP listener at the client side to receive the incoming response message.

As most of web service developers know, Apache tcpmon can be used to monitor message flow between web service invocations. In one way messaging, it is quite straightforward.
You just need to configure tcpmon to listen in some port and direct the messages to the port where the web service is hosted. In client, port of the endpoint reference has to be changed to tcpmonitor listen port. That's all you have to do for monitoring messages in single channel invocation.

In this post, you can see how tcpmonitor is configured to use in dual channel invocation.

1. If you have not done it yet, download Apache tcpmon from here
Unzip the downloaded file and run build/tcpmon.bat {sh}

2. As I stated before, Axis2 starts a http listener at the client in dual channel invocation. Therefore, you need to configure Axis2.xml to redirect messages to tcpmon as follows.

Open AXIS2_HOME/conf/axis2.xml and locate to the following section.

<!-- ============================================ -->
<!-- Transport Ins -->
<!-- ============================================ -->
<transportReceiver name="http"
class="org.apache.axis2.transport.http.SimpleHTTPServer">
<parameter name="port">8080</parameter>
<!-- Here is the complete list of supported parameters (see example settings further below):
port: the port to listen on (default 6060)
hostname: if non-null, url prefix used in reply-to endpoint references (default null)
------------
-->
<parameter name="hostname">http://localhost:8090</parameter>
<!-- <parameter name="originServer">My-Server/1.1</parameter> -->
----------
</transportReceiver>

3. Note the highlighted elements in the above axis2.xml configuration. First you have to uncomment the hostname paramter <parameter name="hostname"> and specify a port which is not already listened in your system (e.g:- 8090).

In tcpmon, create a new listener with 8090 as the listen port and 8080 as the target port. With this configuration, the response messages receive to the reply-to endpoint reference are directed to 8090 tcpmon port and then those will be targeted to client HTTP listener port, 8080.



Now, you should be able to monitor the response flow in dual channel invocation.

Monday, July 7, 2008

How to Deploy Apache Axis2 on IBM WebSphere

As I mentioned in a previous post, the flexible deployment mechanism of Axis2 allows you to install it on any application server with minimum configuration effort.
Lets see how Axis2 can be deployed on IBM WebSphere.

Pre-requisites:
Download and install IBM WebSphere 6.1
Create a profile as specified in the WebSphere installation steps

I will use Axis2-1.4 and WebSphere6.1 for demonstration purposes. But you should be fine with the other versions too.

Step 1
Download Axis2.war from here

Step 2
Start WebSphere server (In windows XP menu All programs--> IBM WebSphere-->Application Server 6.1 --> profiles --> YourProfile -->Start the Server)

Wait until start window closes.

Step3

Access WebSphere administration console
(In windows XP menu All programs--> IBM WebSphere-->Application Server 6.1 --> profiles --> YourProfile-->Administrative Console)

Log in to administration console (You should have configured username and password for admin console when creating WebSphere profile)

Step 4

In the left navigation menu of the WebSphere administrative console, select Install New Application
Enter the path of the Axis2.war file (Browse for axis2.war in your file system)
Enter 'axis2' as the context root for application (See the image below) and click on 'Next'



Step 5

In the Select installation options page, keep the default values and click.
Map modules to servers page will be displayed. Select Apache Axis2 module and click Next.
You will be directed to the Map virtual hosts for Web modules page. Select Apache-axis2 web module and click Next.
You should see a Summary page similar to the one given below. Click 'Finish' to complete installing Axis2.war on WebSphere.



You will get 'Application axis2_war installed successfully.' message in the next page. Click on Save to persist changes directly to the master configuration.

Step 6

Now we have to start the installed Axis2.war. Click on Enterprise Applications link in the left navigation menu.

Select Axis2.war and click on Start button. You will see the axis2.war started successfully message as in the following image.



Step 7

Now open a browser and go to http://localhost:<port>/axis2
Axis2 welcome page will be displayed.

Step 8

Verify the status of installation. Click on 'Validate' link. You should see the following 'Axis2 Happiness' page.



That's all!. If you encounter any issues with deployment, please drop a mail charitha@wso2.com


Thursday, July 3, 2008

WSDL2Code UI tool - Easy and efficient code generation utility

If you are an Apache axis2 user, you may already familiar with WSDL2Java code generation tool. WSO2 WSAS is powered by Apache Axis2 and includes a rich set of features to interact with web services. WSDL2Code is a UI based tool integrated with WSO2 WSAS which allows users to generate code from a WSDL hosted in a remote server or a local file system.
Lets see how WSDL2Code tool makes web service developement effort much easier and productive.

Step 1
Download and Install WSO2 WSAS

Step 2
Start wso2wsas. Go to WSAS_HOME/bin and run wso2wsas.bat{sh}

Step 3
Go to http://localhost:9762
Welcome page of the WSAS console will be displayed. Click on WSDL2Code at the left navigation menu. You will be directed to the following screen.



You can see multiple code generation options in the above screen. These code gen options are similar to the command line options available in WSDL2java tool.

Step 4
Lets generate client stub against default version service using the above tool.
Enter 'http://localhost:9762/services/version?wsdl' in the -uri option available on the top of the page.
Select -uw option and click on 'Generate'
It will prompt to save the generated zip file (e.g:- 1.2151049949841125E12.zip). Save it in a directory in your local file system.

Step 5
Unzip the generated file (You will see src folder, build.xml and pom.xml in the extracted directory) and go to the directory where you extracted the zip file.
Assuming your IDE is eclipse, enter the following command to export the generated code in to eclipse and setting up WSAS libraries at once.

mvn eclipse:eclipse


(If you have not installed maven2, download it from here and add maven_home/bin to your PATH)

You will see 'BUILD SUCCESSFUL' message at the end of executing above command.

Step 6
Open eclipse and go to Window-->Preferences-->Java-->Build path-->Classpath variables
Create a new variable, M2_REPO and enter your maven2 repository path as the value. (maven2 repository is located at user home directory. e.g:- C:/Documents and Settings/Charitha/.m2/repository)
(Note that this step has to be done only once. If the M2_REPO variable is already defined, you can ignore this step)

Step 7
In eclipse, select File-->import-->Existing projects into workspace-->next
Browse root directory of the extracted zip file above. Click 'Finish'.
New project will be added to the workspace with an id like N10001-version. You should see that all the necessary WSAS libraries are added to the project.

Now the only remaining step is to write client to invoke version service as follows

public class VersionClient {

public static void main(String[] args)throws Exception {
VersionStub stub = new VersionStub();
System.out.println(stub.getVersion());
}

}

You may realize how WSO2 WSAS reduce the complexity of web service invocation with these kind of tools. Even if you are beginner to the world of SOA, WSO2 WSAS can be considered as the best paltform to get started with minimum effort.