Showing posts with label embedding. Show all posts
Showing posts with label embedding. Show all posts

Thursday, August 30, 2018

Oracle SOA: Sending delayed JMS messages

Sometimes you might want to put something on a JMS queue and make it available after a certain period has passed to consumers. How can you achieve this using Oracle SOA Suite?

Wednesday, June 12, 2013

Oracle BPEL and Java. A comparison of different interaction options

When building BPEL processes in Oracle SOA Suite 11g, it sometimes happens some of the required functionality can't easily be created by using provided activities, flow control options and adapters. Often there are Java libraries available which can fill these gaps. This blog post provides an evaluation of different options for making interaction between BPEL and Java possible.

In the examples provided in this post, I'm using the JsonPath library (https://code.google.com/p/json-path/) inside a BPEL process. A usecase for this could be that a webclient calls the BPEL process with a JSON message and BPEL needs to extract fields from that message.

The Java code to execute, is the following;

package ms.testapp;

import com.jayway.jsonpath.JsonPath;

public class JsonPathUtils {
   
    public String ExecuteJsonPath(String jsonstring, String jsonpath) {
        String result = JsonPath.read(jsonstring, jsonpath).toString();
        return result;
    }
    
    public JsonPathUtils() {
        super();
    }
}

Of course small changes were necessary for the specific integration methods. I provided code samples at the end of this post for every method.

Integration methods

Embedding

Oracle has provided an extension activity for BPEL which allows Java embedding. By using this activity, Java code can be used directly from BPEL. The JsonPath libraries to use in the embedding activity can be put in different locations such as the domain library directory or be deployed as part of the BPEL process. Different classloaders will be involved. To check whether this matters I've tried both locations.

Performance
The Java call happens within the same component engine. Below are measures from when using JSON libraries deployed as part of the BPEL process (in SCA-INF/lib).
Below are measures from when putting the libraries in the domain library folder.
As you can see from the measures, the performance is very comparable. The location where the BPEL process gets it's classes from has no clear measurable consequences for the performance.

Re-use potential
When the libraries are placed in the domain lib folder, they can be reused by almost everything deployed on the applications server. This should be considered. When deploying as part of the composite, there is no re-use potential outside the composite except possibly indirectly by calling the composite.

Maintenance considerations
Embedded Java code is difficult to maintain and debug. When deployed as part of a BPEL process, changes to the library require redeployment of the process. When libraries are put in the domain library directory, changes to it, impact all applications using it and might require a restart.

XPath

XPath extension functions can be created and used in BPEL (+ other components) and JDeveloper. This is nicely described on; https://blogs.oracle.com/reynolds/entry/building_your_own_path.

Performance
The custom XPath library is included as part of the SOA infrastructure and does not leave this context. As can be seen, the performance is comparable to the Java embedding method.

Re-use potential
The reuse potential is high. The custom XPath library can be used in different locations/engines, dependent on the descriptor file.

Maintenance considerations
Reuse by different developers in JDeveloper requires minimal local configuration, but this allows GUI support of the custom library. There are no specific changes to BPEL code thus low maintenance overhead. Changing the library on the application server requires a restart of the server.

Spring component

The Java code can be called as a Spring component inside a composite. Here another component within the composite is called. The Java code is executed outside the BPEL engine.

Performance


Re-use potential
The following blog posts links to options with the Spring Framework; https://blogs.oracle.com/rammenon/entry/spring_framework_samples. When deployed inside a composite, reuse is limited to the composite. It is possible to define global Spring beans however, increasing re-use. The code can be created/debugged outside an embedding activity.

Maintenance considerations
The Spring component is relatively new to Oracle SOA Suite so some developers might not know how to work with this option yet. It's maintenance options are better then for the BPEL embedding activity. It is however still deployed as part of a composite.

External webservice

Java code can be externalized completely by for example providing it as a JAX-WS webservice or an EJB.

Performance
Performance is poor compared to the solutions described above. This is most likely due to the overhead of leaving soa-infra and the layers the message needs to pass to be able to be called from BPEL.

Re-use potential
Re-use potential is highest for this option. Even external processes can call the webservice so re-use is not limited to the same application server.

Maintenance considerations
Since the code is completely externalized, this option provides the best maintenance options. It can be developed separately by Java developers and provided to be used by an Oracle SOA developer. Also it can be replaced without requiring a server restart or composite redeploy.

Conclusion

The technical effort required to implement the different methods is comparable. Depending on the usecase/requirements, different options might be relevant. If performance is very important, embedding and XPath expressions might be your best choice. If maintenance and reuse are important, then externalizing the Java code in for example an external webservice might be the better option.

Summary of results
This is of course a personal opinion.


The used code with examples of all embedding options can be downloaded here; https://dl.dropboxusercontent.com/u/6693935/blog/TestJavaEmbedding.zip

