Axis demo

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

Short walkthrough

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.

Publish docuents to a 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.

Exposing a service as a webservice

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:

  1. Firstly we embed an axis.war in our sar-file. (It might also be ok to use the JBoss-net service directly, but its has not been tested). In this way we get a channel specific axis deployment. The naming if the war-file is important, since the context path of our webservice will be created by that name. Here we have named in axis-demo.war. Here is how it is copied in maven.xml:
     
    		<a:copy
    	            file="${pom.getDependencyPath('axis:axis-web')}"
    	            tofile="${maven.build.dir}/axis-demo.war"/>
                
  2. Second we create an external amsterdam channel.Here we use the org.backsource.amsterdam.plugins.jmx.ExtendedEntrance which exposed a number of convenience methods that will create a ServiceMessage. In the example we also use the XPath attribute. This will select only a part of the incoming document to send into the chain. This may be valuable since the document will be a SOAPifyed message.
      
      <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>
    
  3. Next we need to deploy our webservice. This is done with the help of the mbean org.backsource.axis.DeployerServiceJMX. Here a couple of things is important to note. The url:s that are use to deploy the service must be coordinated with the naming of the axis.war. See the ServletPath and the definition of the operation. Secondly that we use a custom axis handler: org.backsource.axis.MBeanProxyProvider. This handler is the gateway into the ExtendedEntrance bean. It must be configured the ObjectName of the Entrance bean and an interface.
      
       <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>
    
  4. Last we have to setup the REC invoker in the amsterdam configuration and tell it to register in the Entrance bean:
         
               <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.