Wednesday, 14 September 2016

First steps with Java Embedding in Oracle SOA Suite 11g BPEL 2.0 – useful API calls

While preparing for the next session in our internal SOA for Java Professionals training program on BPEL, ImageI revisited the BPEL activity Java Embedding that allows us to enrich a BPEL process with custom, Java based functionality. I tried to determine how best to explain, present and demonstrate this activity to my colleagues. This article is a brief summary of what I will tell them. It may help you to quickly get up to speed with this activity in BPEL using Oracle SOA Suite 11g.
The Java Embedding activity allows us to add activities in a BPEL process in which we can write a Java snippet using standard JDK libraries, the BPEL APIs, custom and 3rd party Java Classes included in JAR files in deployed SCA composites (in SCA-INF/lib directory) and Java Classes and libraries available on the Classpath for the SOA Suite run time (note: through the oracle.soa.ext.jar file in the directory
<FMW_HOME>/soa/modules/oracle.soa.ext_11.1.1 we make the resources available at run time; use the ANT script in this directory to add custom classes and JAR-files to the oracle.soa.ext.jar file).
I will show the creation of the Hello World of Java Embedding – a very simple BPEL process that has a string as an input and a string as output. This simple process contains a Java Embedding activity that uses Java to:
  • Write a line of log output to the console
  • Set the name for the composite instance
  • Access the name element in the input parameter
  • Set the value on the output parameter
  • Write an entry in the BPEL audit trail
Note: no 3rd party libraries or custom classes are required for these actions.
The process looks like this:
Image
The code in the Java Embedding activity is the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
try {
  System.out.println("==> HelloWorld - Java_Embedding_setOutput, processing input; instance id "+getInstanceId());
  // note: XMLElement can only be used if it is imported using <import> in the BPEL Process
  XMLElement input = (XMLElement) getVariableData("inputVariable", "payload", "/client:process/client:input");
  String name = input.getTextContent();
  System.out.println("qname "+input.getQualifiedName()+" value = "+name);
  addAuditTrailEntry("executing HelloWorld.Java_Embedding_setOutput for "+ name);
  setCompositeInstanceTitle("Composite HelloWorld "+name);
  // note: this statement fails if the targeted element does not already exist
  setVariableData("outputVariable", "payload", "/client:processResponse/client:result", "Hello "+name);
} catch (Exception e) {
  System.out.println("exception "+e.getMessage());
  addAuditTrailEntry(e);
}
The IDE presents the snippet like this:
ImageNote that the IDE does not offer fancy features such as code completion or even design time compilation of the code: only during deployment of the SOA Composite to the SOA Suite run time environment will the correctness of the code be verified. It took me a lot of time to get the code correctly constructed – as I am a lousy typer and used to a instant compiler alerting me to any coding mistakes.
The XMLElement class used in this snippet is not part of the standard JDK APIs. Therefore, this class has to be imported in the BPEL process, using a special import element:
1
<import location="oracle.xml.parser.v2.XMLElement" importType="http://schemas.oracle.com/bpel/extension/java"/>
Image
This snippet uses a number of the API methods available for use in Java Embedding:
  • getVariableData() – to access variables in BPEL process
  • setVariableData – to set the value on variables
  • addAuditTrailEntry() – add an entry to the audit trail
  • getPreference() – access preference (property)
  • setCompositeInstanceTitle() – set the title that is displayed in the EM FMW Console
  • getInstanceId( ) – get value of Unique ID associated with this BPEL process instance
  • lookup() – do JNDI lookup – for example to get hold of EJB
  • setStatus(), setTitle(), setCreator – set meta data on process instance
  • setIndex() – set up to 6 index variables that can be used to query process instances through the BPEL API
When the application is deployed and the service is invoked, the effect of the Java code can be seen in various placing, obviously including the response from the service exposed by the BPEL process:
Image
The response is constructed in the line of code in the snippet that uses setVariable to manipulate the outputVariable.
The console window contains the following line, produced by the System.out.println statement:
Image
The title for the composite instance is set in the snippet and the result is seen in the list of instances shown in the EM FMW console:
Image
Finally, the code adds an entry to the Audit Trail for the BPEL process. This entry is seen in the Flow Trace details for the BPEL process instance:
Image
More interesting things can be done through Java Embedding when 3rd party libraries or custom classes and libraries are engaged. Some additional steps may be required to include this code with the SOA Composite or across the SOA Suite run time environment. See the resources mentioned below for more details.
A few words of warning with regard to Java Embedding in BPEL processes:
Java Embedding means functionality hidden inside, in a not very decoupled way. The Java code is hard to maintain. By embedding Java in BPEL (XML driven) we start mixing technology paradigms, that require different skills as well as expensive XML to Java Object marshalling and unmarshalling.
The best use cases for Java Embedding seems to be advanced logging/tracing or for special validations/transformations. Not to replace built in capabilities of the BPEL engine as well as the other components in SOA Suite 11g and the adapters that come with it. For more extensive custom Java logic, the Spring Component should be considered, rather than including larger sections of Java code in a BPEL process.

No comments:

Post a Comment