« How to Read WSDL | Main | Invoking BPEL from Delphi »

Invoking BPEL from an HTML Form

Invoking BPEL from HTML


Lets look at how to invoke a BPEL process directly from an HTML form.  This is useful if you want to bang a quick front end onto a BPEL process and want someone else to look at the data in and out of a process without giving them access to the java console.


So basically what we want is a WSDL description that has an HTTP GET or POST binding so that we can invoke it from a simple HTML form.  Lets go through the steps to create this process using JDeveloper.


1. Create the Process


I went into JDeveloper and created a new BPEL process, in this case I called it HTMLInvoked and I selected a "Synchronous" process as we want the GET or POST to actually get some data back.


This gives me the simple process shown below.



Simple BPEL Process


2. Modify the WSDL


We now need to change the WSDL so that it has an HTTP binding.  Lets go through the WSDL a section at a time and look at the changes necessary.


I. Add Namespaces to the Description


We will be using some additional namespaces so we need to add these into the "definitions" tag to make them available to the WSDL.


<definitions name="HTMLInvoked"
targetNamespace="http://xmlns.oracle.com/HTMLInvoked"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:client="http://xmlns.oracle.com/HTMLInvoked"
xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"

The xsd namespace is included because we will be using some XSchema types outside of the types section of the WSDL.  The mime namespace is included to allow us to identity the type of the HTTP response.  Finally the http namespace is included to allow us to use the HTTP binding elements.


II. Clean up the Types


We won't be passing in a complex XML document, and so we don't need the default input message type of HTMLInvokedProcessRequest in the Types section, so lets delete it leaving us with the following types definition.


<types>
<schema attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace="http://xmlns.oracle.com/HTMLInvoked"
xmlns="http://www.w3.org/2001/XMLSchema">
<element name="HTMLInvokedProcessResponse">
<complexType>
<sequence>
<element name="result" type="string"/>
</sequence>
</complexType>
</element>
</schema>
</types>

We will leave this to just return an XML document containing a single string.


III Modify the Input Message


We now need to modify the input message to be able to receive parameters from an HTML form.


<message name="HTMLInvokedRequestMessage">
<part name="firstname" type="xsd:string"/>
<part name="lastname" type="xsd:string"/>
</message>
<message name="HTMLInvokedResponseMessage">
<part name="payload" element="client:HTMLInvokedProcessResponse"/>
</message>

Here we have changed the message to be a multi-part message. We need one part for each parameter we will be passing from our HTML form.  The part names will match the names of the parameters in the form.  Note that the parts have a type attribute rather than an element attribute.  This explains the need for the declaration of the xsd namespace.


IV Add a Binding Definition


We could leave the Port Type unchanged but I decided to change the operation name to be something more meaningful than "process" - I called it "Hello" as I am going to have a Hello World process.  This leaves the Port Type looking like this.


<portType name="HTMLInvoked">
<operation name="Hello">

<output message="client:HTMLInvokedResponseMessage"/>
</operation>
</portType>

Note that if you do change the operation name you will need to go back the BPEL file generated and change the operation name in the "receive" and "reply" BPEL operations.


We now need to describe how to map this Port Type onto a concrete protocol, such as an HTTP GET.  For this we need to declare a Binding similar to the one below.


<binding name="HTMLInvokedBinding" type="client:HTMLInvoked">
<http:binding verb="GET" />
<operation name="Hello">
<http:operation location="/Hello" />

<http:urlEncoded />

<output>
<mime:mimeXml part="Body" />
</output>
</operation>
</binding>

This declares that we are providing a binding for the "HTMLInvoked" port type.  We now use the http namespace to bind this onto HTTP GET operations.  For the operation name "Hello" in the Port Type we are mapping it to a URL path "/Hello".  Input message is going to be url encoded and the response is going to be an XML document.


V Add a Service Definition


We are now on the last leg. We just need to tell people where the service is located.  To do this we need a Service definition.


<service name="HTMLInvokedService">
<port name="HTMLInvokedPort" binding="client:HTMLInvokedBinding">
<http:address location="http://axreynol-pc:9700/httpbinding/default/HTMLInvoked" />
</port>
</service>

This declares that the service provides a single port implementing the "HTMLinvokedBinding".  The location of this service is actually constrained by the BPEL WSIF HTTP implementation.  The location tells people what URL to invoke to call the service.  The location is built up as follows.


protocol:server:port/wsif provider/domain/process
http://axreynol-pc:9700/httpbinding/default/HTMLInvoked

The protocol, server and port are self explanatory and are defined by the app server running the BPEL PM.  The wsif provider in this case is the "httpbinding" provider used for both GET and POST operations.  The domain is the BPEL domain in which the process is defined.  Finally the process is the name of the BPEL process.


3. Modify the BPEL


Lets now modify our BPEL to do something.  We'll add a single assignment statement to concatanate the firstname and lastname parameters into a "Hello <firstname> <lastname>" string as shown below.


<assign name="BuildHelloString">
<copy>
<from expression="concat('Hello ', bpws:getVariableData('inputVariable','firstname'), ' ', bpws:getVariableData('inputVariable','lastname'))"/>
<to variable="outputVariable" part="payload" query="/client:HTMLInvokedProcessResponse/client:result"/>
</copy>
</assign>

This leaves our process looking like this.





4. Deploy & Test the Process


We can now test our process by deploying it to a BPEL PM instance and invoking it via a URL.  Once deployed we can invoke it with a URL similar to the one below.


http://axreynol-pc:9700/httpbinding/default/HTMLInvoked/Hello?firstname=Antony&lastname=Reynolds


Note that the operation "Hello" is include in the path and the parts are passed as normal HTTP parameters.


This should return a result similar to the one below.





Summary


Although there are limits on the complexity of input documents you can construct from an HTML directly, using HTML WSIF bindings is still a useful way to quickly give people access to a mock-up of a Business Process.  As you can see from above, it is not a lot of work and you can then use a tool like dreamweaver or frontpage to create a friendly front end to your BPEL process.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

About This Entry

This page contains a single entry from the blog posted on September 5, 2005 10:24 PM.

The previous post in this blog was How to Read WSDL.

The next post in this blog is Invoking BPEL from Delphi.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type and Oracle