Uploaded image for project: 'Cocoon'
  1. Cocoon
  2. COCOON-1274

[PATCH] SOAP Flowscript Integration


    • Type: Improvement
    • Status: Closed
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: 2.1.4
    • Fix Version/s: None
    • Component/s: - Flowscript
    • Labels:
    • Environment:
      Operating System: other
      Platform: All
    • Bugzilla Id:



      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.


      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.





            • Assignee:
              reinhard@apache.org Reinhard Poetz
              adam@prema.co.nz Adam Ratclife
            • Votes:
              0 Vote for this issue
              0 Start watching this issue


              • Created: