Thursday, August 10, 2006

Manipulating XML payload

Introduction

When you are using BPEL 10.1.2 and want to replace values in an XML payload. There are a few possibilities:

  • Using assign with from and to tags. In the to-tag you can add a XPATH queury. A disadvantage is that the XPATH query in the to-tag can not be dynamic.
  • Using XSLT stylesheet. This use more CPU intensive and additional files are needed to format the XML input to the desired output.
  • Using and expression function like addChildNode(), appendChildNode(). These functions are deprecated.
So what is the best way to handle XML? Thanks to murugac for his answer on the BPEL forum. I copied it to my blog to extract the reusable text.

Please don't use the addChildNode() function, this function is going to deprecated, instead use the new bpel extension insert/append (bpelx:append):

Syntax:
<bpel:assign>
<bpelx:append>
<bpelx:from ... />
<bpelx:to ... />
</bpelx:append>
</bpel:assign>

The from-spec within <append> yields a single node or a node list. (Please note: the from-spec of <bpel:copy> still MUST yield ONLY one node.) The node list will be appended as child nodes to the target node specified by to-spec. If the from-spec yields zero node, "bpel:selectionFailure" fault will be generated.

The to-spec MUST yield one single L-Value element node. Otherwise, "bpel:selectionFailure" fault will be generated. The to-spec cannot refer to a partnerLink.

See: appendChild (org.w3c.dom.Node)

Example: (XSD details at end of the document)

Consolidating multiple bills of material into one single bill of material by appending multiple "b:part" for one BOM to "b:parts" the consolidated BOM.
-----------------------
<bpel:assign>
<bpelx:append>
<from variable="billOfMaterialVar"
query="/b:bom/b:parts/b:part" />
<to variable="consolidatedBillOfMaterialVar"
query="/b:bom/b:parts" />
</bpelx:append>
</bpel:assign>
-----------------------

2. Insert
2.1 insertBefore
Syntax:
<bpel:assign>
<bpelx:insertBefore>
<bpelx:from ... />
<bpelx:to ... />
</bpelx:insertBefore>
</bpel:assign>

The restriction and semantics of from-spec under insertBefore is similar to those in the case of <bpelx:append>.

The to-spec under <insertBefore> MUST points to one or more single L-Value nodes. If more than one nodes are returned, the first node will be used as the reference node. The reference node MUST be an element node. The parent of the reference node MUST be an element node also. Otherwise, "bpel:selectionFailure" fault will be generated. The to-spec cannot refer to a partnerLink.

The node list generated by the from-spec will be inserted before the reference node.

See: insertBefore(org.w3c.dom.Node,%20org.w3c.dom.Node)

Example: (XSD details at end of the document)

Say before the execution of <insertBefore>, the value of "addrVar" is:
----------------------
<a:usAddress>
<a:state>CA</a:state>
<a:zipcode>94065</a:zipcode>
</a:usAddress>
----------------------

After the execution of the following:
----------------------
<bpel:assign>
<bpelx:insertBefore>
<from>
<a:city>Redwood Shore></a:city>
</from>
<to "addrVar" query="/a:usAddress/a:state" />
</bpelx:insertBefore>
</bpel:assign>
----------------------

The value of "addrVar" becomes:
----------------------
<a:usAddress>
<a:city>Redwood Shore</a:city>
<a:state>CA</a:state>
<a:zipcode>94065</a:zipcode>
</a:usAddress>
----------------------


2.2 insertAfter
Syntax:
<bpel:assign>
<bpelx:insertAfter>
<bpelx:from ... />
<bpelx:to ... />
</bpelx:insertAfter>
</bpel:assign>

<insertAfter> is very similar to <insertBefore>. Except:

If more than one L-Value nodes are returned by the to-spec, the last node will be used as the reference node.
Instead of inserting nodes "before" the reference node, the source nodes will be inserted after the "reference" node.

This operation can also be considered a macro of conditional-switch + (append or insertBefore).


Example: (XSD details at end of the document)

Say before the execution of <insertAfter>, the value of "addrVar" is:
----------------------
<a:usAddress>
<a:addressLine>500 Oracle Parkway</a:addressLine>
<a:state>CA</a:state>
<a:zipcode>94065</a:zipcode>
</a:usAddress>
----------------------

After the execution of the following:
----------------------
<bpel:assign>
<bpelx:insertAfter>
<from>
<a:addressLine>Mailstop 1op6</a:addressLine>
</from>
<to "addrVar" query="/a:usAddress/a:addressLine[1]" />
</bpelx:insertAfter>
</bpel:assign>
----------------------

The value of "addrVar" becomes:
----------------------
<a:usAddress>
<a:addressLine>500 Oracle Parkway</a:addressLine>
<a:addressLine>Mailstop 1op6</a:addressLine>
<a:state>CA</a:state>
<a:zipcode>94065</a:zipcode>
</a:usAddress>
----------------------

