Loosely typed interfaces – The Normalizer Pattern and Oracle SOA Suite

When getting two or more systems working together, the making a connection part is generally the easiest, identity propagation is a bit trickier, but many times, the syntax and semantics of one system is at odds with another one. Over the decades this has been manifest in many ways and thankfully there are tools and techniques to work through them. A collation of such techniques is Enterprise Integration Patterns. The book, along with the associated website, is worthy of a dedicated article or two, and is not the real subject of this article. One message transformation pattern the book describes is the Normalizer Pattern where different formats for essentially the same object are catered for.
An example where this form of message translation becomes necessary is when using a service with a loosely typed interface. This can often happen when an existing system or utility (such as a batch / command processor) gets exposed as a web service. The request / response payload is little more than a collection of key / value pairs. There are a couple of ways to cater for this using Oracle SOA Suite 11g which I will outline in this article. One has full tool support. The other, a solution using XSLT, is not fully supported, but has an advantage in that the XSLT can be used both with the BPEL and Mediator components.

Troublesome Payloads
The challenge is to get something that is strongly typed into something that is loosely typed

Strongly Typed Loosely Typed


Furniture
Pam Beech
50000
20000
47000


NAME
Furniture


MANAGER
Pam Beech


BUDGET
50000


SPENT
20000


COMMITTED
47000

Now this is quite a simple example and the real world has a lot more complicated cases out there. Ones that would involve number formatting, character encoding, attribute concatenation, and so on. For the purposes of this exercise however, it is ideal to illustrate the point. All the files in this example are free and available for you to use, modify or incorporate into your own solution as you see fit. The example was produced and tested using Oracle Fusion Middleware 11.1.1.2.0. That is JDeveloper Studio 11.1.1.2.0 and WebLogic Server 11gR1. To reduce the number of files and dependencies involved, the example is a simple service (BPELProcessExample.wsdl) that takes a strongly typed request payload and returns a loosely typed response payload. The SOA composite project contains two BPEL processes that provide slightly different implementations for this same WSDL.

BPEL assign with copy and insertAfter
You can cater for the key / value pair structure by repeatedly appending a new ‘property’ element and then, using an XPATH predicate to specify which ‘property’ element is the target, copying the desired values. In the BPEL process this can all be done in a single ‘assign’ command, using the insertAfter instruction from the Oracle BPEL extension library. The BPEL designer supports this approach, and it is used extensively in production systems around the globe. It can get difficult to maintain and hard to read if the payload is large though. If dealing with a large payload see if you can split the copy / insertAfter instructions into two or more ‘assign’ commands. Ideally, you would give these ‘assign’ commands logical names such as ‘assign_part_1_admin_details’ and ‘assign_part_2_finance_details’. What is a large payload in this case then? Well, I would say that if you have more than 10 key value pairs you should be seriously thinking about splitting them up and if you have more than 20, you should be definitely splitting them up. Remember, you might be familiar with the structure and understand how it is constructed, but what about the college graduate brought in by the consulting firm in a months time, or even you having to come back to this in 6 months time? Go on, make the maintenance a bit easier for everyone and break that assign behemoth into manageable chunks!

BPEL transform with XSLT
If experienced in dealing with XML documents then this approach will probably be very familiar to you. Extensible Stylesheet Language Transformations is used to convert XML data into some other format, which may also be XML data. In this case the stylesheet explicitly describes the target XML structure, making it somewhat easier to read than the BPEL assign approach described earlier. For example…



MANAGER






The ‘client’ is a namespace prefix for the schema and in this SOA composite example the request and response happen to be defined in the same schema. This is easier to read, even if one is not all that familiar with XSL. For large payloads it is not necessary to split up the transformation as one might consider for the BPEL assign, but it could be done. The single transformation file could have a whole set of templates. However, the XSL Mapper does not support this approach yet, so if using this approach you will have to work in the Source editor, not the Design mode. Since this is using XSLT, the same XSL file can be used by the Mediator too, so it is not only a BPEL solution.

Which one is right for me?
As one can see from the diagrams there is not much difference in the BPEL designer between the two examples and the decision on which technique to use would be based on factors which are different from company to company, but clearly use of the XSL mapper is an important factor.
The complete example application with SOA composite is available at http://sites.google.com/site/soastation/soastation_looselytyped_normalizer.zip

Custom XSLT functions in Oracle BPEL and ESB

In the Oracle SOA Suite there is a Custom XSLT function example. You can find it in bpel/samples/demos/XSLMapper/ExtensionFunctions. It is not immediately obvious that this approach of enabling access to static methods on a java class works for transformations in the ESB too. This is because both BPEL and ESB use the same Oracle XSLT processor.

The principle is simple:

To illustrate how straight forward this is I’ll go through an example that converts HEX to Decimal. So, with a class called xsltfunctions.HEX2DEC the namespace is defined in an XSL file as xmlns:sample = “http://www.oracle.com/XSL/Transform/java/xsltfunctions.HEX2DEC”.

The class HEX2DEC has static method called toDecimal:


public static String toDecimal(String hex) {
String dec = new BigInteger(hex, 16).toString(10);
return dec;
}

In the XSL file this method is invoked like this:

Note that the namespace prefix ‘sample’ is defined as mentioned earlier using the http://www.oracle.com/XSL/Transform/java/ combined with the classname.

So, you could compile the HEX2DEC class, add it to a jar and put that jar in /j2ee/home/applib so that any transform using the custom function in BPEL or ESB will work. It’s that simple.

All that’s left is to inform JDeveloper of your custom function so that you can easily refer to it in the XSL Mapper to do this you need to do two things:

  1. Create an XML file detailing the extension functions you have and tell JDeveloper about it in the “User Defined Extension Functions Config File” field of the XSL Map preferences (Tools->Preferences->XSL Map). This will list the functions in the User Defined Extension Functions section of the XSL Map component palette so you can drag and drop it into the XSLT at design time.
  2. Add the class to the JDeveloper classpath so that you can run the transform using the test feature with JDeveloper.

The extension functions XML looks like this:

To add the class to the JDeveloper classpath involves defining a JDeveloper extension. For JDeveloper 10.1.3.2 the extension needs to be a valid JSR 198 extension. Documentation on this can be found in /doc/extension/ide-extension-packaging.html.

Do this by defining a simple ‘extension.xml’ like this:

<extension version="1.0" esdk-version="1.0" id="xstlfunctions"
xmlns=”http://jcp.org/jsr/198/extension-manifest”&gt;
SOAStationXSLTFunctions
Peter O’Brien

The extension.xml (naming convention for these files) needs to be in the meta-inf folder of the jar containing the classes. The filename for the jar needs to be a combination of the extention id and esdk-version so in this case it would be xsltfunctions.1.0.jar. This jar should then be copied into the /extension directory.

Restart JDeveloper to pick up the changes for both the ‘User Defined Extension Functions Config File’ and the JDeveloper extension and you’re ready to go.