DEVELOPERS GUIDE
This page contains detailed instructions on creating new Web Services
for JClarens.
Installation Instructions
See the Installation Guide.
Configuration
There are two files that can be used to configure jclarens. The first
is in webapp/WEB-INF/classes/log4j.properties. This file contains the
logging settings for jclarens. The last line can be used to change the log
level. Change DEBUG to WARN, ERROR, FATAL, INFO, or OFF. The other
log settings can be customized according to the log4j configuration rules.
See http://jakarta.apache.org/log4j/docs/documentation.html for information on
configuring log4j.
The second file lives in webapp/xmlrpc_handlers.properties. This file
contains the configuration settings for the individual service handlers
and for JClarens in general. Service handler configurations are described
in the 'Service Adapter Configuration' section below.
ADDING NEW JCLARENS SERVICES
For the impatient
1) Generate or obtain a WSDL for your service using whatever method you prefer.
2) Install jclarens.
3) Download and unzip the HelloWorld sample source code from SourceForge:
http://sourceforge.net/project/showfiles.php?group_id=53073&package_id=114981
4) Modify the ant buildfile build.xml file and make the following changes:
- the project name on the first line should be any name you want. This
does not have to match the name of the service.
- The service.name property at line 18 should be the name of your
service. Don't use spaces, underscores or other punctuation here.
- (optional) The java package path for your service at line 19.
5) If you did not install jclarens into the default location
(/usr/lib/jclarens), then you must set the actual jclarens installation
directory in build.properties. On Windows, the backslashes in the path should be replaced with double backslashes (e.g. "c:\\jclarens" instead of "c:\jclarens").
6) Copy your service wsdl into the same directory that contains the build.xml
file, and rename it to match the service.name property in build.xml. For example, if your service name is newhelloworld, then the wsdl should be newhelloworld.wsdl.
7) run ant wsdl2java to generate the java interface class and SOAP binding
classes. These are placed in the 'java' subdirectory, using a directory
hierarchy that matches the package path that you (optionally) set in step 4.
8) Create an implementation of your service interface and put it in the
same directory as the service interface. OR, just put in your implementation code into the *SoapBindingImpl.java file created by 'ant wsdl2java'.
9) Copy the java/.../helloworld/HelloWorldXmlRpcBinding.java
template to the same directory that now contains your new SOAP binding
files, and rename it to any suitable name.
10) Customize the xmlrpc binding class to suit your service. The execute()
method must be updated with a set of if/else statements, one for each
method in your web service. Each if/else block should perform any argument
checking, and convert the xmlrpc parameters to the data types expected by
your service implementation class. It must also convert any return objects
from your service implementation class into the appropriate xmlrpc data
types (Vector, Hashtable, Integer, Boolean, or String).
11) Rename the helloworld_service.properties file to <your_service_name>_properties, and modify it according to your service. Most importantly, place the names of the correct implementation, interface and xmlrpc binding classes.
12) Run ant jar to make sure that the code compiles correctly. Run ant install to build and install your new service into your jclarens installation. The user running ant install must have write permissions to the jclarens installation directory.
13) Add a line to
$jclarens_install_dir/jakarta-tomcat-*/webapps/jclarens/xmlrpc_handlers.properties
of the following form:
service.<your_service_name>.properties=<your_service_name>_service.properties
(e.g. service.newhelloworld.properties=newhelloworld_service.properties)
This will 'turn on' the service the next time you restart jclarens.
14) Restart jclarens. Use your favorite Clarens/SOAP/XMLRPC client to
connect to the server and test your service. Look in the jclarens log
files for any debugging or error messages:
$jclarens_install_dir/logs/jclarens.log
$jclarens_install_dir/logs/jclarens_traffic.log
$jclarens_install_dir/logs/catalina.out
15) (Optional) Rename the jclarens-helloworld.spec template and customize it for your service.
16) (Optional) Run 'ant rpm' to build an installable RPM package for your service. This is a very verbose command, and you should look for (and fix) any warnings
that it detects. Make sure to increment the version or release number
for every new release of your service.
Now for the whole story
JClarens uses a single servlet to handle both incoming xmlrpc and soap
requests. This servlet looks at the first few lines of the xml payload
to determine if it is a soap or xmlrpc message. xmlrpc messages are
passed to an embedded Apache XmlRpc engine for processing. These
engines look at the methodName element in the xml payload for the
service method name and passes control to a xmlrpc handler object that
was written specifically to handle requests for that method. The
handler executes any necessary actions and returns a java object (or
array of objects) back to the controlling servlet. The servlet
serializes the response objects and returns a xml response document back
to the client.
The steps involved in writing new service handlers for jClarens include:
1) Create a WSDL for your service
2) Generate the server side stubs for the service
3) Implement the service interface
4) Write the xmlrpc binding file
5) Write a simple properties file describing your service
Additional optional, but very useful steps are:
6) Install for testing
7) Update spec file template
8) Create rpm
9) Install rpm
Writing a Jclarens Handler
There are three main pieces to a jclarens handler. The first is the
service interface. This interface describes the method signatures of
the web service. The second piece is an implementation of the service
interface. This is where the service's real work takes place. The third
piece is an xmlrpc/soap wrapper around the interface to allow it to be
invoked via the xmlrpc/soap protocol.
The separation of the service interface/implementation from the
xmlrpc/soap layers makes it easier to support new protocols (rmi, etc.)
at a later time. xmlrpc has a limited set of data types that get passed
over the wire (Vector, Hashtable, and some primitives) that don't always
match the data types that the service methods expect. The xmlrpc
wrapper translates the xmlrpc data types into data types that the
service interface expects.
jClarens provides a template for creating new jClarens services. This
template contains an ant buildfile, sample wsdl, sample rpm spec file,
and sample xmlrpc binding file. This template is a good starting point
when creating new jClarens services.
1) WSDL
The Single Point of Truth for a Web Service interface description is the
WSDL document. This document describes the method signatures for a Web
Service, including descriptions of complex input and output data
structures, in a language-neutral manner. WSDL is a human readable (but
sometimes not so easy to write) and machine readable document. Java
interfaces can be generated from the WSDL, which is the preferred method
for creating the java interface classes. There are a number of ways to
create the initial WSDL file. An XML editor can be used, or a tool such
as java2wsdl can be used to create WSDL from java interface files. The ant buildfile in the
template has a 'java2wsdl' target to make the process of generating the
WSDL from a Java interface class easier.
* Note: Do not use an underscore ('_') as part of the service name.
2) Interface
The WSDL2Java tool can be used to create java interfaces from a WSDL
document. If the WSDL was written correctly then no changes should be
necessary to the generated java file. If changes are required, they
should be made in the WSDL and the java interface regenerated. It is
important to run the WSDL2Java tool even if the WSDL was generated from
existing java interface files because WSDL2Java creates the server-side
SOAP stubs in addition to the java interface. The ant buildfile in the
template has a 'wsdl2java' target to make the process of generating the
interface files and server side stubs easier.
3) Service Implementation
The service implemtation is a new class that implements all of the
methods in the service interface. The service implementation class must
be declared to "implement" the service interface class. After running
ant wsdl2java, a SoapBindingImpl class will be generated that can be
used as a starting point for the service implementation.
4) xmlrpc wrapper
The service implementation performs the work of the web service, but has
no knowledge of the transport protocol used for the service invocation.
'wsdl2java' generates binding classes for the SOAP protocol, but not for
xmlrpc. A xmlrpc binding wrapper must be written in order to access the
new service via xmlrpc. This binding wrapper has the task of converting
the xmlrpc-encoded input and output parameters from Vectors and
Hashtables into the native interface types. The service template shows
an example of what this xmlrpc binding wrapper looks like.
If the service implementation requires any special configuration at creation
time (such as a database username/password), then it can use the
pk.edu.niit.clarens.util.ConfigurationProps class. This class allows the
handler to load configuration settings from the service specific configuration
file (described in more detail in Service Adapter Configuration) .
Registering a new service handler involves the creation of a new
properties file that describes the interface, implementation class,
xmlrpc binding class, version numbers, wsdl filename, and any service
specific configurations. The properties in this file take the form:
service.<servicename>.<key>=<value>
For example, the echo service interface is described by the following entry:
service.echo.interface=pk.edu.niit.clarens.services.echo.Echo
The word "echo" following the first "service." indicates that this property
is for the "echo" service. The second half of the property
"pk.edu.niit.clarens.services.echo.Echo" is the name of an interface that
defines the web service.
The required properties for a new service handler are:
service.<servicename>.interface=pk.edu.niit.clarens.services.helloworld.HelloWorld
service.<servicename>.handler=pk.edu.niit.clarens.services.helloworld.HelloWorldXmlRpcBinding
service.<servicename>.impl=pk.edu.niit.clarens.services.helloworld.HelloWorldImpl
service.<servicename>.major_version=0
service.<servicename>.minor_version=65
service.<servicename>.wsdd=wsdd/servicename_deploy.wsdd
If the service requires additional runtime configuration (such as a database
username/password, or some file path) then the service implementation can make use of the pk.edu.niit.clarens.util.ConfigurationProps
class to load configuration properties. For example, the configuration property service.echo.mypropertyname=foobar is loaded using the following code snippet:
String valueFromConfig = ConfigurationProps.getInstance("echo").getProperty("mypropertyname");
The final step for hooking the new service into jClarens is to make add
a new entry to jClarens' xmlrpc_handlers.properties file. This entry
simply points to your new service adapter configuration:
service.<servicename>.properties=sample_service.properties
Sample service build targets
The sample service contains several build targets to assist in the
creating, building, installation, and packaging of a new service.
The buildfile reads the local build.properties file in order to locate
the jclarens jar files necessary for compiling the service. It should only
be necessary to verify that the 'jclarens.base' property points to the
root of your jclarens installation.
'wsdl2java': This target generates the service interface file and soap
bindings from the WSDL. The wsdl file must be located in the
same directory as the ant buildfile. The name of the WSDL file
must match the name of the new service. The generated files
are placed in the java directory using the package path
that was defined in the build.xml file.
'java2wsdl': This target generates a wsdl from a compiled java
interface file.
'classes': Compile the class files.
'install': Installs the new web service into your local jclarens
installation. The web service files are copied into the
${jclarens.base}/jakarta-tomcat-5.0.28/webapps/jclarens
directory.
'releasezip: Build a source zip file for the new web service.
'rpm': Create a binary rpm package for the new web service. This
binary rpm will have a dependency on the jclarens base rpm.
|