Today we had an interesting exploration into the many ways available in the Oracle Service Bus to load a piece of XML into a variable in a message flow – to use as the source for populating part of a to-be-forwarded request message to the business service or for enriching the response message. Even such a seemingly straightforward task turned out to have a number of ways to approach, each with their own merits and complexities.
The various approaches we uncovered in a space of ten minutes or so:
- use a static expression in an Assign action, simply copying the XML content into the variable
- use the function fn:doc that can load XML from a local file and assign the XML to a variable that way
- introduce the file adapter to load the XML file from the local file system and assign it to a variable; this would also support non-XML formats – like comma separated values – that can be converted to XML
- use the database adapter (or the fn-bea:execute-sql) to retrieve the XML content from a relational database
- store the XML content in an XQuery transformation
- do any of the above and wrap it inside a Proxy Service that can be invoked from from other services, potentially governed by the service result cache
Considerations for choosing an approach definitely include the reusability (we do not want to define the same XML document in more than one location) and overhead (especially for parsing the XML). Solutions that cache the XML rather than load it every time a service instances has a need for it are definitely preferred.
It turns out that due to the stateless nature of the OSB the first four methods are not attractive in our situation – where we have very few changes in these static (!) XML documents and many instances of the services. The fifth approach, using the XQuery resource, is easily reusable across projects and services and has as an important bonus the fact the XQuery transformation templates are cached by the OSB, across the stateless instances of OSB Services.
Using XQuery templates to cache static XML content for assignment to variables
An XQuery template can be created with no other function than the embodiement of an XML document. In a very simple form, that would mean the following steps:
1. create a new XQuery Transformation
2. Specify the name of the XQuery transformation. Pick a name that describes the XML content that you will create or paste in this file.
3. Press Next. The next two steps have you select the source and target types for the XQuery transformation. In this case, these do not matter at all. Pick any(type) you like and proceed to Finish.
4. The XQuery editor opens. Open the source tab. And remove all text except the first line.
5. Paste the XML content in the XQuery template, under the first line:
Assign the XQuery resource to the variable
When you now open the variable expression editor from the Assign activity’s property palette, select the XQuery Resources tab. Browse to the XQuery resource that contains the static XML content that you are interested in.
After assigning the XQuery resource to the variable, the property palette looks like this:
In the message flow, the variable myVariable will contain the XML document that you pasted into the StaticXMLContent.xq file, after the assign step is done.
Assigning XML document directly to variables
The most straightforward method – without any reuse potential or caching benefit, unless used wrapped in a Proxy Service that is accessed from a Business Service that is ‘service result cache enabled – is invoked as shown in this figure:
Service result cache in OSB: http://download.oracle.com/docs/cd/E14571_01/doc.1111/e15867/configuringandusingservices.htm#CHDDCGEE
Discussion on OTN Forum on caching of variables in OSB: http://forums.oracle.com/forums/thread.jspa?threadID=2163579&tstart=0
Reading key-value properties in OSB: http://forums.oracle.com/forums/thread.jspa?threadID=1131939
Article that started our whole discussion: http://blogs.oracle.com/christomkins/2010/02/domain_value_maps_in_oracle_se.html Chris Tomkins on Domain Value Maps in OSB.