Domain Value Maps (DVM) are an interesting feature of Oracle SOA Suite for supporting Canonical Data Models. They help to map from one vocabulary, used in a given domain, to another vocabulary used in a different domain. For example, one domain might represent a country with a numeric code while another domain may represent a country with the ISO-standard alphanumeric country code. In SOA Suite 10g there were part of the “old” Oracle ESB and in SOA Suite 11g they can be used from a Mediator component.
Unfortunately this feature is not yet available in Oracle Service Bus (OSB). It will be added in the future, as the statement of direction states.
This might be less of a problem when using both the Oracle SOA Suite together with the Oracle Service Bus in a larger architecture. In this case, the responsibility for mapping these values can be delegated to the SOA Suite 11g Mediator component, where the DVM functionality is available.
But if only the OSB is used standalone, then such value mappings would be nice in the OSB as well. With the help of XQuery the DVM functionality can be implemented in a similar way, so that if the feature is later available in a new version of OSB, it can be replaced by that with minimal work involved. This blog entry shows the custom DVM functionality implemented for the Oracle Service Bus.
Custom DVM functionality implemented using XQuery function in OSB
In order to show the custom DVM functionality a simple OSB service has been implemented. It only consists of a simple Proxy Service, which accepts a request message with two static code values (country and currency), translates the message into the canonical format and returns (echo) it to the caller. A sample request and the corresponding response can be seen in the window below taken from soapUI.
The message flow of the Proxy Service below uses a stage (TransformationToCanonicalState), which is responsible to map from the source to the canonical format. First the value maps are assigned to variables (Assign 1 for country map and Assign 2 for currency amp) and then the message is transformed using an XQuery function (Assign 3).
For the definition of the Domain Value Maps the same format known from the SOA Suite is used. The picture below shows the map for the currency code mapping. The <columns> element defines the number of value domains and assigns a name to each domain, in our case Source and Canonical. The <rows> element defines the value mappings, i.e. the value 10 in the Source domain should be mapped to to the value CHF in the Canonical domain.
The format is based on a XML Schema which can be found in the Oracle SOA Suite documentation here. An XSD file with the schema is also part of the example OSB project which can be downloaded from here.
The next window shows the definition of the 3rd Assign action in the XQuery Expression Editor. The first parameter holds the source message to be translated and the next two parameters hold the content of the two value maps for country and currency mapping.
The XQuery script (transform.xq) implements the transformation. The next figure shows it in the graphical (design) view. The translation of the countryCode to isoCountry and from currencyCode to isoCountry are both using the corresponding parameters holding the content of the domain value maps.
The source of the transform() function is shown below
The custom DVM functionality is wrapped by the lookupValue() function, matching the DVM implementation of the Oracle SOA Suite, where a function with the same name is available. The only difference is the first parameter, which in our case is an element holding the contents of the domain value map, whereas in the SOA Suite version the first parameter only holds the name (reference) of the DVM file.
The source of the lookupValue() function can be seen below
The function looks up the necessary source value and translates it to corresponding target value.
Unfortunately the Oracle Service Bus does not support the XQuery Modules feature, which would allow the creation of function libraries to be reused. Therefore the lookupValue() function needs to be copied into the transform.xq script. This copy-paste reuse is not optimal, I hope that OSB will fully support XQuery 1.0 and especially the Module functionality in the future.
This finishes the custom implementation of the DVM functionality in Oracle Service Bus. It closely matches the DVM functionality of the Oracle SOA Suite, which Oracle will offer in a future version of OSB as well. The solution shown in this blog can help in the meantime and will allow for an easy migration to the built-in function in the future. It’s only a proof-of-concept and has not yet been used in production!
The example project can be downloaded form here.