Archive for September 2011
This article serves as a tutorial on how to develop Web Service using Axis2 and JAXB XML data binding.
Current version of Axis2 framework at the time of writing this tutorial is 1.6.1. Its integration in Eclipse java development tool supports two types of wizards for creating web services: Web Service Wizard and Web Service Client Wizard. Using these two wizards enables us to build client-side and server-side web service artefacts for Axis2. Its preferences include selecting XML data binding type. Supported types in these wizards are ADB and XMLBEANS. Although when using supplied Web Service wizards there are only those two supported data bindings in fact Axis2 also supports JiBX and JAXB data bindings.
Because the standard development of Web Services compliant to JAX-WS 2.1 is using JAXB 2.0 data binding we will show how to develop web services under these technologies. For this we will not use supported wizards, but WSDL2Java command line tool. This tool is supplied in downloaded Axis2 package. Be aware that WAR (Web Archive) Axis2 distribution does not include mentioned tool.
For this tutorial we will develop a Top Down Web Service from supported WSDL.
We will assume that we already have installed Tomcat server version 7.
Preparing Eclipse environment.
To prepare Eclipse environment for implementing our web service we must set Axis2 runtime location. In Eclipse we enter “Preferences” (Window -> Preferences), than we navigate to “Web Services” -> “Axis2 Preferences”, where we set “Axis Runtime Location” to the location of extracted Axis2 folder (Image below). After this we can also prepare User Libraries under “Java” -> “Build Path” -> “User Libraries” where we first add new Library, and then we add all JAR files from “lib” directory under extracted Axis2 directory to this library.
After this we must add AXIS2_HOME environment variable (assuming we already have JAVA_HOME environment variable set) which points to installation directory of Axis2 e.g. “C:\axis2-1.6.1”.
Preparing project for developing Web Service.
We will develop our sample Web Service into Dynamic Web Project. For creating project with support for Axis2 we must select proper facets. We can do this when creating new “Dynamic Web Project” using button “Modify” (Image below).
We must select “Axis2 Web Services”. Since current version of Axis2 runs on Servlet version 2.5 or less it is also necessary to change “Dynamic Web Module” version to 2.5. Note that this is not necessary if we are using target runtime that does not support Web Module higher than 2.5.
At this stage we have prepared our project for building a web service.
Preparing WSDL Web Service description.
For the purpose of this tutorial creating WSDL description does not hold high priority. That is why we will skip the part of creating one and will use one supported on this link: WeatherServiceWSDL
Generating Java skeleton.
As mentioned earlier in this tutorial we will use WSDL2Java command line tool (we can find it in axis2 installation directory under directory “bin”). For generating Java Skeleton classes we will use the following command shown on image below:
- o – Path where Java skeleton will be generated (usually web project path).
- ss – Marks generating server side artefacts
- d – Selected data binding for generating Java skeleton, “jaxbri” marks JAXB Reference Implementation data binding.
- uri – supported is local disk path or URL of WSDL file.
After generation Java skeleton we must implement web service. Image below shows generated classes.
Implementation classes are named “*Skeleton.java”. There we implement generated method that represents our Web Service operation. Note that sometimes it is necessary to refresh file list in Eclipse Project Explorer for generated files to be visible.
Packaging Web Service.
When generating web service Java Skeleton, WSDL2Java tool also creates ant build file for building and packaging generated web service. This file is “build.xml”. Our next task is to run this Ant task. For the purpose of this tutorial we will add a builder that uses generated Ant task to prepare our web service for deployment. Another option would be manually running this task with Ant.
This we will do by Right Clicking on project that holds generated classes and selecting “properties”. Under “builders” we add new Ant builder. Only thing we must do when configuring this builder is to select build file. We must select generated “build.xml” file as seen on image below. Recommended is also to change builder name.
After setting new builder we see build log on console. Building must be successful.
Deploying Web Service.
Result of successful building is Axis Archive package, which includes build web service. Procedure in previous stage creates this kind of package under “build/lib” folder in our project. Archive name in the case of this tutorial is “WeatherService.aar” and it includes developed services class files. We have different possibilities on how to deploy Web Service packed this way. We can deploy it under Axis administrative console, or we can manually add it to Axis service repository. For the purpose of this tutorial we will manually deploy it on Axis runtime which has been already added into our project at stage 2. We must do two things. First one is copying Axis archive file, in our case is “WeatherService.aar” to “WebContent/WEB-INF/services” folder that represents Axis2 repository. Next step is to add “WeatherService.aar” into “services.list” text file situated in the “services” folder.
Files used at this stage of the tutorial are shown in image below.
Running Web Service.
After completed all this steps successfully, we are now able to test developed Web Service. WSDL should be accessible, when using default configuration, at address like: http://localhost:8080/WeatherService/services/WeatherService?wsdl
You can download a Eclipse snapshot of this project from this link: WeatherService
OpenNebula is an open-source cloud computing framework for building private, public and hybrid cloud environments. Its goal is to provide an open, flexible and extensible management layer to automate and orchestrate the operations of existing (on-premises) or remote hardware infrastructure including networking, storage, virtualization, monitoring and user management. OpenNebula also support a mechanism called “hooks”; triggering of custom scripts, tied to the state change of a particular resource. Hooks can be a powerful feature, as they open a wide area of possibilities for system and process automation.
Hooks can be trigger by a state change in either Virtual Machine or Host. For Virtual Machine state changes, the hook script can be executed on the head node (OpenNebula cluster controller), or on the scheduled host directly. The hooks mechanism is available “out of the box”, so no additional installations or settings are required – apart from the hooks themselves, of course. To demonstrate the usage of hooks when extending the base OpenNebula system with our specific business and process flows, we included a simple example. The example is very easy to understand, yet not completely trivial and could also be used in a real-world scenario.
Let’s say we are the administrators of an OpenNebula cloud, which can be fully utilized by our client’s IT staff. The IT staff has full control over the virtual machines, but we’d still like to be informed when a VM is up & running, particularly about the VM’s owner and the host machine on which the VM is currently running. To achieve this, we will send an e-mail to a predefined address when any of the virtual machines enter the “running” state, along with the required VM’s runtime information.
Great! Now let’s get our hands dirty… The example system’s architecture is as follows:
- we will use the OpenNebula’s hooks mechanism to trigger a Ruby script when the state of a VM changes to RUNNING
- the Ruby script will pass the message containing the Virtual Machine’s ID to a server socket
- the Java socket server will, upon receiving a valid message, trigger the execution of our business logic
- the business logic will use OpenNebula’s Java RPC API to connect to the cloud, retrieve the VM’s runtime information and send an e-mail to a predefined address
1) We first have to define a new Virtual Machine hook for the “running” state. Open
$ONE_LOCATION/etc/oned.conf (depending on your installation type). This is your Hook Manager’s configuration file. Add the following lines at the end of file:
VM_HOOK = [
name = "demo_vmhook_running",
on = "RUNNING",
command = "demohook.rb",
arguments = "VM RUNNING $VMID",
remote = "no" ]
A little explanation won’t hurt:
- “name” is the name for the hook and can be anything, but it is useful to provide a descriptive enough name in case something goes wrong with the script or the hook itself – the name parameter will be displayed in the logs.
- “on” means the state this hook is bound to, in our case running. Other states include create, shutdown, stop, etc. For the complete list, please consult the documentation.
- “command” is the script file that gets executed when the hook is triggered. We use a Ruby script “demohook.rb” since Ruby is automatically installed with OpenNebula and quite easy to read.
- “arguments” is probably the most important part of hook’s definition, because we can access VM template variables with $ sign. Hence, $VMID means the ID of the Virtual Machine that just entered the RUNNING state.
- “remote” is currently set to “no”, because we want the “demohook.rb” script to be executed on the head-node, where our Java program is running. By setting this to “yes”, the script is executed remotely (on the host where the VM was scheduled to run), which can also be quite a powerful feature of OpenNebula.
2) Create the Ruby script
demohook.rb and place it in
$ONE_LOCATION/share/hooks, depending on your installation type:
puts("3 arguments required")
sck = TCPSocket.new("127.0.0.1", 3344)
sck.write(ARGV + "_" + ARGV + "_" + ARGV)
p 'TCP socket connection refused on port 3344 - is Java socket server running?'
The script is also available in the source zip file. You can change the port number (3344), but please make sure you also change the port in Java program accordingly (file
3) Restart OpenNebula by issuing the following command:
$ sudo service opennebula restart
OK, we have just installed the OpenNebula hook along with the script, which will just pass the arguments to a server socket on port 3344. Now we need the socket listener to trigger the execution of our business logic (get VM’s runtime information and send it via e-mail to the system administrator). We will use Java programming language to utilize the Java RPC API and take full control of the rest of the process. This approach allows us to keep the Ruby script as simple as possible and free of any specific business logic, as Java code is usually easier to maintain and extend. We could, of course, limit ourselves to Ruby only and put everything in “demohook.rb” script. It doesn’t even have to be Ruby, it could also be Python, plain old shell script or maybe even PHP. But to demonstrate this example better, the socket connection between Ruby and Java seemed like a good idea. OK, let’s take care of the last part…
4) Download and extract this zip file on your OpenNebula head node, preferably inside your home directory. We recommend you put all the files in
opennebula_hooks_demo subdirectory, apart from the “demohooks.rb” script, which you should put as per #2 above (if not created already). Now open the
build.xml file and change the “basedir” property (line #1) to whatever your home folder is:
<project name="OpenNebulaHooksDemo" basedir="/YOUR_HOME_FOLDER/opennebula_hooks_demo" default="main">
5) We’re almost done, we just need to change of couple of settings:
Open the file
/YOUR_HOME_FOLDER/opennebula_hooks_demo/src/si/cloud/opennebula/MailSender.java and specify your e-mail server, username, password and other information required by
private static final String MAIL_HOST = "smtp.gmail.com";
private static final int MAIL_PORT = 465;
private static final String MAIL_USERNAME = "firstname.lastname@example.org";
private static final String MAIL_PASSWORD = "mypassword";
private static final String MAIL_FROM = "email@example.com";
private static final String MAIL_TO = "firstname.lastname@example.org";
To retrieve VM’s runtime information from OpenNebula, we use Java RPC API. Full API documentation can be found here, but for this example to work, you just need to double-check the basic connection settings. Open the file
/YOUR_HOME_FOLDER/opennebula_hooks_demo/src/si/cloud/opennebula/OpenNebula.java and change the settings accordingly.
private static final String ONE_RPC_HOST = "localhost";
private static final String ONE_RPC_PORT = "2633";
private static final String ONE_ADMIN_USERNAME = "oneadmin";
private static final String ONE_ADMIN_PASSWORD = "oneadmin";
6) Make sure Java 6 (or above) and Apache Ant are installed on your head node. You can run the example Java program by issuing the
ant command in the project’s base directory, e.g.
/YOUR_HOME_FOLDER/opennebula_hooks_demo (which should also be the directory containing Ant’s
If you encounter any problems setting up the system, please feel free to send me an e-mail or post a comment below.
Marcel Krizevnik and Matjaz B. Juric will attend Oracle Open World 2011 and JavaOne 2011 in San Francisco. Matjaz will also join the Product Briefing at the Oracle HQ, SOA / BPM Partner Advisory Council, SOA Partner Community Reception, SOA CAB, SOA Governance CAB, and several other meetings.
More info:OOW 2011
Next week we will have several presentation at SIOUG 2011:
- Keynote on Java EE 7 and the Cloud
- Presentation on BPM/SOA
- Workshop on BPM Suite 11g and SOA Suite 11g
More info: SIOUG 2011
Today, we had a presentation on SOA Architectural Patterns on the OpenBlend conference, which took place at Ljubljana Castle. There were a lot of participants. An amazing event, very recommended!