Some time ago I was thinking in how to read XML Resources available in OSB projects at runtime. It would be very useful to hold some configuration data to be read by the proxy services through XPath or Java Call. After many searches in Google, I did not find any documentation or example in how to read OSB resources content programmatically at runtime. The popular OSB APIs and MBeans do not provide any method to get the resources content, but only their references. The question was how to get the resources content through their references.
With the help of JShrink I spent some time decompiling the OSB native jar functions and making a reverse engineering to discover how to do this. Fortunately, after some good tries I found what I was looking for. Using some internal OSB built-in libraries we can access any project resource at runtime.
In this article I will show how to read a sample XML Resource programmatically at runtime. In this sample I will use a Custom XPath to read a XML resource that holds application configuration parameters. Obs.: the same API shown here can also be used into a Java Call.
The sample project structure will look like this:
File “xsd/Parameters.xsd”: a simple schema that we’ll use in this scenario to describe the XML structure that holds the parameters:
<xsd:complexType name="Parameters"> <xsd:sequence> <xsd:element name="ParameterList" type="tns:ParameterList"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="ParameterList"> <xsd:sequence> <xsd:element name="Parameter" type="tns:Parameter" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="Parameter"> <xsd:sequence> <xsd:element name="Key" type="xsd:string"/> <xsd:element name="Value" type="xsd:string"/> </xsd:sequence> </xsd:complexType>
File “xml/Parameters.xml”: the sample XML that will be read by our XPath function at runtime:
<ns0:Parameters xmlns:ns0="http://gibaholms.wordpress.com/samples/xsd/2012/02/parameters"> <ns0:ParameterList> <ns0:Parameter> <ns0:Key>Color</ns0:Key> <ns0:Value>Blue</ns0:Value> </ns0:Parameter> <ns0:Parameter> <ns0:Key>Size</ns0:Key> <ns0:Value>500</ns0:Value> </ns0:Parameter> </ns0:ParameterList> </ns0:Parameters>
File “xq/ReadXmlParameters.xq”: a sample test XQuery that calls our XPath function passing as argument the full reference path to the XML parameters file:
xquery version "1.0" encoding "Cp1252";
(:: pragma bea:schema-type-return type="ns0:Parameters" location="../xsd/Parameters.xsd" ::)
declare namespace xf = "http://tempuri.org/ReadXmlResource/xq/ReadXmlParameters/";
declare namespace ns0 = "http://gibaholms.wordpress.com/samples/xsd/2012/02/parameters";
declare namespace param = "http://gibaholms.wordpress.com/xpath/ReadXmlResource";
declare function xf:ReadXmlParameters() as element() {
param:readXml("ReadXmlResource/xml/Parameters")
};
xf:ReadXmlParameters()
Now, let’s create the custom XPath that does the magic. Create a simple Java project and add the following compile dependencies:
- <MIDDLEWARE_HOME>\Oracle_OSB1\modules\com.bea.common.configfwk_1.5.0.0.jar
- <MIDDLEWARE_HOME>\Oracle_OSB1\modules\com.bea.core.xml.xmlbeans_2.1.0.0_2-5-1.jar
- <MIDDLEWARE_HOME>\Oracle_OSB1\lib\modules\com.bea.alsb.resources.core.jar
- <MIDDLEWARE_HOME>\Oracle_OSB1\lib\modules\com.bea.alsb.resources.xml.jar
The XPath project structure is shown below:
In the file “osb-readxmlresourcefunction.xml” we describe the XPath functions contract. This file is a requirement of OSB and must be copied to the functions directory with the generated jar file:
<xpf:xpathFunctions xmlns:xpf="http://www.bea.com/wli/sb/xpath/config"> <xpf:category id="Custom Functions"> <xpf:function> <xpf:name>readXml</xpf:name> <xpf:comment>This function reads a XML Resource file from OSB</xpf:comment> <xpf:namespaceURI>http://gibaholms.wordpress.com/xpath/ReadXmlResource</xpf:namespaceURI> <xpf:className>com.wordpress.gibaholms.xpath.ReadXmlResource</xpf:className> <xpf:method>org.apache.xmlbeans.XmlObject readXml(java.lang.String)</xpf:method> <xpf:isDeterministic>true</xpf:isDeterministic> <xpf:scope>Pipeline</xpf:scope> <xpf:scope>SplitJoin</xpf:scope> </xpf:function> </xpf:category> </xpf:xpathFunctions>
The secret to access OSB resources at runtime is the various “*Repository” classes. The code of our “readXml” XPath function is shown below:
package com.wordpress.gibaholms.xpath;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import com.bea.wli.config.Ref;
import com.bea.wli.config.component.NotFoundException;
import com.bea.wli.sb.resources.config.XmlEntryDocument;
import com.bea.wli.sb.resources.xml.XmlRepository;
public class ReadXmlResource {
public static XmlObject readXml(String xmlRefPath) {
Ref ref = new com.bea.wli.config.Ref("XML", Ref.getNames(xmlRefPath));
XmlObject xmlObject = null;
try {
XmlEntryDocument xmlEntryDocument = XmlRepository.get().getEntry(ref);
String xmlContent = xmlEntryDocument.getXmlEntry().getXmlContent();
xmlObject = XmlObject.Factory.parse(xmlContent);
} catch (NotFoundException e) {
e.printStackTrace();
throw new RuntimeException("XML Resource not found.");
} catch (XmlException e) {
e.printStackTrace();
throw new RuntimeException("Error parsing XML content.", e);
}
return xmlObject;
}
}
As we can see in the code, the class “com.bea.wli.sb.resources.xml.XmlRepository” does the magic of retrieve the XML resource content through it “com.bea.wli.config.Ref” reference. Following the same principle, we can use the other various “*Repository” classes to access other types of resources in projects at runtime, like Schemas, XSLTs, WSDLs and so on.
To test the function, just run the XQuery “xq/ReadXmlParameters.xq” in the sbconsole:
The test XQuery has no parameters, so just execute it:
Then you must see the parameters XML loaded at runtime, like shown below:
I’m glad to share this discovery with other ALSB / OSB developers and I hope help you to do more useful things with this knowledge.
If someone already has another solution to read OSB project resources at runtime or already use this API for some other purpose, please share the experience with us through comments. Thanks.
Attachments
Source Code:
https://github.com/gibaholms/articles/tree/master/Read_XML_Resource_in_OSB
Tags: 11g, alsb, aqualogic, bea, bus, enterprise, fusion, middleware, oracle, osb, service, soa, xpath





