My first WSRFLite service

Roland Kübert

Revision History
Revision 0.315.05.2008rk - kuebert@hlrs.de
UNICORE took over the proposed changes to start.sh and added a batch script for Windows; corresponding sections were adapted.
Revision 0.230.04.2008rk - kuebert@hlrs.de
Minor layout and spelling corrections. Added license information.
Revision 0.103.04.2008rk - kuebert@hlrs.de
First draft.

Abstract

WSRFLite is a lightweight hosting environment for services using the Web Services Resource Framework (WSRF). Development is, in general, straightforward and simple, but the documentation supplied with WSRFLite is, at best, sketchy. It is sometimes outdated, sometimes just incomplete and sometimes nonexistent - a fate that most documentations share. This article tries to give a simple and direct introduction on how to obtain WSRFLite, install it, configure it, build and deploy a first service and, finally, access it with a client. The scope of this article is narrowed down to the points mentioned above and, therefore, no introduction to WSRF or web services in general is given.

This document is licensed under the Creative Commons Attribution-Noncommercial 2.0 Germany license, which can be found at http://creativecommons.org/licenses/by-nc/2.0/de/deed.en.


Table of Contents

1. Obtaining WSRFLite

WSRFLite can be obtained via the Download page at Sourceforge.net (direct download). Don't bother looking at Unicore.eu because you will finally be redirected to Sourceforge anyway.

As of the writing of this document, v1.8.6 is the current stable release; it has been released on 23. January 2008. The name of the archive file is wsrflite-1.8.6-all.zip.

2. Installation

Saying installation is perhaps a bit to exaggerated, since what you really have to do is simply unzip the downloaded archive. It does not really matter where you unzip it though. Under Windows, I recommend something like c:/dev/wsrflite-1.8.6, while under Linux you may just unzip it to your home directory so that you get ~/wsrflite-1.8.6 or, if you have the privileges, do as I do and put it under /opt/wsrflite-1.8.6.

Anyways, from now on I will refer to the installation directory just as $WSRFLite. And in case that you wondered: yes, that was the whole installation. ;)

3. Configuration

The central configuration file for WSRFLite is $WSRFLITE/conf/wsrflite.xml. It contains generic parameters, for example if SSL should be used an where the containers keystore is located, and service descriptions, which detail on the deployed services. For using the example shop service, you have to change the service description; you also have to change the path to the keystore and, if you do not necessarily need SSL, you should disable it.

3.1. Disabling SSL

To disable SSL, just change the property unicore.wsrflite.ssl from true to false.

This gives us the possibility to monitor packages as they are going over the wire.

3.2. Specifying the keystore

The keystore specified in wsrflite.xml is wrong; technically, when you disable SSL you do not need to correct it, but since you will sooner or later trip over this error, there's no point in not adding 5 letters to the config file. ;)

Change the value of the property unicore.wsrflite.ssl.keystore from demo_keystore to conf/demo_keystore. As already said, if you start the server with SSL disabled, this property is never read; if you start it with SSL enabled, you get an exception:

	SCHWERWIEGEND: Could not start server.
	java.io.FileNotFoundException: /opt/wsrflite-1.8.6/demo_keystore (No such file or directory)
    	at java.io.FileInputStream.open(Native Method)
	

If the keystore is specified correctly, you get this in the logging statements:

	INFO: Security Settings:
	SSL is enabled
	Using keystore conf/demo_keystore, type JKS.
	

3.3. Specifying the deployed services

wsrflite.xml also contains specifications for services which are deployed in the container. The initial specification does not correspond to the services that will be developed and deployed using the example code, it just shows how plain and WSRF services have to be specified, so you have to change that. The initial example looks like this:


<service name="shop" wsrf="false">
   <interface class="example.PlainService" />
   <implementation class="example.PlainServiceImpl"/>
</service>

<service name="cart" wsrf="true">
   <interface class="example.WSRFService" />
   <implementation class="example.WSRFServiceImpl"/>
</service>

	

Change it to the following code:


<service name="shop" wsrf="false">
   <interface class="example.IShop" />
   <implementation class="example.ShopImpl"/>
</service>

<service name="cart" wsrf="true">
   <interface class="example.ShoppingCart" />
   <implementation class="example.ShoppingCartHomeImpl"/>
</service>

	

A side note: at this point, you cannot start the container, regardless if you have changed the deployment information or not. You will receive a ClassNotFoundException anyway because the classes specified in wsrflite.xml have not been deployed to the $WSRFLITE/lib directory.

4. Building your first service

As we will be using the example service supplied with WSRFLite as our first service, we do not have to terribly much.

Firstly, change to the example directory $WSRFLITE/doc/example. There, run ant xmlbeans, which will generate schema beans from the schema file schema/example.xsd and jar them into the file myXmlBeans.jar. Copy this file $WSRFLITE/lib.

Now we need to compile the implementation classes, jar them and copy them to the lib directory as well. Therefore, run ant compile, which compiles the source files and puts them into the classes directory. Jar them up with jar cfv example_service_implementation.jar -C classes/ . and copy them to $WSRFLITE/lib as well

