Table of Contents
This chapter introduces examples of using the ADK for Web Services. In this chapter <TOMCAT_ROOT> is used to describe the directory Tomcat is installed in and <AXIS_ROOT> is used to describe the directory Axis is installed in.
These examples use the Axis/Tomcat combination as webservices server. This combination was chosen because it is freely available. It is possible to use other systems to host the services but this has not been tested. If you want to use .NET webservices please take a look in the javadoc of the SendRPCMessageTask, it contains some notes about .NET. The first two examples (SOAPAgent and UDDIAgent) do not need a local Tomcat server as they use webservices available on the internet (you do need an internet connection to run them).
To compile and run the examples you need to install the Tomcat servlet server and the Axis web service library. You also need to copy the axis libraries to the directory <ADK_ROOT>\lib\webservices\axislibs and sign them. (See instructions below)
Install Tomcat 4.0.x or later . Make sure you choose a version that runs on JDK1.3 (the one that runs only on 1.4 needs libraries that are not by default in 1.3).
Install Axis 1.0 ( http://xml.apache.org/axis, not a more recent version) in Tomcat by copying the <AXIS_ROOT>\webapps\axis directory to the <TOMCAT_ROOT>\webapps directory. This is all that is needed to install Axis in the Tomcat server. For more information about webservices in Axis see the Axis manual.
Copy the jars from the <AXIS_ROOT>\lib directory to the <ADK_ROOT>\lib\webservices\axislibs directory and sign them by doing:
jarsigner -keystore ..\..\..\config\keystore1.dat -storepass developer1
<jarfile>.jar developer1
for all the jars in the directory. You can also use your own key to sign the files provided you set the permissions in the habitat accordingly. For more info do 'jarsigner -help' or see http://java.sun.com/j2se/1.3/docs/tooldocs/win32/jarsigner.html For more info on security and signing see the developer guide.
Copy the contents of the <ADK_ROOT>\examples\webservices\axis directory into the <TOMCAT_ROOT>\webapps\axis folder of the Tomcat tree. These are the example Web Services required by the example agents.
Start the Tomcat server:
cd <TOMCAT_ROOT>\bin
startup.bat
(see the <TOMCAT_ROOT>\RUNNING.txt file in the Tomcat tree for more informatin).
You can check if Tomcat is running by checking http://localhost:8080. If Tomcat runs you will see a default page.
You can check if Axis is running by checking http://localhost:8080/axis. If Axis runs you will see a page with some links to check parts of Axis.
We have several test agents that demonstrate the use of Web Services:
An agent making an SOAP-RPC call to a remote Web Service
An agent testing four different UDDI querying related tasks
An agent that calls stub code to access a locally running Stock Quotes Web Service
To learn more about the ADK and Web Services refer to the Developer Guide chapters "Web Services" and "Using Web Services with the ADK".
The SOAPAgent makes a RPC call to a remote Web Service ( http://www.mybubble.com:8080/soap/servlet/rpcrouter) that returns synonyms of a word passed as the method call parameter. To run it do:
cd <ADK_ROOT>\bin
habitat ..\examples\webservices\testsoapagent.xml
The output will be unpolished, just HTML that is printed to the terminal. This agent requests the server to return synonyms of the word car.
The UDDIAgent makes use of the IBM test UDDI ( http://www-3.ibm.com/services/uddi/testregistry/inquiryapi) to demonstrate different possibilities of searching a registry. To run it do:
cd <ADK_ROOT>\examples\webservices
habitat-uddi-example testuddiagent.xml
This example uses another script file because the UDDI library doesn't work with the crimson XML parser we use for the habitat. This example uses of the Xerces XML parser included in the lib\webservices\xerces directory.
The output will show the agent searching the White Pages, the Yellow Pages and do a UDDI Retrieve action.
The last test agent embeds the client code generated with the Axis tools. It shows how to make a SOAP call to a Web Service (a local one in this case) without using a SOAP library. The local Web Service used is generated using Axis Wsdl2java tool and runs at http://localhost:8080/axis/StockQuoteService.jws. To run it do:
cd <ADK_ROOT>\bin
habitat ..\examples\webservices\stubbasedstockquote.xml
The value of the stock named "XXX" is shown.
For these examples Tomcat is expected to run on port 8080.
This example shows how a document-style SOAP message can be sent to a Web Service.The Apache Axis library uses JAX RPC (not JAXM) so it is not possible to create agents that communicate with Web Services asynchronously. The example below shows how synchronous document messaging can be implemented.
To run the example, you need to have Tomcat running and the Web Service installed. See step 2 of the previous example. Afterward starting Tomcat you have to deploy the Web Service:
cd <ADK_ROOT>\examples\webservices\deployment
deploy.bat deploy_docmesservice.wsdd
Now, run the demo:
cd <ADK_ROOT>\examples\webservices\
set ADK_ROOT=<ADK_ROOT> (something like C:\adk)
..\..\bin\habitat docmessageagenthabitat.xml
When running the demo, you will see some output in the Tomcat console window (shell), as well as in the habitat window. The service prints out the order details received from the client (an ADK agent). The agent prints out the contents of the XML file (document-style SOAP message) received on request from the Web Service (DocumentMessageWebservice).
The ADK supports the creation of a Web Service to contact agents in a habitat. Thus, a Web Service can be used as an interface to an agent-application. The following chapter provides a basic system with examples that illustrate how to create your own customized Web Service interface. All examples use SOAP RPC-style messaging.
The system consists of three parts:
A habitat;
A Web Service client program; and
a Web Service that connects to the habitat.
The habitat is a standard habitat, and the client program can be created in the same way as any Web Service client, using languages other than Java. The important component of the system is the Web Service itself (Seen in blue in the following diagram).
Sending messages to an agent from a Web Service can be achieved by using the tryllian.are.messenger.jxta.JXTAMessenger In fact, any program can communicate with a habitat using this class. The example provided shows how this is done from a Web Service
This example discusses the following:
Setup of a Web Service system.
Deployment and usage of the basic system.
Creating your own Web Service.
If you have not already done so: Install Tomcat and Axis as described in the first web services example.
Before you can deploy the Web Service, you must copy a number of libraries to the <TOMCAT_ROOT>\webapps\axis\WEB-INF\lib folder. (In addition to the libraries already listed in the first web services example)
<ADK_ROOT>\lib\are.jar
<ADK_ROOT>\lib\are-common.jar
<ADK_ROOT>\lib\are-plugins.jar
<ADK_ROOT>\lib\runtime\are-runtime.jar
<ADK_ROOT>\lib\runtime\are-jxta.jar
<ADK_ROOT>\lib\runtime\jxta.jar
<ADK_ROOT>\lib\runtime\jxtasecurity.jar
<ADK_ROOT>\lib\runtime\log4j.jar
<ADK_ROOT>\lib\webservices\habitat-gateway.jar
Make sure you restart Tomcat after copying these files, otherwise Tomcat will not be able to locate the classes.
The Axis manual shows how to deploy a Web Service. The deployment descriptor looks like this:
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="SimpleTupleGateway" provider="java:RPC">
<!-- scope=Application: all requests are handled by _one_ instance -->
<parameter name="scope" value="Application"/>
<parameter name="className" value="tryllian.webservices.gateway.example.SimpleTupleGateway"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
An important part of this descriptor is the scope parameter: Setting this to "Application" causes the system to create only one instance to handle all requests to the Web Service. Without this setting, there would be a new instance for every request, but it is (currently) not possible to create more than one instance of a JXTAMessenger. JXTAMessenger is the essential part of the Web Service which allows you to communicate with a habitat.
Deploy the service:
cd <ADK_ROOT>\examples\webservices\deployment
deploy deploy_gateway.wsdd
Due to an issue in the current JXTA implementation it is not possible to run more than one JXTAMessenger per JVM. In the current setup this limits you to using only one webservice with agent communication. If you get an exception LocalHost can't be initialized twice, you need to undeploy any gateway previously deployed (run deploy undeploy_gateway.wsdd) and restart Tomcat. If you need more than one webservice to communicate with the habitat see Sharing a JXTACommunicator for a possible solution.
Note that you can check whether deployment was succesful by checking http://localhost:8080/axis and select the list of deployed webservices.
You need a running habitat to test the system. First, start the habitat:
cd <ADK_ROOT>\bin
habitat.bat
The habitat should start and display some startup information. When it is up and running, run TestSimpleTupleGateway to test the Web Service connection to the habitat. This tests the gateway by asking for the list of agent addresses. You need to supply the test with the habitat-id of the habitat to which you want to connect. This number is displayed when the habitat starts up. The system will assume the Web Service is running on http://localhost:8080/axis/servlet/AxisServlet.
['set' command should be all on one line, with no spaces in the path]
set CP=<ADK_ROOT>lib\webservices\axislibs\axis.jar;
<ADK_ROOT>\lib\webservices\axislibs\jaxrpc.jar;
<ADK_ROOT>\lib\webservices\axislibs\saaj.jar;
<ADK_ROOT>\lib\webservices\axislibs\commons-logging.jar;
<ADK_ROOT>\lib\webservices\axislibs\commons-discovery.jar;
<ADK_ROOT>\lib\webservices\habitat-gateway.jar;
<ADK_ROOT>\lib\runtime\crimson.jar;
<ADK_ROOT>\lib\runtime\jaxp.jar
java -cp %CP% tryllian.webservices.gateway.example.TestSimpleTupleGateway <habitat-id>
This should print a list of agent addresses of the agents in the habitat.
By default, the Web Service is configured to connect to a habitat running on localhost on the default port with the habitat-name "axis-habitat". You need to explicitly set this name in the habitat.properties file in your ADK installation.
The basic Web Service provided is useful, but you can also create your own Web Services with a custom API. If you write your own Web Service, you can totally hide the use of the habitat. This feature allows a regular Web Services user to seamlessly solve a problem without dealing directly with agents.
Suppose you want a Web Service that solves the following problem: Converting temperatures from Celsius to Fahrenheit and vice versa.
You can find the latest version of the code for this web service in the examples directory in your ADK installation.
Now, start a habitat containing the temperature agent:
cd <ADK_ROOT>\bin
habitat.bat ..\examples\webservices\temperatureconverter_habitat.xml
Make sure the previously deployed service is removed, and restart Tomcat. (see the note about running multiple messengers).
cd <ADK_ROOT>\examples\webservices\deployment
deploy undeploy_gateway.wsdd
cd <TOMCAT_ROOT>\bin
shutdown
startup
Note for GNU/Linux users: Make sure all Tomcat java processes are gone before you restart Tomcat. If there are any left: explicitly kill them Check <TOMCAT_ROOT>\logs\catalina.out to see if there were no exceptions during startup
Deploy the Web Service (the class file for the temperature agent is already in the file habitat-gateway.jar). Tomcat should already be started before deploying the Web service.
cd <ADK_ROOT>\examples\webservices\deployment
deploy deploy_temperature.wsdd
Run the example:
[set CP as shown above]
java -cp %CP% tryllian.webservices.gateway.example.TemperatureConverterClient convertToFahrenheit 3
It should print the following:
Converted temperature is: 37
The current implementation of JXTA only allows one JXTACommunicator per virtual machine. This prevents you from using more than one webservice that communicates directly with a habitat at a time. However, it is possible to let multiple webservices share one JXTACommunicator. The simplest way is to create one webservice that contains a JXTACommunicator and acts as a relay that other webservices can use. A slightly more complicated solution would be to create a messenger singleton that handles the messaging for all webservices. Please note that this messenger will need to be loaded from a classloader that all webservices can access. In Tomcat this means is should be loaded from the common\lib directory. We're working on a standard solution for this.