02/28/2012 at 9:37 AM |
Really nice,
Great we can then have a central MDS project which contains all the xml entries.
maybe you can also make a MDS implementation, where you have your osb partition in MDS or re-use the soa one for the xml ( the soa already has the required upload and delete scripts )
for the OSB book ,Eric Elzinga make a recipe where he used a file adapter to do the same.
thanks for sharing.
02/28/2012 at 4:34 PM |
Thanks for the feedback Biemond.
Im planning to use this technique to make something about integrating JUnit to create automated testing support to XQuery and XSLT transformations, and even to automate Proxy Services message flow unit testing.
What do you think about it ?
02/29/2012 at 5:46 PM |
Hi,
I know somebody already tried to do this for Xquery , I know the jdev xquery jars are different then that of OSB.
but it would be really cool.
good luck
03/01/2012 at 10:51 PM |
Great Post!
07/03/2012 at 9:12 AM |
why not simply rename the extension from xml to xq?
07/03/2012 at 11:09 AM |
Hi Alessandro,
Thanks for the reply!
For the case of data parametrization your suggestion is valid, I already did this xq approach in many clients. The only cons I’ve come across was the need to use a assign task to get all the parameters every time and the time spent to explain the sysadmin what is a xq and no support for caching the parameters.
But the data parametrization is only a practical sample to show the possibilities, much more things can be done using this approach. The main purpose was to show the possibility to get programmatically at run-time not only xml, but any resource from OSB, like cannonical models, xqueries, xslts, do unit testing of transformations with JUnit, etc.
08/02/2012 at 5:04 PM |
“This file is a requirement of OSB and must be copied to the functions directory with the generated jar file”. Where is this function directory?
08/03/2012 at 7:30 AM |
Hi Dhiego,
To install a custom xpath function in OSB 11g, you must copy the jar file and the xml descriptor to the folder “\Oracle_OSB1\config\xpath-functions”, then you must restart the server.
08/03/2012 at 9:50 AM |
Thank you very much. I’ll try it!
11/09/2012 at 12:38 PM |
excellent post. in my case I have some parameters which changes from environment to environment . I wanted to add to customization xml file and have proxy read it from it. couldn’t find a way to add/read custom variable to customization file. Any ideas?
11/12/2012 at 2:49 AM |
Hi Ross,
With customization files you will be able to do search and replace in your xml parameters or xquery, but i never tried it With a pattern, maybe you must replace the exact value. Letme know if worked. Regards.
02/07/2013 at 12:30 PM |
Nice post.
I followed this article to access an osb resource (xsd) within a jar called from a proxy service via java callout. But I am getting an error – java.lang.RuntimeException: XML Resource not found at line
Ref ref = new com.bea.wli.config.Ref(“XML”, Ref.getNames(schemaRefPath));
I verified the path of the resource and everything is ok. Could you please help.
02/07/2013 at 2:31 PM |
Hi Viv,
If your resource is a xsd, you must try:
Ref ref = new com.bea.wli.config.Ref(“XSD”, Ref.getNames(schemaRefPath));
Each type of resource have its own “type name” (XML, XSD, WSDL, etc…)
Regards,
Gilberto
02/21/2013 at 3:19 AM |
Hi Gib,
Changes it to XSD leads to this error -
java.lang.IllegalArgumentException: Expected a query of type XML but got XSD
at this line of code -
XmlEntryDocument xmlEntryDocument = XmlRepository.get().getEntry(ref);
02/21/2013 at 9:45 AM |
Hi Viv,
The BEA naming conventions are pretty consistent, the classes XmlEntryDocument and XmlRepository works only for “XML” resources…
For “XMLSchema” resources, you must replace it to “SchemaEntryDocument” and “SchemaRepository”, from the jar file “com.bea.alsb.resources.schema.jar”.
Another thing, in the previous post I said “XSD”, but I guess the correct String is “XMLSchema”. Try with both please and then let me know which worked.
02/21/2013 at 1:24 PM |
Appreciate your help Gib. It worked with following line of codes -
Ref ref = new com.bea.wli.config.Ref(“XMLSchema”, Ref.getNames(schemaRefPath));
try {
SchemaEntryDocument schemaEntryDocument = SchemaRepository.get().getEntry(ref);
String xsdContent = schemaEntryDocument.getSchemaEntry().getSchema();
Another thing to note that the schema name should NOT suffix “.xsd”.
02/21/2013 at 2:30 PM |
Great news Viv !! Thanks for your feedback. Regards !