cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bugzi...@apache.org
Subject DO NOT REPLY [Bug 31359] New: - [PATCH] SOAP Flowscript Integration
Date Wed, 22 Sep 2004 11:57:08 GMT
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=31359>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=31359

[PATCH] SOAP Flowscript Integration

           Summary: [PATCH] SOAP Flowscript Integration
           Product: Cocoon 2
           Version: 2.1.4
          Platform: All
        OS/Version: Other
            Status: NEW
          Severity: Enhancement
          Priority: Other
         Component: Flowscript
        AssignedTo: dev@cocoon.apache.org
        ReportedBy: adam@mrigitech.com


Intro
-----

This code is an initial implementation of Luke Hubbard's concept of loading 
web services as objects within flowscript allowing their methods to be called 
using native data types as parameters.  The WebServiceLoader uses Apache Axis 
for the generation of client-side Java bindings and is limited to SOAP-based 
web services.

The impetus for writing this code came from the need to direct the application 
flow of control based upon the response from a remote SOAP web service.  As 
Luke pointed out all of the components needed to do this already existed in 
either the Cocoon or Axis projects so there wasn't so much for me to do.  I 
find accessing web services in this way useful and hope that this 
functionality can be added to Cocoon in some shape or form.

Flowscript
----------

flowWebServices.js in the attached archive shows how 2 SOAP services are 
called from the flow layer using the WebServiceLoader, the example services 
are listed at http://www.xmethods.net.  The steps required to call a SOAP 
service using the loader are:

- import the WebServiceLoader class in the script file
- create an instance of the loader using the cocoon object so that the 
component is correctly initialized
- load the web service as a local object by passing the WSDL URI to the 
loader, optionally naming the required service and port
- call methods on the web service as a local object

No external Java code is needed.

Java Implementation
-------------------

The class org.apache.cocoon.components.flow.ws.WebServiceLoader.java is 
responsible for loading the web service. It coordinates parsing of the WSDL, 
endpoint selection, generation of the java client side bindings, and dynamic 
compilation of the desired endpoint client proxy. The WebServiceLoader 
implements several Avalon interfaces:

- Contextualizable: the Avalon context is needed for accessing the 
cocoon 'work-directory' property. Generated java files are created in a 
subdirectory of the work directory.
- ThreadSafe: I believe implementing this interface ensures that only one 
instance of the class is created per container. The WebServiceLoader holds a 
reference to an instance of the CompilingClassLoader.  The intention here was 
to avoid unnecessary re-compilation of the client bindings. I do confess I 
didn't look deeply into the workings of the CompilingClassLoader having lifted 
it more or less directly from the FOM javascript interpreter.
- Serviceable: the ServiceManager is used to lookup a SourceResolver for 
construction of the classloader.
- LogEnabled: for logging.

The WebServiceLoader creates an EndpointDefinition.  The class 
org.apache.cocoon.components.flow.ws.EndpointDefinition.java is essentially a 
wrapper around an instance of javax.wsdl.Definition.  An EndpointDefinition 
instance represents a unique service/port combination declared within the WSDL 
document.  If the service and port name aren't supplied when the web service 
is loaded the WSDL is navigated and the 1st service declared in the document 
with a port with a SOAP binding is selected as the default service.

Once an EndpointDefinition has been created client bindings are generated from 
the WSDL by org.apache.cocoon.components.flow.ws.ClientBindingGenerator.java.  
This class extends the WSDL2Java utility from the Apache Axis project, it's 
purpose is purely to allow for programmatic invocation of the tool.  The 
generated classes are created in a subdirectory of the cocoon work directory.

Now that the client bindings have been created an instance of the client 
endpoint proxy is dynamically instantiated by reflection and it is this object 
that is returned to the calling flowscript.  The proxy object is put in a 
cache before being returned to the client.

I hope that this code might be a starting point for getting this functionality 
into Cocoon, my understanding of the Cocoon architecture might be a little bit 
thin to bring this up to scratch for inclusion in the project.

Cheers
Adam

Mime
View raw message