Monday, August 07, 2006

Using properties variables Part#1

Introduction

When programming in any language you often use properties to set particular variables. You use this to reduce "hard-coded" settings and to be independent of different environments. For Oracle BPEL thare are many solutions to use a property mechanism.

Variables
Within a BPEL process you can define variables and assign expressions to it. These variables you can use this in your BPEL process. While these variables are used along the BPEL proces, you define tprhese as global variables.

In the BPEL process an assign must be cartied out to set the variable:

<assign name="Assign_1">
<copy>

<from expression="'marc_soa@vijfhuizen.com'"></from>
<to variable="globalEmailAdress"></to>
</copy>
</assign>

BPEL properties
It is possible to define propertie settings within the BPEL process. The properties are set globally and outside the BPEL process. The properties can be accessed via a internal function.

In the bpel.xml file add the following lines, just before the end-of :

<preferences>
<property name="propertyEmailAddress">marc_soa@vijfhuizen.com</property>
</preferences>


The properties are accessed in the BPEL process (.BPEL file) via the ora:getPreference() function:

ora:getPreference('propertyEmailAdress')

In a next article, we discuss how to use properties from the database an call this via a single BPEL process.

Tuesday, August 01, 2006

Using ANT in a BPEL environment

Introduction

Updated: Sep 2007, for 10.1.3.3, download code here.

Oracle’s scalable application architecture in combination with the BPEL architecture combines the best elements to create a high available and high performance environment. Using tools to develop BPEL applications can be very complex when multiple environments exist.
In general there are the following environments;
  • Development
  • Test
  • Acceptance
  • Production
Depending on the customer requirements more or less environments exists.
This paper describes a solution to develop applications based on BPEL for multiple environments.

Overview

In general development of BPEL processes is done via an IDE tools. These tools are:
The first two products are graphical tools to design and develop BPEL processes. These tools can also be used for compilation and deployment of a BPEL process. The obant tool is part of the BPEL software stack and can be used to compile and deploy a BPEL process.
Combining these tools make is in general enough for designing and implementing BPEL applications.
It will be more complex if design and development must be done for various environments; developing new BPEL applications in development environment and fixing BPEL processes in a production environment.

Solution
The obant tool can compile from a current directory an ANT build.xml file. It will read the XML tags from this and interpret them. Oracle Jdeveloper generates this build.xml file when a new BPEL process is created.

It is possible to extend this “build.xml” file with other ANT tasks. But this is not logical. When developing BPEL applications, it will result in many BPEL processes, each having it’s own “build.xml” file.

A solution could be to have a general “build.xml” that is able to compile the BPEL processes.

A feature of the current obant tool, is that is only possible to use the core ANT tasks. It is not possible to use the optional tasks or even extend it with other tasks without changing the obant script.

The solution described in the next paragraphs will take this into account. The solution will cover the following features and can be easily change and extended to customer requirements:
  • Using full ANT tasks features
  • Multiple environments
  • Compiling multiple BPEL processes
  • Deployment to cluster environment
See also the white paper “Deploying BPEL processes in a High Available Application Cluster”

Directory Structure
Apart of using a version control tool to maintain all the files in a central repository, the files must be downloaded from this repository onto the hard drive. As source control tools as Oracle Source Control Management, SubVersion, CVS and ClearCase can be used.

The directory structure for this solution is as follows:

/home/mkelderm/projects/bpel
|-ant
|---doc
|---properties
|---templates
|-----async
|-----empty
|-----sync
|-source
|---default
|-----dev
|-------custom
|---------extlibraries
|---------html
|---------images
|---------java
|---------jdev
|-------HelloWorld
|-derived
|---default
|-----dev
|-------custom
|---------ear
|---------war
|-------ear
|-------stage
|-------HelloWorld
|---------jar
|-------war

The meaning of the directory names is mentioned in the next table.

Directory Description
/home/mkelderm/projects/bpel The base directory of the BPEL application
ant The location of the ANT scripts.
ant/doc The location of the documentation that you are reading.
ant/properties The location of the properties files that the ANT build script is reading. For each environment an separate property file is created.
ant/templates In this directory the BPEL templates are located. By default an empty, asynchronous and a synchronous BPEL process are located here.
source In this directory all the source code that is related to the BPEL application is located beneath here.
source/default The BPEL domain.
source/default/dev The environment that is valid for the BPEL application. By default ‘dev’ is used. This could also be ‘test’, ‘prod’ or even version number.
source/default/dev/custom Any addition code, non-BPEL processes, related to the BPEL application is located here. For example custom Java code.
source/default/dev/HelloWorld As example a BPEL process is located beneath the ‘dev’ directory. In this case the BPEL process HelloWorld. Each BPEL process has its own sub directory.
derived Any file that is not source code related but can be derived from the source code is located here. For example compiled BPEL processes (JARS), java classes, java documentation
derived/default BPEL domain
derived/default/dev Environment
derived/default/dev/custom Custom derived code; for example classes
derived/default/dev/HelloWorld The BPEL process HelloWorld containing the jar file.
derived/default/dev/ear The derived EAR file, used form deployment
derived/default/dev/war The derived WAR file, used form deployment


