Architecture & Design How to Write Axis2 Web Service Clients for the Cloud

How to Write Axis2 Web Service Clients for the Cloud

Introduction


Cloud computing has become a buzz word in the IT field, and
people are developing application for the Clouds. One of the
cool features we can find with Cloud apps like Amazon is that
they support the Web service API to configure, run and monitor
the instances in the Cloud. Due to various reasons Amazon EC2
has become one of the most commonly use commercial Clouds, so
today we are going to discuss how to write a Web service client
for Cloud apps like Amazon, Writing a client for other Cloud
apps would be much the same. Since most of them will have the
same set of API as well as security requirements.

Axis2 can be used both as a server and a client to invoke
services. In previous articles we have discussed a number of
different accepts of Axis2 on the server side. One of the other
most important sides of Axis2 is how to use Axis2 as a client to
invoke other Web services. When writing to a client using Axis2
there are two main approaches, the first approach is to write
the client by hand, the second is to use tools to generate the
client stub to invoke the remote service.


Hand written client vs generated client


In the first approach, we have to write the code for all the
processing, which includes, serialization and de-serialization
message, invoking the services and etc.., put simply there are a
number of steps we have to perform to invoke the service.
However the most important thing is that we can write the most
efficient code when we write the client by hand, since we can
optimize the code for our particular use case.

On the other hand, in the second approach what we do is use the
Axis2 tool to generate the client side stub to invoke the
service. With that approach we do not need to worry about the
message serialization and de-serialization, setting up the
system or invoking the service. Generated code handles all
that for us. So the code generation approach is more convenient and
time saving, especially to minimize the number of errors.


In this article we are going to discuss how to use the Axis2
code generation tool to generate client side code and then how
to set up that code to invoke a remote service. In particular we
are going to write an Axis2 client to invoke Amazon EC2 cloud
APIs.


Setting up Axis2


The first step of creating the Axis2 client stub for a remote service is
setting up the Axis2 client side, for that we need to download
Axis2 binary distribution. We can download Axis2 binary
distribution from the Axis2 official web site. Download that and
then extract the downloaded zip file. Now we are ready to
generate the stub for the Amazon EC2 Web service API. We can find
the EC2 WSDL from following URL, http://ec2.amazonaws.com/doc/2009-03-01/AmazonEC2.wsdl.

If you are new to WSDL then you will find it somewhat hard to
understand the WSDL, the nice thing is that you do not need to
understand the WSDL to generate the Axis2 client. That is one of
the cool feature of code generation; it reduces the complexity.
The tool can process the WSDL and generate the code for us. Now
let’s generate client stub for the EC2 WSDL.


First go to the “bin” directory of the extracted Axis2
distribution, there you can find a number of shell scripts and
Windows batch files. So depending on the OS platform you have to
use either shell scripts or batch files. When we generate the
code we can pass a number of options to the code generation tool,
however in this particular case we are not going to discuss all
of them. Run the following command to generate the code,


In Linux:


./wsdl2java.sh -uri http://ec2.amazonaws.com/doc/2009-03-01/AmazonEC2.wsdl -o out

In Windows:


wsdl2java.bat -uri http://ec2.amazonaws.com/doc/2009-03-01/AmazonEC2.wsdl -o out


Then it will create a directory called “out” inside the bin
directory and create the code inside that. If you browse you
will able to see a large file. DO NOT try to open that or read
through it, it is so complex to read, and there is no reason to
read or edit that file. That single class has all the
serialization and de-serialization code as well as the service
invocation code.


Next we are going to use some other code generation
parameters and generate code in a different manner. The idea is
to generate data binding (serialization and de-serialization)
code into septate classes. Next run the following command.
Notice the difference?



In Linux:


./wsdl2java.sh -uri http://ec2.amazonaws.com/doc/2009-03-01/AmazonEC2.wsdl -o out_unpack -u

In Windows:


wsdl2java.bat -uri http://ec2.amazonaws.com/doc/2009-03-01/AmazonEC2.wsdl -o out_ unpack -u

What are those options?

Now we are going to discuss some of the options we use when we generate the code,



  • -uri :- as the name implies the “uri” option is to specify the location of the WSDL document, it can either be a remote URL or path to a local file.
  • -o :- This parameter is used to specify the output location of the code, so that the Axis2 tools generates the code into it.
  • -u :- The idea of “u” option is to unpack the code, it will generate the data binding code and service invocation code into separate classes.


Now we have generated the client side stub for our Amazon EC2. Our next step is to write the code to use the stub. In fact there is not such a big difference from writing a client to the other Web service and EC2, so if you know how to use a stub then it will be easy for you to use the generated stub to do the work you want.


Invoking the stub

As we discussed before there is no difference using the previously generated stub for EC2 and a normal stub with one exception. The exception being, in the case of Amazon EC2 we have to use security so we need to setup security requirement for EC2. Basically we need to configure the public key and the certificate. In addition to that due to some of the missing features in Axis2 security implementation we need to write some additional code. But we are not going to discuss that here since it will complicate the article, you can find the required library in the resource section. Download that and add it into the classpath, then you can use those utilities for the client.

Writing the security handler

