Tuesday, February 19, 2008

Using SOAP_CLIENT to access Human Tasks services

The are a lot of issues related to access the human work flow tasks from java. Especially via SOAP. The Java API of Oracle SOA Suite provides a mechanism to use various access method:
  • JAVA_CLIENT
  • REMOTE_CLIENT
  • SOAP_CLIENT
It is hard to get the Java API working with the SOAP_CLIENT method. I'm using now SOA Suite 10.1.3.3.1 And dit the following:
  • commons-logging-api.jar
  • commons-logging.jar
  • bpm-infra.jar
  • orabpel-common.jar
  • orabpel-thirdparty.jar
  • orabpel.jar
  • oc4jclient.jar
  • jazncore.jar
  • xml.jar
  • xmlparserv2.jar
  • orasaaj.jar
  • soap.jar
  • bpm-services.jar
  • wsclient_extended.jar
Note :wsclient_extended.jar can be download from OTN.

Create you Java project and use the following libraries, I copied the libraries from the application server.

The I changed the orabpel.jar file! It is a strange trick, but you must remove all the files from META-INF directory:
  1. Extract orabpel.jar
  2. Remove all files in META-INF
  3. Re-jar orabpel.jar
Make sure you have a correct version of the wf_client_config.xml file. This file must be located in your source directory. The file is copied from application server $ORACLE_HOME/bpel/system/services/config. Verify that the connection to your remote server is removed! Remove the ejb tags.
   <ejb>
<serverURL>opmn:ormi://linux.site:oc4j_soa/hw_services</serverURL>
<user>oc4jadmin</user>
<password>welcome1</password>
<initialContextFactory>oracle.j2ee.rmi.RMIInitialContextFactory</initialContextFactory>
</ejb>
When you got this working, you will find that predicates, aka the where clause, are not working. This can be solved by setting the property:
  Predicate.enableXMLSerialization(true);
Before you use any predicate. The SOAP call is based on HTTP and therefore the predicate must be serialized to send over to the server.

Wednesday, February 06, 2008

How to deploy Oracle AIA ESB service.

To deploy your ESB service to the Oracle SOA Suit with Application Integration Architecture, make sure you have a AIA enviroment avialable. This can be on your workstation or you use the server.

In my case I assume you have all your ESB services available on the server. For example a local copy of the source control system like SubVersion.

First make sure your have the environment settings correct.

Set the correct ORACLE_HOME and PATH settings of your middle tier installation. I assume you have set this in the /etc/oratab file.

. oraenv
[] ? assoa

Go to the 'bin' directory in which AIA is installed (the $AIA_HOME dir).


. aiaenv.sh

This will set various environment variables like AIA_HOME, ANT_HOME and the PATH.

Then go to the directory of your ESB service and type the following statements


ant ExtractESBDeploymentPlan

ant CustomiseAndDeployESB

Marc

Friday, February 01, 2008

Enable AIA functions in JDeveloper

Using Oracle Application Integration Architecture Framework, it assumes that you have a complete SOA Suite installed including JDeveloper. Now most of us will have only a workstation for developing and using a server to deploy and test your BPEL/ESB services.
When using Oracle AIA, it will install and configure your local SOA server AND JDeveloper to be ready for Oracle AIA.

This article describes how you could enable new AIA functions in JDeveloper.

To enable the new AIA functions in JDeveloper, you must copy the following files into your JDeveloper directory:

From:
  %AIA_HOME%/lib/aia.jar

To:
  %JDEV_HOME%/jdev/jdev/lib/patches

From:
  bpm-ide-common.jar    
(This is a specific patched version, created during the AIA installation)

To
  %JDEV_HOME%/integration/lib
Note on Unix use ${AIA_HOME}
Restart JDeveloper to enable these extensions.

Open your expression builder and in your advanced function you will see the new AIA functions.

While I was writing this article, an old colleague Martien van den Akker, pointed me on an article on Metalink note " 550378.1". This note contains a complete zip file that creates to necessary files, it also supplies the aia.jar file.


Happy programming :-)

Marc

Getting the name of the parent process

Sometimes you need to known which BPEL process called me. This could be use full to extract information from the calling process. In this example I created a piece a Java code that can be used in the Java Embedded step in the BPEL process.

It determines if it is called from an other BPEL process. If so, it derives the name of the process.
<bpelx:exec name="Java_Get_ParentName"
language="java" version="1.5">
<![CDATA[
String inputvar1 = "";
String parentId = "";
String parentName = "";

// Define variables to use;
com.oracle.bpel.client.IInstanceHandle instance;
com.oracle.bpel.client.IInstanceHandle[] instances;
com.oracle.bpel.client.util.WhereCondition condition;

try
{
parentId = getParentId();
//
if (parentId == null || parentId.equals(""))
{
// Process is called via NON BPEL process:
// SoapUI, BPELConsol, external WebService
//
parentId = String.valueOf(getInstanceId());
parentName = "myself";
}
else
{
//
// Set the whereclause
addAuditTrailEntry("Set Query to determine parent process");
condition =
new com.oracle.bpel.client.util.WhereCondition( "cikey = ?" );
condition.setLong(1, Long.parseLong(parentId));
//
// Perform the query using the Locator
addAuditTrailEntry(
"execute the query: cube_instance.cikey = " + parentId);
instances = this.getLocator().listInstances(condition);
addAuditTrailEntry(
"Number of instances found " + instances.length);
if (instances.length == 0)
{
addAuditTrailEntry("No instances found");
addAuditTrailEntry("Am I called from synchronous process???");
}
else
{
instance = instances[0];
parentName = instance.getProcess().getProcessId().toString();
addAuditTrailEntry
("The process name of the parent is " + processId);
}
}
}
catch (Exception e) {}

setTitle("I am called from " + parentId + "(" + processId + ")" );
setVariableData("parentId_LocalVariable", parentId);
setVariableData("parentName_LocalVariable", processId);
]]>
</bpelx:exec>

The trick is as follows. Using the "this.getParentId()" function is used to query the BPEL proces dehydration store. It queries the table CUBE_INSTANCE for those records that matches with the column CIKEY.
If there are no records found, then it is called from a synchronous process, because these type of processes are not dehydrated.
Uf the "this.getParentId()" function returns empty, the BPEL process is not called from a BPEL process, but from an external source; SoapUI, BPEL console or other webservice or client.