Friday, March 30, 2012

Base64Encode and Base64Decode in BPEL

Introduction

When working with files or messages which are not linked to an XML schema (for example opaque files when using the FileAdapter), it is often a technical requirement to perform a Base64Encoding or Base64Decoding on the message. There is no ready to use XPath expression available to perform this action, however SOA Suite 11g provides Java classes to perform encoding and decoding functionality. In BPEL these can be used in a Java embedding activity. 

In this entry I will provide 2 working example BPEL processes ready for use to perform Base64Encoding anbd decoding. Also I will give some tips on Java embedding in BPEL. I will focus on BPEL 2.0.

An alternative is to use a custom XPath function to do the encoding/decoding. I have not looked into this yet (time constraints). I can imagine BPEL development using such a custom function will go faster since you don't have to invoke a separate process to perform the action. Traceability is however something to mind here.

Implementation

To implement Java embedding in BPEL there are some things you need to keep in mind. Of course the first is; can I use Oracle supplied libraries or do I need to implement external ones. It is preferred to use Oracle supplied libraries because of several reasons;

- Oracle provides support for them
- You can avoid conflicts with libraries already present
- Your project has a smaller footprint on the server and you don't need to do additional configuration to extend your process with additional libraries

Make the required classes available in the classpath of the BPEL project.


If you decide to use external JAR's, you can do this by adding a JAR file to SCA-INF/lib directory of the project and under Project properties (right click the project) specifying the JAR in 'Libraries and classpath'. Also under Deployment click edit and specify that the JAR which is added to the project is deployed as part of the SAR. See http://docs.oracle.com/cd/E15586_01/integration.1111/e10224/bp_java.htm for more information. In this example I will use Oracle supplied libraries so I will not describe this topic further here/now.

Import the classes in BPEL


Import the required classes in BPEL by using for example the following tag to import the XMLElement class

<import location="oracle.xml.parser.v2.XMLElement" importType="http://schemas.oracle.com/bpel/extension/java"/>


Plenty of examples on the exact syntax of the import statement can be found; http://vaibhav-ambavale.blogspot.com/2011/03/java-embedding-in-bpel-20.html. You can also use tricks like; <bpelx:exec import="java.lang.*"/> to make life easier so you don't have to specify the entire package name  of commonly used classes in your embedding activity.

Create the Java embedding activity


There are some things to mind when using the Java embedding activity;
- it does not provide auto-completion and syntax checking (development is hard! only use short pieces of easy debuggable code)
- you have to use the full package name of the class unless you import the class as shown above
- you have to initialize the variables you are going to assign to, else the setVariableData method will throw a selectionFailure exception
- using the oracle.xml.parser.v2.XMLElement class makes it easy to work with variables in the BPEL process (see sample below)

I've used the default synchronous BPEL 2.0 process template in the wizard as a start and have not altered the message formats (string in, string out). This is reflected in the used Java code. Mind that using these code samples, you need to add the import location statement in the BPEL process as shown before. The encoding and decoding process have a similar structure; first initialize the output, then a Java embedding activity which is available under the Oracle Extensions as can be seen in the below screenshot.


Base64Encode



addAuditTrailEntry("Base64encode started");  
try {  
XMLElement input = (XMLElement) getVariableData("inputVariable","payload","client:input");  
java.lang.String input_str = input.getTextContent();  
addAuditTrailEntry("Base64encode input_str="+input_str);  
oracle.soa.common.util.Base64Encoder encoder = new oracle.soa.common.util.Base64Encoder();      
java.lang.String encoded = null;     
encoded = encoder.encode(input_str);  
addAuditTrailEntry("Base64encode encoded="+encoded);  
setVariableData("outputVariable","payload","client:result",encoded);  
} catch (Exception e) {  
  addAuditTrailEntry("Base64encode Exception: "+e.getMessage());  
}  
addAuditTrailEntry("Base64encode ended");

Base64Decode



addAuditTrailEntry("Base64decode started");   
try {   
XMLElement input = (XMLElement) getVariableData("inputVariable","payload","client:input");   
String input_str = input.getTextContent();   
addAuditTrailEntry("Base64decode input_str="+input_str);   
oracle.soa.common.util.Base64Decoder decoder = new oracle.soa.common.util.Base64Decoder();       
String decoded = null;      
decoded = decoder.decode(input_str);   
addAuditTrailEntry("Base64decode decoded="+decoded);   
setVariableData("outputVariable","payload","client:result",decoded);   
} catch (Exception e) {   
  addAuditTrailEntry("Base64decode Exception: "+e.getMessage());   
}   
addAuditTrailEntry("Base64decode ended");

You can download the complete sample with the encode and decode processes ready for deployment here; http://dl.dropbox.com/u/6693935/blog/Base64Utils.zip