The axis demo demonstrates the usage of publishing to a webservice endpoint and how to deploy a webservice entrance into an amsterdam service. It also shows how to backup, transform and select on the messages.
The demo uses the more modern approach to deploy a channel as a JBoss service.Here is the jboss-service.xml
To get a feeling of how the jboss-service descriptor may be used, and how a GET channel may be set up, please begin by reading the simplejms walkthrough.
As in simplejms we have two services. One that fetches documents from its subdirectory of JBoss data directory and publish them to a webservice, and one that expose the service as an Axis webservice.
The major part of the GET service looks much like the simplejms. It ends with a publisher that send the documents it gets to the webservice the other service expose.
The only really important thing to note here is that the url to the webservice is decided by how the embedded axis.war is named,more on that further down.
<publisher
className="org.backsource.amsterdam.plugins.axis.AxisHandler">
<ws-url>http://localhost:8080/axis-demo/services/DeliverDocument</ws-url>
<ns>http://localhost:8080/axis-demo</ns>
<method>handleDocument</method>
<user>vv</user>
<password>vv</password>
</publisher>
Another this worth mentioning is the packing strategy used here. As in the simple jms example we uses the JBoss feature to get an unpacked dir in its datadir. Included in the axis-demo.sar are some example files.
0 05-26-04 11:18 channels/axis-demo/data/.keep
1705 05-26-04 16:14 channels/axis-demo/examples/newversion.xml
1684 05-26-04 15:13 channels/axis-demo/examples/oldversion1.xml
1602 05-26-04 15:17 channels/axis-demo/examples/oldversion2.xml
Which will be unpacked in for example
jboss-3.2.3/server/default/data/channels/axis-demo/ |-- data |-- examples | |-- newversion.xml | |-- oldversion1.xml | `-- oldversion2.xml
Just copy one of the files into the data dir and the service will pick it up.
The reveiving channel gets its data through a webservice. This is created with the same principles as in the simple jms example. There a basically for parts involved in this:
<a:copy
file="${pom.getDependencyPath('axis:axis-web')}"
tofile="${maven.build.dir}/axis-demo.war"/>
<mbean code="org.backsource.amsterdam.plugins.jmx.ExtendedEntrance"
name="amsterdam.channel:service=Service,name=wsin">
<depends>amsterdam:service=AmsterdamChannel,name=axis-demo</depends>
<!-- Strip SOAP stuff -->
<attribute name="XPath">/*/*</attribute>
</mbean>
<mbean code="org.backsource.axis.DeployerServiceJMX" name="axis:service=Deployer,name=axis-demo">
<!-- jboss.web.port -->
<attribute name="Port">8080</attribute>
<attribute name="ServletPath">axis-demo/services/AdminService</attribute>
<attribute name="Wsdd"><deployment
name="JMX.net.test"
targetNameSpace="http://net.jboss.org/jmx/test"
xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:jmx="http://net.jboss.org/jmx/test"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="DeliverDocument"
style="message" provider="Handler">
<parameter name="handlerClass"
value="org.backsource.axis.MBeanProxyProvider"/>
<parameter name="ObjectName"
value="amsterdam.channel:service=Service,name=wsin"/>
<parameter name="InterfaceName"
value="org.backsource.amsterdam.plugins.axis.AxisEntrance"/>
<parameter name="allowedMethods" value="handleDocument"/>
<operation name="handleDocument" qname="tt:DeliverEvents"
returnQName="tt:DeliverEventsReturn"
returnType="type:Document"
xmlns:type="http://xml.apache.org/xml-soap"
xmlns:tt="http://localhost:8080/axis-demo">
<parameter name="events" qname="Events"
type="type:Document"/>
</operation>
<requestFlow>
<handler
type="java:org.backsource.axis.UserPasswordAutenticationHandler">
<parameter name="allowedUser" value="vv"/>
<parameter name="allowedPassword" value="vv"/>
</handler>
</requestFlow>
</service>
</deployment>
</attribute>
</mbean>
<rec-service-invoker
className="org.backsource.amsterdam.service.jboss.RecMBeanServiceInvoker"
name="amsterdam.channel:service=Service,name=wsin"
use-bean="true"
/>
Dependencies in the service is resolved by the order the beans are defined in the jboss-service.xml file.
The other important part of the service is the filter chain. Lets step though it.
First we use an Id filter. This is neede if we want to use a filter that need an url from the ServiceMessage. Since many receiving invokers have no ability to get an id for the message (no filename to use) an abstract url needs to be generated. the IdFilter will create an id url that is a time-stamp.
<filter className="org.backsource.amsterdam.plugins.varia.IdFilter">
</filter>
Next we uses a backup filter. It is often convenient to save the incoming data in a raw form before it is worked upon.
<filter className="org.backsource.amsterdam.plugins.file.FileHandler">
<filter-conf>
<directory>${jboss.server.data.dir}/channels/axis-demo/raw-backup</directory>
</filter-conf>
</filter>
Observe that we use the jboss.server.data.dir property to find the directory to backup into. This directory will have been automatically created since we include it in the sar-file (trough the use of empty .keep files):
0 05-26-04 11:10 channels/axis-demo/raw-backup/.keep
0 05-26-04 11:10 channels/axis-demo/msg-backup/.keep
After that we have a transforming filter. In this case an xsl that will transform a new xml format to an old one. Here a lot of things are set up:
<filter className="org.backsource.amsterdam.plugins.xml.TransformerFilter">
<filter-conf>
<dom-cached-stream factory="org.backsource.utils.io.DOMCachedStreamFactory">
<param name="encoding">iso-8859-1</param>
</dom-cached-stream>
<resolver base="/xsl/">
</resolver>
<filter-map>
<filter-map-entry namerefs="wsin">
<xsl>versiontransform.xsl</xsl>
</filter-map-entry>
</filter-map>
</filter-conf>
</filter>
Our first step is to setup a cached stream factory. The point in doing this is that a lot of the plugins components support caching of the data in a ServiceMessage. This is often very convenient since data in a ServiceMessage is often an InputStream, and every filter that looks into that stream will exhaust it. Instead of that every filter needs to cache the original stream, peek into it and then reconstitute it, this is handled by base components and the cached stream api, which produces streams that are rewindable.
Next we configure a resolver. Here we do not use this powerful feature much, but it may be configured with an XML catalog with advanced mappings of entries. Here we set its base url to resolve against as /xsl. This will actually be used as a base url against the classpath.
We then set up a filter-map. A filter map is a map of stylesheets configurations. Which filter-map-entry that is used is decided by the ContentMapEntry in the ServiceMessage that travels through the invocation chain.Here we give an xsl-file (its also possible to specify parameters to the xsl-file.
The location of the xsl file will actually also be resolved through the configured resolver (which among all its capable of doing resolves through the classpath). The xsl-file is therefore includes in the sar-file:
2790 05-27-04 09:32 xsl/versiontransform.xsl
We also use a selecting filter: XPathFilter. With this filter its possible to select which messages should be allowed to continue down the chain, and which should not be allowed this:
<filter className="org.backsource.amsterdam.plugins.xml.XPathFilter">
<filter-conf>
<xpath>/ResponseSituation/Situation/SituationElement/ElementLocation/LocationCodeExtent[FirstLocationCode=16269]</xpath>
</filter-conf>
</filter>
We end the chain by backing up the transformed data of the messages that passed the XPathFilter.