In these posts post1,post2, I have explained how to create custom XSL functions using Java in both BPEL(Oracle SOA)/BPM(Oracle BPM) processes.
Step2 : Create Synchronous BPEL process to perform age calculation for the given RequestElement[] array.
Step3: Create ApplicationContext Pojo to hold RequestElement data inside Context.
Step4: Create ApplicationContextManager class to grab data from for-each loop of XSL and hold it in Java Map(Collection) object.
In order to create ApplicationContextManager, We create a ThreadLocal Object which is of type ApplicationContext created in Step3. ThreadLocal will help us here to maintain transaction context with an execution thread for the duration of this particular BPEL instance/call.
Step5: Create an XSL to populate "mapStrings" HashMap global variable. with PersonId and DataOfBirth values. Please find XSL tranformation for the same.
Step6: For the sake of verifying if the transaction being maintained , I have created another XSL transformation ,which will populate data from mapStrings object into BPEL output variable.
Deploy and Execute the process:
Please download this example process here.
Input:
Output:
This post describes about ,how to create ApplicationContext and how to use it among XSLs across Oracle SOA process.
Below example explains on how to calculate age of persons by taking array of DateOfBirth inputs.
I know it can be done with simple XSL transformation by calling custom XSL function.
But, the main intention is to explain the ApplicationContext creation and usage of it over multiple XSLs used in the course of BPELprocess.
ApplicationContext meaning here is : Create a Java Context(with inspiration of ThreadLocal class) object which gets initialized at start of the BPEL process with necessary data either in the form of Collections or POJO, And hold these initialized definitions throughout the lifecycle of BPEL Process token(instance) ,which can be read or modified as and when needed.
Note/Warning : It can be done in Oracle BPM processes too, But only in short spanning synchronous BPM processes.In case of long running instances , Using this ApplicationContext approach would result in malfunction , because the JVM heap will get erased when you restart application server.
Note/Warning : It can be done in Oracle BPM processes too, But only in short spanning synchronous BPM processes.In case of long running instances , Using this ApplicationContext approach would result in malfunction , because the JVM heap will get erased when you restart application server.
Step1 : Create an XSD to define input and output of a synchronous BPEL process.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <?xml version="1.0" encoding="windows-1252" ?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://ande.prabhas.org/v1/" targetNamespace="http://ande.prabhas.org/v1/" elementFormDefault="qualified"> <xsd:element name="RequestElement"> <xsd:complexType> <xsd:sequence> <xsd:element name="Request" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="PersonID" type="xsd:string"/> <xsd:element name="DateOfBirth" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="ResponseElement"> <xsd:complexType> <xsd:sequence> <xsd:element name="Response" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="PersonID" type="xsd:string"/> <xsd:element name="age" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> |
Step2 : Create Synchronous BPEL process to perform age calculation for the given RequestElement[] array.
Step3: Create ApplicationContext Pojo to hold RequestElement data inside Context.
1 2 3 4 5 6 7 8 9 10 11 12 13 | package ande.prabhas.org; import java.util.HashMap; import java.util.Map; public class ApplicationContext { Map<String, String> mapStrings; public ApplicationContext() { mapStrings = new HashMap<String, String>(); } } |
Step4: Create ApplicationContextManager class to grab data from for-each loop of XSL and hold it in Java Map(Collection) object.
In order to create ApplicationContextManager, We create a ThreadLocal Object which is of type ApplicationContext created in Step3. ThreadLocal will help us here to maintain transaction context with an execution thread for the duration of this particular BPEL instance/call.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | package ande.prabhas.org; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.Map; import java.util.Set; public class ApplicationContextManager { private static ThreadLocal<ApplicationContext> globalAppContext = new ThreadLocal<ApplicationContext>() { protected synchronized ApplicationContext initialValue() { return new ApplicationContext(); } }; public static void setString(String key, String value) { if (globalAppContext.get().mapStrings != null) globalAppContext.get().mapStrings.put(key, value); } public static String getString(String key) { if (globalAppContext.get().mapStrings != null && globalAppContext.get().mapStrings.get(key) != null) { return globalAppContext.get().mapStrings.get(key); } else return null; } public static void performAgeCalc() { Iterator<String> iter=globalAppContext.get().mapStrings.keySet().iterator(); for(;iter.hasNext();) { String key = iter.next(); int age = calcAge(globalAppContext.get().mapStrings.get(key)); globalAppContext.get().mapStrings.put(key, age+""); } } //Warning : Execution of reset is must when you are using the appcontext over XSLs.The stored objects will not be GCed and will hog the heap space if the instance load is more by the day public static void reset() { globalAppContext.get().mapStrings.clear(); } } |
Step5: Create an XSL to populate "mapStrings" HashMap global variable. with PersonId and DataOfBirth values. Please find XSL tranformation for the same.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <xsl:stylesheet version="1.0" xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/" xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20" xmlns:mhdr="http://www.oracle.com/XSL/Transform/java/oracle.tip.mediator.service.common.functions.MediatorExtnFunction" xmlns:bpel="http://docs.oasis-open.org/wsbpel/2.0/process/executable" xmlns:oraext="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:client="http://xmlns.oracle.com/FindAgeService/FindAgeSvc/FindAgeService" xmlns:dvm="http://www.oracle.com/XSL/Transform/java/oracle.tip.dvm.LookupValue" xmlns:hwf="http://xmlns.oracle.com/bpel/workflow/xpath" xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:med="http://schemas.oracle.com/mediator/xpath" xmlns:ids="http://xmlns.oracle.com/bpel/services/IdentityService/xpath" xmlns:ns1="http://ande.prabhas.org/v1/" xmlns:bpm="http://xmlns.oracle.com/bpmn20/extensions" xmlns:xdk="http://schemas.oracle.com/bpel/extension/xpath/function/xdk" xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions" xmlns:ctxt="http://www.oracle.com/XSL/Transform/java/ande.prabhas.org.ApplicationContextManager" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:bpmn="http://schemas.oracle.com/bpm/xpath" xmlns:ora="http://schemas.oracle.com/xpath/extension" xmlns:socket="http://www.oracle.com/XSL/Transform/java/oracle.tip.adapter.socket.ProtocolTranslator" xmlns:ldap="http://schemas.oracle.com/xpath/extension/ldap" exclude-result-prefixes="xsi xsl client plnk ns1 xsd wsdl bpws xp20 mhdr bpel oraext dvm hwf med ids bpm xdk xref bpmn ora socket ldap"> <xsl:template match="/"> <ns1:ResponseElement> <xsl:for-each select="/ns1:RequestElement/ns1:Request"> <xsl:variable name="loadValues" select="ctxt:setString(ns1:PersonID,ns1:DateOfBirth)"/> <ns1:Response> <ns1:PersonID> <xsl:value-of select="ns1:PersonID"/> </ns1:PersonID> </ns1:Response> </xsl:for-each> </ns1:ResponseElement> <xsl:comment> <xsl:value-of select="ctxt:printData()"/> </xsl:comment> <xsl:variable name="performCalc" select="ctxt:performAgeCalc()"/> </xsl:template> </xsl:stylesheet> |
Step6: For the sake of verifying if the transaction being maintained , I have created another XSL transformation ,which will populate data from mapStrings object into BPEL output variable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <xsl:stylesheet version="1.0" xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/" xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20" xmlns:mhdr="http://www.oracle.com/XSL/Transform/java/oracle.tip.mediator.service.common.functions.MediatorExtnFunction" xmlns:bpel="http://docs.oasis-open.org/wsbpel/2.0/process/executable" xmlns:oraext="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:client="http://xmlns.oracle.com/FindAgeService/FindAgeSvc/FindAgeService" xmlns:dvm="http://www.oracle.com/XSL/Transform/java/oracle.tip.dvm.LookupValue" xmlns:hwf="http://xmlns.oracle.com/bpel/workflow/xpath" xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:med="http://schemas.oracle.com/mediator/xpath" xmlns:ids="http://xmlns.oracle.com/bpel/services/IdentityService/xpath" xmlns:ns1="http://ande.prabhas.org/v1/" xmlns:bpm="http://xmlns.oracle.com/bpmn20/extensions" xmlns:xdk="http://schemas.oracle.com/bpel/extension/xpath/function/xdk" xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions" xmlns:ctxt="http://www.oracle.com/XSL/Transform/java/ande.prabhas.org.ApplicationContextManager" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:bpmn="http://schemas.oracle.com/bpm/xpath" xmlns:ora="http://schemas.oracle.com/xpath/extension" xmlns:socket="http://www.oracle.com/XSL/Transform/java/oracle.tip.adapter.socket.ProtocolTranslator" xmlns:ldap="http://schemas.oracle.com/xpath/extension/ldap" exclude-result-prefixes="xsi xsl client plnk ns1 xsd wsdl bpws xp20 mhdr bpel oraext dvm hwf med ids bpm xdk xref bpmn ora socket ldap"> <xsl:template match="/"> <ns1:ResponseElement> <xsl:for-each select="/ns1:RequestElement/ns1:Request"> <ns1:Response> <ns1:PersonID> <xsl:value-of select="ns1:PersonID"/> </ns1:PersonID> <ns1:age> <xsl:value-of select="ctxt:getString(ns1:PersonID)"/> </ns1:age> </ns1:Response> </xsl:for-each> </ns1:ResponseElement> </xsl:template> </xsl:stylesheet> |
Deploy and Execute the process:
Please download this example process here.
Input:
Output:
Comments
Post a Comment