Olivier Le Diouris
April 4th, 2006.
package com.collaxa.cube.ws;
public abstract interface HeaderHandler
{
void invoke(com.collaxa.cube.engine.types.bpel.CXPartnerLink pLnk,
java.lang.String operation,
java.util.Map payload,
java.util.Map header,
java.util.Map callProperties);
}
If you are working with the BPEL Designer of JDeveloper, this interface is available
from the library named OraBPEL.
<BPELSuitcase>
<BPELProcess id="ProcessWithHeaderHandler" src="ProcessWithHeaderHandler.bpel">
<partnerLinkBindings>
<partnerLinkBinding name="client">
<property name="wsdlLocation">ProcessWithHeaderHandler.wsdl</property>
</partnerLinkBinding>
<partnerLinkBinding name="GreetingsPL">
<property name="wsdlLocation">GreetingsPL.wsdl</property>
<property name="requestHeaderHandlers">bpel.util.OutboundHandler</property>
<property name="responseHeaderHandlers">bpel.util.InboundHandler</property>
</partnerLinkBinding>
</partnerLinkBindings>
</BPELProcess>
</BPELSuitcase>
Notice that you can have distinct handlers for request and response, that makes it very convenient.
Those two handlers can actually be implemented by the same Java class.
|
In this case, and for the following ones, we have a very simple BPEL Process, from which we invoke
a ridiculously simple Web Service through a Partner Link.
The partner link we talk about is the one labeled GreetingsPL on the diagram. Behind the Partner Link is a Java Web Service, the implementing class is like
package greetings;
public class Greetings
{
public static String sayHello(String name)
{ return "Hello " + name + "!"; }
}
No big deal indeed.
This Web Service if of course exposed through a WSDL document, available through HTTP. |
package bpel.util;
import com.collaxa.cube.ws.HeaderHandler;
import com.collaxa.cube.engine.types.bpel.CXPartnerLink;
import com.collaxa.cube.xml.dom.CubeDOMElement;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class CustomHeaderHandler implements HeaderHandler
{
public CustomHeaderHandler()
{
System.out.println("Creating the CustomHeaderHandler");
}
public void invoke(CXPartnerLink pLink,
String operation,
Map payload,
Map header,
Map callProps)
{
System.out.println("in the CustomHeaderHandler, operation is [" + operation + "]");
if (pLink != null)
{
System.out.println("Partner Link:" + pLink.toString());
Map plProps = pLink.getProperties();
if (plProps != null)
{
try { dumpMap(plProps, "PartnerLink"); }
catch (Exception e)
{ System.out.println("PartnerLink dump:" + e.toString()); }
}
else
System.out.println("PartnerLink map is null");
}
else
System.out.println("Partner Link is null!");
if (payload != null)
System.out.println("The payload has " + payload.size() + " elements");
else
System.out.println("payload is null");
if (header != null)
System.out.println("The header has " + header.size() + " elements");
else
System.out.println("header is null");
if (callProps != null)
System.out.println("The callProps has " + callProps.size() + " elements");
else
System.out.println("callProps is null");
try { dumpMap(payload, "payload"); }
catch (Exception e)
{
System.out.println("Error dumping payload:");
System.out.println(e.toString());
}
try { dumpMap(header, "header"); }
catch (Exception e)
{
System.out.println("Error dumping header:");
System.out.println(e.toString());
}
try { dumpMap(callProps, "callProps"); }
catch (Exception e)
{
System.out.println("Error dumping callProps:");
System.out.println(e.toString());
}
}
private void dumpMap(Map map, String mapName) throws Exception
{
...
}
}
This class is basically spitting out the content of the different parameters it receives.
package bpel.util;
import com.collaxa.cube.engine.types.bpel.CXPartnerLink;
import com.collaxa.cube.xml.dom.CubeDOMElement;
import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Node;
public class OutboundHandler extends CustomHeaderHandler
{
public OutboundHandler()
{
super();
}
public void invoke(CXPartnerLink pLink,
String operation,
Map payload,
Map header,
Map callProps)
{
System.out.println("On the way OUT");
System.out.println("=================================>>>");
super.invoke(pLink, operation, payload, header, callProps);
}
}
and
package bpel.util;
import com.collaxa.cube.engine.types.bpel.CXPartnerLink;
import java.util.Map;
public class InboundHandler extends CustomHeaderHandler
{
public InboundHandler()
{
super();
}
public void invoke(CXPartnerLink pLink,
String operation,
Map payload,
Map header,
Map callProps)
{
System.out.println("On the way IN");
System.out.println("<<<=================================");
super.invoke(pLink, operation, payload, header, callProps);
}
}
Such handlers would be registered in the BPEL Suitcase, just like already mentionned above.
06/04/04 10:38:38 Creating the CustomHeaderHandler
06/04/04 10:38:38 On the way OUT
06/04/04 10:38:38 =================================>>>
06/04/04 10:38:38 in the CustomHeaderHandler, operation is [sayHello]
06/04/04 10:38:38 Partner Link:<partnerLink name="GreetingsPL" partnerLinkType="
{http://greetings/Greetings.wsdl}GreetingsPortType_PL">
<myRole name="null">
<ServiceName>null</ServiceName>
<PortType>null</PortType>
<Address>null</Address>
</myRole>
<partnerRole name="GreetingsPortType_Role">
<ServiceName>{http://greetings/Greetings.wsdl}GreetingsWS</ServiceName>
<PortType>{http://greetings/Greetings.wsdl}GreetingsPortType</PortType>
<Address>null</Address>
</partnerRole>
<conversationId>bpel://localhost/default/ProcessWithHeaderHandler~1.0/19401-BpInv0-BpSeq0.3-3</conversationId>
<properties>{}</properties>
</partnerLink>
06/04/04 10:38:38 Dumping PartnerLink
06/04/04 10:38:38 The payload has 1 elements
06/04/04 10:38:38 The header has 0 elements
06/04/04 10:38:38 The callProps has 10 elements
06/04/04 10:38:38 Dumping payload
06/04/04 10:38:38 Key:name
06/04/04 10:38:38 Value is a com.collaxa.cube.xml.dom.CubeDOMElement
06/04/04 10:38:38 Value:
<name>Oracle</name>
06/04/04 10:38:38 Dumping header
06/04/04 10:38:38 Dumping callProps
06/04/04 10:38:38 Key:is-initial-call
06/04/04 10:38:38 Value is a java.lang.Boolean
06/04/04 10:38:38 Value:true
06/04/04 10:38:38 Key:input-header-variables
06/04/04 10:38:38 Value is a java.util.HashMap
06/04/04 10:38:38 ** Hashmap of 0 entries **
06/04/04 10:38:38 Dumping input-header-variables
06/04/04 10:38:38 ** End of dump for input-header-variables **
06/04/04 10:38:38 Key:parentId
06/04/04 10:38:38 Value:19401
06/04/04 10:38:38 Key:completionPersistPolicy
06/04/04 10:38:38 Null value for completionPersistPolicy
06/04/04 10:38:38 Key:process-id
06/04/04 10:38:38 Value is a com.oracle.bpel.client.BPELProcessId
06/04/04 10:38:38 Value:bpel://localhost/default/ProcessWithHeaderHandler~1.0/
06/04/04 10:38:38 Key:rootId
06/04/04 10:38:38 Value:19401
06/04/04 10:38:38 Key:conversationId
06/04/04 10:38:38 Value:bpel://localhost/default/ProcessWithHeaderHandler~1.0/19401-BpInv0-BpSeq0.3-3
06/04/04 10:38:38 Key:location
06/04/04 10:38:38 Value:http://oliv-lap:9700/very-usefull/GreetingsWS
06/04/04 10:38:38 Key:priority
06/04/04 10:38:38 Value:3
06/04/04 10:38:38 Key:work-item-key
06/04/04 10:38:38 Value is a com.collaxa.cube.engine.core.WorkItemKey
06/04/04 10:38:38 Value:19401-BpInv0-BpSeq0.3-3
06/04/04 10:38:38 httpHeaders is null
06/04/04 10:38:39 Creating the CustomHeaderHandler
06/04/04 10:38:39 On the way IN
06/04/04 10:38:39 <<<=================================
06/04/04 10:38:39 in the CustomHeaderHandler, operation is [sayHello]
06/04/04 10:38:39 Partner Link:<partnerLink name="GreetingsPL" partnerLinkType="
{http://greetings/Greetings.wsdl}GreetingsPortType_PL">
<myRole name="null">
<ServiceName>null</ServiceName>
<PortType>null</PortType>
<Address>null</Address>
</myRole>
<partnerRole name="GreetingsPortType_Role">
<ServiceName>{http://greetings/Greetings.wsdl}GreetingsWS</ServiceName>
<PortType>{http://greetings/Greetings.wsdl}GreetingsPortType</PortType>
<Address>null</Address>
</partnerRole>
<conversationId>bpel://localhost/default/ProcessWithHeaderHandler~1.0/19401-BpInv0-BpSeq0.3-3</conversationId>
<properties>{}</properties>
</partnerLink>
06/04/04 10:38:39 Dumping PartnerLink
06/04/04 10:38:39 The payload has 1 elements
06/04/04 10:38:39 header is null
06/04/04 10:38:39 The callProps has 11 elements
06/04/04 10:38:39 Dumping payload
06/04/04 10:38:39 Key:name
06/04/04 10:38:39 Value is a com.collaxa.cube.xml.dom.CubeDOMElement
06/04/04 10:38:39 Value:
<name>Oracle</name>
06/04/04 10:38:39 header is null
06/04/04 10:38:39 Dumping callProps
06/04/04 10:38:39 Key:is-initial-call
06/04/04 10:38:39 Value is a java.lang.Boolean
06/04/04 10:38:39 Value:true
06/04/04 10:38:39 Key:input-header-variables
06/04/04 10:38:39 Value is a java.util.HashMap
06/04/04 10:38:39 ** Hashmap of 0 entries **
06/04/04 10:38:39 Dumping input-header-variables
06/04/04 10:38:39 ** End of dump for input-header-variables **
06/04/04 10:38:39 Key:parentId
06/04/04 10:38:39 Value:19401
06/04/04 10:38:39 Key:completionPersistPolicy
06/04/04 10:38:39 Null value for completionPersistPolicy
06/04/04 10:38:39 Key:process-id
06/04/04 10:38:39 Value is a com.oracle.bpel.client.BPELProcessId
06/04/04 10:38:39 Value:bpel://localhost/default/ProcessWithHeaderHandler~1.0/
06/04/04 10:38:39 Key:rootId
06/04/04 10:38:39 Value:19401
06/04/04 10:38:39 Key:conversationId
06/04/04 10:38:39 Value:bpel://localhost/default/ProcessWithHeaderHandler~1.0/19401-BpInv0-BpSeq0.3-3
06/04/04 10:38:39 Key:location
06/04/04 10:38:39 Value:http://oliv-lap:9700/very-usefull/GreetingsWS
06/04/04 10:38:39 Key:httpResponseHeaders
06/04/04 10:38:39 Value is a java.util.HashMap
06/04/04 10:38:39 ** Hashmap of 5 entries **
06/04/04 10:38:39 Dumping httpResponseHeaders
06/04/04 10:38:39 Key:content-length
06/04/04 10:38:39 Value: 514
06/04/04 10:38:39 Key:connection
06/04/04 10:38:39 Value: Close
06/04/04 10:38:39 Key:content-type
06/04/04 10:38:39 Value: text/xml; charset=utf-8
06/04/04 10:38:39 Key:server
06/04/04 10:38:39 Value: Oracle Application Server Containers for J2EE 10g (10.1.2.0.2)
06/04/04 10:38:39 Key:date
06/04/04 10:38:39 Value: Tue, 04 Apr 2006 17:38:39 GMT
06/04/04 10:38:39 ** End of dump for httpResponseHeaders **
06/04/04 10:38:39 Key:priority
06/04/04 10:38:39 Value:3
06/04/04 10:38:39 Key:work-item-key
06/04/04 10:38:39 Value is a com.collaxa.cube.engine.core.WorkItemKey
06/04/04 10:38:39 Value:19401-BpInv0-BpSeq0.3-3
06/04/04 10:38:39 httpHeaders is null
Notice the method name (operation), the content of the Partner Link, and the
values of the payloads.
package bpel.util;
import com.collaxa.cube.engine.types.bpel.CXPartnerLink;
import com.collaxa.cube.xml.dom.CubeDOMElement;
import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Node;
public class OutboundHandler extends CustomHeaderHandler
{
public OutboundHandler()
{
super();
}
public void invoke(CXPartnerLink pLink,
String operation,
Map payload,
Map header,
Map callProps)
{
System.out.println("On the way OUT");
System.out.println("=================================>>>");
super.invoke(pLink, operation, payload, header, callProps);
System.out.println("===== Now, something specific =====");
// Overriding the payload...
if (pLink.getName().equals("GreetingsPL")) // Then we override
{
CubeDOMElement cde = (CubeDOMElement)payload.get("name");
Node txt = cde.getFirstChild();
txt.setNodeValue("Oracle BPEL PM");
payload.put("name", cde); // Here we are
}
System.out.println("===== End of the Dump =====");
}
}
package greetings;
public class Greetings
{
public static String sayHello(String name)
{ return "This is a dummy WS, " + name + ". Implemented for tests."; }
}
We have published this web service in such a way that its url is
http://oliv-lap:9700/very-very-usefull/ServiceForRedirection.
We have the possibility to change the location parameter of the call properties, so that
this one will be substituted to the one originally targeted.
package bpel.util;
import com.collaxa.cube.engine.types.bpel.CXPartnerLink;
import com.collaxa.cube.xml.dom.CubeDOMElement;
import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Node;
public class OutboundHandler extends CustomHeaderHandler
{
public OutboundHandler()
{
super();
}
public void invoke(CXPartnerLink pLink,
String operation,
Map payload,
Map header,
Map callProps)
{
System.out.println("On the way OUT");
System.out.println("=================================>>>");
super.invoke(pLink, operation, payload, header, callProps);
System.out.println("===== Now, something specific =====");
// Overriding the payload...
if (pLink.getName().equals("GreetingsPL")) // Then we override
{
CubeDOMElement cde = (CubeDOMElement)payload.get("name");
Node txt = cde.getFirstChild();
txt.setNodeValue("Oracle BPEL PM");
payload.put("name", cde); // Here we are
// Changing the location
String location = (String)callProps.get("location");
System.out.println("Original location is [" + location + "]");
callProps.put("location", "http://oliv-lap:9700/very-very-usefull/ServiceForRedirection");
}
System.out.println("===== End of the Dump =====");
}
}