Based on the previous directory structure a script is made that takes control over these directories and fulfill the appropriate actions onto it. The script is made generic so that any other structure can be implemented.

Build Script: OBBUILD.SH - Configure
Based on the obant tool, as part of the Oracle BPEL PM 10g. A script is made that is able to full-fill the same functions. There are some differences. The script will use the full version of ANT, it will not use the tool obant.
The script expects that a full-version of ANT is downloaded and installed on the machine on the script executed. ANT and an additional library are found on the following locations:
The script is also expecting the Oracle BPEL PM is installed and configured on the server on which the script is executed.

The “obbuild.sh” will use the above ANT versions and reference to the Oracle BPEL environment. Within the three environment settings must be checked before this script can be executed. The settings are:

ANT_HOME=/home/mkelderm/projects/ant/apache-ant-1.7.0
ORACLE_HOME=/apps/oracle/products/10.1.3/as
ORABPEL_HOME=${ORACLE_HOME}/bpel
JAVA_HOME=${ORACLE_HOME}/jdk
ANT_JAVA_EXTENSIONS=/home/mkelderm/projects/bpel/tools/ant/lib


Build Script: OBBUILD.SH – Options
The script has a help function to show the possible options.

obbuild.sh -h
obbuild.sh [-[hvtV] [-e environment] [-f build-file]
[-r replace-file] [task] [arg1] [arg2] .. [arg6]]

-h Shows this help
-v Show the version of this program
-t Show all the tasks in the build file
-e Select envirnonment property file, default 'dev', reading dev.properties
-f Read a specific build file, default is build.xml in current directory
-r Read a specific replacement file,
use for promoting BPEL process to other environments.
-V Show verbose output
task The task to be executed, default is main
arg1..6 Optional arguments passed to the build file
as properties ANT.ARG1..ANT.ARG6


The script is reading a “build.xml” file to perform all the ANT tasks. By default it look in the current directory for the “build.xml”. With the option –f another build file can be mentioned. The –e option set the environment. In this file settings for a specific environment can be set; development, system test, production etc. By default it tries to read the “dev” environment; ./properties/dev.properties. The task is the task that ANT will be executed. By default it looks for the “main” task. Depending on the task, additional arguments can de given.

Build Script: OBBUILD.SH – Examples

obbuild.sh
Start the script with no arguments. It searches for the ./properties/dev/properties file and ./build.xml file and execute the “main” task of this file.

obbuild.sh –t

List all the tasks from the default build.xml file.

obbuild.sh –f /home/user/bpel/build.xml
It reads the build.xml from another location.

obbuild.sh –e systemtest
It reads the properties file named systemtest from ./properties/systemtest.properties.

obbuild.sh –f /home/user/bpel/build.xml –e systemtest CompileBPEL
Compile all the BPEL processes for the systemtest environment using a specific build file.

Build Script: build.xml
The build.xml file contains all the functions to maintain BPEL processes. Currently the following tasks are available


obbuild.sh -t
obbuild.sh: Tasks in ./build.xml
_Init - Internal: Initialize environment
_CleanSVN - Internal: remove svn files
_CheckoutLatest - Internal: Checkout the latest sourcecode from SVN
_CheckoutVersion - Internal: Checkout the particular version from SVN
[arg=version]
CreateDirs - Create directory structure
CreateNewProcess - Create a new BPEL process, based on a template
[arg1=bpel-process-template_name, arg2=bpel-process-name].
Compile - Compile one or all BPEL processes (
[arg=bpel-process-name])
DeployLocal - Deploy one or all BPEL processes to a domain
on the local server
[arg1=[Bpel-process|all]], [arg2=[domain-name|default]]
, [arg3=version|1.0]
Download - Download latest source code
[arg=version]
CreateWar - Create WAR file, containing all the BPEL processes
[arg=war-filename]
CreateEar - Create BPEL ear file
[arg=ear_filename]
main - Default task
Promote - Find/Replace on one or more BPEL processes,
see replace.properties
DeploySCP - Deploy one or all BPEL processes to a domain
on a remote server [arg1=[Bpel-process|all]]

CreateDirs
This task creates an initial directory structure as mentioned previously.

Example: For the prod environment create a new structure

obbuild.sh –e prod CreateDirs

CreateNewProcess
Create a new BPEL process based on a template.