Thursday, September 18, 2008

BreizhJug : 1ère séance

Lundi soir a vu l'ouverture du JUG rennais : le BreizhJUG. Nous avons pu assister à une excellente présentation de Didier Girard sur GWT. J'avais déjà jeté un coup d'oeil sur cette technologie mais il faut avouer qu'il m'a donné envie d'approfondir tout ça. Les possibilités offertes par le framework Google sont absolument fantastiques, spécialement quand on le couple à Google Gears (logiciel permettant d'utiliser les applications web en mode déconnecté). Gears que Google a bien entendu intégré à Chrome (étonnant non !?).


Pour finir, un merci tout particulier à Nicolas De loof et Matthieu Jouan, les deux organisateurs.

Monday, September 1, 2008

custom interaction with an Oracle BPEL process

For interacting with Oracle BPEL, you can, of course, use the Human Task. The problem is that Human Task is Oracle-dependent and is too complex to implement. So if you want to handle interactions, you simply use custom correlation. Let's see that with an example.

First, we create a simple asynchronous BPEL process which is locked just after the initial Receive task. To lock the process, we use another Receive task which is linked to a second operation called unlock : the process is dehydrated.

<definitions
name="Lock"
targetNamespace="http://java-soa.blogspot.com/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"
xmlns:pns1="http://java-soa.blogspot.com//correlationset"
xmlns:client="http://java-soa.blogspot.com/"
>
<import namespace="http://java-soa.blogspot.com//correlationset" location="Lock_Properties.wsdl"/>
<types>
<schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://java-soa.blogspot.com/"
xmlns="http://www.w3.org/2001/XMLSchema">
<element name="LockProcessRequest">
<complexType>
<sequence>
<element name="id" type="string"/>
</sequence>
</complexType>
</element>
<element name="UnlockProcessRequest">
<complexType>
<sequence>
<element name="id" type="string"/>
</sequence>
</complexType>
</element>
<element name="LockProcessResponse">
<complexType>
<sequence>
<element name="result" type="string"/>
</sequence>
</complexType>
</element>
</schema>
</types>
<message name="LockRequestMessage">
<part name="payload" element="client:LockProcessRequest"/>
</message>
<message name="UnlockRequestMessage">
<part name="payload" element="client:UnlockProcessRequest"/>
</message>
<message name="LockResponseMessage">
<part name="payload" element="client:LockProcessResponse"/>
</message>
<portType name="Lock">
<operation name="initiate">
<input message="client:LockRequestMessage"/>
</operation>
<operation name="unlock">
<input message="client:UnlockRequestMessage"/>
</operation>
</portType>
<portType name="LockCallback">
<operation name="onResult">
<input message="client:LockResponseMessage"/>
</operation>
</portType>
<plnk:partnerLinkType name="Lock">
<plnk:role name="LockProvider">
<plnk:portType name="client:Lock"/>
</plnk:role>
<plnk:role name="LockRequester">
<plnk:portType name="client:LockCallback"/>
</plnk:role>
</plnk:partnerLinkType>
<bpws:propertyAlias propertyName="pns1:correlationId" messageType="client:LockRequestMessage" part="payload"
query="/client:LockProcessRequest/client:id"/>
<bpws:propertyAlias propertyName="pns1:correlationId" messageType="client:UnlockRequestMessage" part="payload"
query="/client:UnlockProcessRequest/client:id"/>
</definitions>



the main difference between this task and the initiate receive is that this one do not create a new process instance (ie. the "create instance" property is unchecked). So, this task must be linked to a current instance. To do that, we have to use the custom correlation. We initiate the correlation set with the request id present in the request payload on the initiate task. This correlation set is, in a second time, attached to the lock task and that's all (the id must be unique in Oracle BPEL); Oracle BPEL will manage the interactions.



When an initiate request is coming, Oracle BPEL gets the id and stores it. After that, the process is dehydrated on the lock Receive task. When an unlock message is coming,
the id is checked and Oracle BPEL correlates it with the process. At this moment, the process is rehydrated and its execution is resumed.

Now it's simple for a developer to create an "Unlock client" as you can see in the following code (we are using JAX-WS but you can use what you want to implement a client :
Axis, .Net, Soap-UI...) :

package com.javasoa.ws;

import java.net.MalformedURLException;
import java.net.URL;

/**
* Lock client.
*
* @author Grégory LE BONNIEC
*/
public class LockClient {

/** arguments count. */
private static final int ARGS_COUNT = 3;

/** type : initiate. */
private static final String TYPE_INIT = "init";

/** type : unlock. */
private static final String TYPE_UNLOCK = "unlock";

/////////////////////////////////////////////////////////////////////////

/**
* Starts the lock client.
*
* @param args arguments
*/
public static void main(String[] args) {
if (args.length != ARGS_COUNT) {
System.out
.println("[ERR] command : java LockClient [wsdl] [type] [id]");
System.exit(1);
}
String wsdl = args[0];
String type = args[1];
String id = args[2];

URL wsdlURL = null;
try {
wsdlURL = new URL(wsdl);
} catch (MalformedURLException me) {
System.out.println("[ERR] malformed URL");
System.exit(1);
}

LockService service = new LockService(wsdlURL);
if (TYPE_INIT.equals(type)) {
LockProcessRequest request = new LockProcessRequest();
request.setId(id);
service.getLockPort().initiate(request);
} else if (TYPE_UNLOCK.equals(type)) {
UnlockProcessRequest request = new UnlockProcessRequest();
request.setId(id);
service.getLockPort().unlock(request);
} else {
System.out.println("[ERR] unknown type");
System.exit(1);
}
}

}


To create a new process, here is the command : java LockClient [wsdl] init [id] (example : http://localhost:8888/orabpel/biosom/Lock/1.0/Lock?wsdl init greg)



To unlock a process, here is the command : java LockClient [wsdl] unlock [id] (example : http://localhost:8888/orabpel/biosom/Lock/1.0/Lock?wsdl unlock greg)



This example is very simple but you can, of course, implement a correlation set more complicated and send more complex messages.

Download sources