As we discussed before to use Amazon EC2 we need to use the WS- Security, to use WS-Security in Axis2 we need to write a special handler to provide and handle the user-name and password. And writing that is so simple, we just need use the following code as the security handler:
  import org.apache.ws.security.WSPasswordCallback;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.callback.CallbackHandler;
import java.io.IOException;

public class SecurityHandler implements CallbackHandler {
public static String password;

public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
for (Callback callback : callbacks) {
WSPasswordCallback pwcb = (WSPasswordCallback) callback;
pwcb.setPassword(password);
}
}

}


Having written the security handler and other security related code we are now ready to write the code to invoke the stub.

Setting up the public key and certificate


The next step of writing the client is setting up the public key
and the certificate, for that you first need to have an EC2
account. If you do not have one, create an account and then use
the EC2 tools to generate the public key and the certificate.
For more information about creating those two keys refer to the
resource section.

Writing the client


As we have a number of times to use Amazon EC2 we need to use
WS-Security so we need to setup the required security for the
client. One of the key requirements of that is to add the
required modules into the classpath. In this case we need to
have Axis2 security module in the classpath, otherwise the code
we are going to write will not work. So download the Axis2
security module (Apache Rampart) and put that into classpath.

There are a number of ways of creating the instance of Stub,
and that does not have a direct impact on the invocation. So
here we are going to create the instance of Stub inside the
constructor of the client as follow:



ConfigurationContext configCtx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(null, null);

Create an instance of the stub.

stub = new AmazonEC2Stub(configCtx);



We first create a configuration context, for the most part we
do not need that. However there are situations where we need to
create ConfigurationContext using the custom Axis2 configuration
file and our own repository, in those cases we need this step.

Next we need to initialize some of the required parameters,
like populate key stores and configure security handler. You can
find the required code for those below. As we discussed
previously we are going to use the attached utils.jar for this
because that particular library file has all the required
methods and classes we are going to use.



ec2PrivateKey = EC2Utils.pem2der(ec2PrivateKey);
ec2Cert = EC2Utils.pem2der(ec2Cert);
File jks = new File(EC2_JKS);
if (jks.exists()) {
jks.delete();
}
SecurityHandler.password = EC2_KS_PASSWORD;
EC2Utils.doImport(EC2_JKS, ec2PrivateKey, ec2Cert, EC2_USER, EC2_KS_PASSWORD);


Now we have done everything we need to setup the client, and
we are ready to write the code to invoke the Amazon EC2. We
are going to discuss only one of the methods (RunInstances) in the
stub, we can use the same procedure for all the other methods
once we understand how to use the one method.


Amazon has different kinds of instance types, so we have to
write the code to cope with that. The following few lines does
that.



if (instanceType == null) {
instanceType = InstanceType.SMALL;
}


To start an instance in EC2, we need to pass the required request
parameters. The following code segment handles that. The code is so
simple and we do not need to discuss them one by one.



RunInstances req = new RunInstances();
RunInstancesType params = new RunInstancesType();
params.setInstanceType(instanceType.getType());
params.setImageId(amiID);
params.setKeyName(keyName);
params.setMaxCount(numberOfInstances);
params.setMinCount(numberOfInstances);

if (groupName == null) {
groupName = “default”;
}
GroupSetType gst = new GroupSetType();
GroupItemType git = new GroupItemType();
git.setGroupId(groupName);
gst.setItem(new GroupItemType[]{git});
params.setGroupSet(gst);

req.setRunInstances(params);



We need to configure the security parameters for each
invocation, so the following code will do that for us. This
means setting up the correct security policy for the method.



enableSecurity(“RunInstances”);


Now we have all we need, so let’s call the Service. We’ll use
the following code to invoke the service.



RunInstancesResponse respone = stub.RunInstances(req);


Now its time to process the response.


RunInstancesResponseType resType = respone.getRunInstancesResponse();
RunningInstancesSetType instances = resType.getInstancesSet();
RunningInstancesItemType[] items = instances.getItem();
ArrayList instanceIds = new ArrayList();
for (int i = 0; i < items.length; i++) { RunningInstancesItemType item = items[i]; instanceIds.add(item.getInstanceId()); System.out.println("InstanceID " + item.getInstanceId()); }

You can find the complete client for invoking RunInstances in
the resource section. Once you run this code it will start an
EC2 instance for you. As we discussed before, we need to create
the Amazon EC2 account, then the key files as well as the Amazon
Machine Image. If we do not have them then it would be hard to
follow this document. However the concept will remain the same,
so if you want to invoke some other service you can follow the
same steps.


To run the client, you need to pass the location of the
public key, location of the certificate and name of the AMI. You
can find a sample client in the resource section, edit and
run it.


Summary


In this article we discussed how to use Axis2 tools to generate
client side code, and then we discussed how to use the generated
client to invoke a service. Since the Amazon EC2 has become one
of the most commonly used Cloud APIs, we use Amazon EC2 WSDL to
generate and invoke the service. In addition to that we
discussed some of the client side security of Axis2 and how to
use it. Now, you can complete the client to use the rest of the
methods in the stub.

Resources



  1. utils.jar

  2. AWSClient.java

  3. SecurityHandler.java

  4. Amazon Elastic Compute Cloud

Latest Posts

Related Stories