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"/>
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
= bpel 1.1 ?
ReplyDeleteThe example given in this post is BPEL 2.0 (SOA Suite 11g). In Oracle SOA Suite 10g (BPEL 1.1) you can use com.collaxa.common.util.Base64Decoder/Base64Encoder instead of oracle.soa.common.util.Base64Decoder/Base64Encoder. See http://darrenrogan.blogspot.nl/2008/05/bpel-decode-base64-element-via-embedded.html for an example.
ReplyDeleteit gives string output the decode should be xml output in my case
ReplyDeleteHi Maarten ,
ReplyDeleteWith the above code only data inside xml tags gets encoded i want to encode complete XML document with tags and enclosed content. Is there a way to do the same.
Before encoding, get your xml assigned to a 'string' type variable using getContentAsString() and then use the below java embedding
Deletetry{
String input = (String) getVariableData("EncodePayloadInput");
oracle.soa.common.util.Base64Encoder encoder = new oracle.soa.common.util.Base64Encoder();
String encodedString = null;
encodedString = encoder.encode(input);
addAuditTrailEntry("Base64decode encoded="+encodedString);
setVariableData("base64EncodedString",encodedString);
}
catch (Exception e) {
addAuditTrailEntry("Base64encode Exception: "+e.getMessage());
}
Hi Maarten,
ReplyDeleteWhat is the difference in using java.util.Base64.getMimeDecoder() & oracle.soa.common.util.Base64Decoder ??
And which one is much better?
BR.
Hi Maarten,
ReplyDeleteWhat is the diffrence in using java.util.Base64.getMimeDecoder()
and oracle.soa.common.util.Base64Decoder??
And which is better out of these?
BR.