Run the start script ($WSRFLITE/bin/start.sh or $WSRFLITE/bin/start.bat and check that the container comes up without problems.

5. Building the first client

All that is missing now is a simple client. Just take the code provided below:

package de.hlrs.unicore.clients.shop;

import org.example.AddItemRequestDocument;
import org.example.AddItemResponseDocument;
import org.example.CreateShoppingCartDocument;
import org.example.CreateShoppingCartResponseDocument;
import org.example.AddItemRequestDocument.AddItemRequest;
import org.example.ItemDocument.Item;
import org.example.ItemDocument.Item.Factory;
import org.oasisOpen.docs.wsrf.rp2.GetResourcePropertyDocument;
import org.oasisOpen.docs.wsrf.rp2.GetResourcePropertyResponseDocument;
import org.w3.x2005.x08.addressing.EndpointReferenceType;

import de.fzj.unicore.wsrflite.xfire.XFireClientFactory;
import de.fzj.unicore.wsrflite.xmlbeans.BaseFault;
import de.fzj.unicore.wsrflite.xmlbeans.client.BaseWSRFClient;
import de.fzj.unicore.wsrflite.xmlbeans.exceptions.InvalidResourcePropertyQNameFault;
import de.fzj.unicore.wsrflite.xmlbeans.exceptions.ResourceUnavailableFault;
import de.fzj.unicore.wsrflite.xmlbeans.exceptions.ResourceUnknownFault;
import example.IShop;
import example.ShoppingCart;

public class ShopClient {
	
	public ShopClient() {
		System.out.println("Running ShopClient");
		
		EndpointReferenceType epr1 = EndpointReferenceType.Factory.newInstance();
		epr1.addNewAddress().setStringValue("http://localhost:7777/services/shop");
		CreateShoppingCartResponseDocument createNewShoppingCart = null;
		try {
			BaseWSRFClient shopClient = new BaseWSRFClient(epr1);
			IShop shopProxy = shopClient.makeProxy(IShop.class);
			
			CreateShoppingCartDocument createShoppingCartDocument = CreateShoppingCartDocument.Factory.newInstance();
			createShoppingCartDocument.addNewCreateShoppingCart();
			createNewShoppingCart = shopProxy.createNewShoppingCart(createShoppingCartDocument);
			System.out.println("Response: " + createNewShoppingCart);
			
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(0);
		}

		ShoppingCart proxy = null;
		try {
			XFireClientFactory clientFactory = new XFireClientFactory();
			EndpointReferenceType cardEpr = createNewShoppingCart.getCreateShoppingCartResponse().getEndpointReference();
			proxy = clientFactory.createProxy(ShoppingCart.class, cardEpr.getAddress().getStringValue(), cardEpr, null);
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(0);
		}
		
		AddItemRequestDocument requestDocument = AddItemRequestDocument.Factory.newInstance();
		AddItemRequest request = AddItemRequest.Factory.newInstance();
		Item item = Factory.newInstance();
		item.setID("ItemId");
		item.setName("Foo");
		item.setPrice(5.0f);
		request.setItem(item);
		requestDocument.setAddItemRequest(request);
		
		AddItemResponseDocument responseDocument = proxy.add(requestDocument);
		System.out.println("Response: " + responseDocument);

		// Query cart
		try {
			GetResourcePropertyDocument getResourcePropertyRequest = GetResourcePropertyDocument.Factory.newInstance();
			getResourcePropertyRequest.setGetResourceProperty(ShoppingCart.RPEntryQName);
			GetResourcePropertyResponseDocument getResourcePropertyResponse = proxy.GetResourceProperty(getResourcePropertyRequest);
			System.out.println("Resource Property document: "+ getResourcePropertyResponse);
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(0);
		}
	}
	
	public static void main(String[] args) {
		new ShopClient();
	}

}
	

If everything worked, you should get an output like this:


Running ShopClient
27.04.2008 13:00:53 de.fzj.unicore.wsrflite.Kernel printHeader
INFO: WSRFlite 1.8.6-SNAPSHOT (c) Forschungszentrum Juelich 2006-2008
Response: <exam:CreateShoppingCartResponse xmlns:exam="http://example.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <add:EndpointReference xmlns:add="http://www.w3.org/2005/08/addressing">
    <add:Address>http://localhost:7777/services/cart?res=47898d1a-f096-4191-b039-1ef875b690c0</add:Address>
  </add:EndpointReference>
</exam:CreateShoppingCartResponse>
Response: <exam:AddItemResponse xmlns:exam="http://example.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
Resource Property document: <rp:GetResourcePropertyResponse xmlns:rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <exam:Entry xmlns:exam="http://example.org">
    <exam:Item>
      <exam:name>Foo</exam:name>
      <exam:ID>ItemId</exam:ID>
      <exam:price>5.0</exam:price>
    </exam:Item>
  </exam:Entry>
</rp:GetResourcePropertyResponse>

	

6. Summary

Just to shortly sum up what we achieved in this tutorial. We downloaded and installed WSRFLite, configured WSRFLite to our liking, built our first service, deployed it and configured a client to access the service.

Based on this article, you can begin to build more complex services and hopefully have a productive use of WSRFLite.