Reusing data type definitions in Oracle Service Bus
By Chris Tomkins on Jan 21, 2008
Note: This post was first published before Oracle merged with BEA when the Oracle Service Bus product was known as AquaLogic Service Bus, hence the occasional reference to BEA and AquaLogic Service Bus.
One of the main goals of Service Oriented Architecture is to promote reuse, not just of services but also of things like data type definitions - after all, once you've defined something once you don't typically want to have to do it again. One common web services practice however, actually prevents the reuse of data type definitions. In the remainder of this post I will describe the practice, how it prevents reuse and explain an improved practice which allows these data type definitions to be reused in other services.
Web services are described by a WSDL (Web Services Description Language) document, one of the the key elements of which is the types section, where the data type definitions for the request and response messages for your web service are described, in XML schema syntax. In the interest of simplicity these definitions are often placed inline, i.e. described within the WSDL file, which is fine for your web service but prevents these definitions from being reused elsewhere.
The alternative approach is to define your data types in a separate XML schema file and add a line into the WSDL document which imports this schema into the types section of the WSDL. This not only gives you better encapsulation - your data type definitions are described in one file and your web service in another - but also allows you to use these data type definitions in other services.
Lets work through a simple scenario to demonstrate why you might want to do this:
Imagine you have an existing SOAP/HTTP web service (we'll use the free CurrencyConverter service provided by WebServiceX) which you need to expose to a JMS messaging system. In order to keep things simple you decide to make the message definitions used by the JMS messaging system the same as those expected by the web service.
The steps you would follow are described below:
1 - Save a copy of the CurrencyConverter WSDL document to your machine and extract the types definitions from it into a separate schema. To do this, open the CurrencyConverter.wsdl file and copy and paste the contents of the <wsdl:types> element into a separate file called CurrencyConverterTypes.xsd.
2 - Next we need to ensure the namespaces are correct. Modify the first line of the CurrencyConverterTypes.xsd file to say:
3 - Now modify the <wsdl:types> section of CurrencyConverter.wsdl to import CurrencyConverterTypes.xsd:
<s:import namespace="http://www.webserviceX.NET/" schemaLocation="CurrencyConverterTypes.xsd" />
We have now extracted the inline data type definitions from our WSDL. In the remainder of the steps we will create the business service representing our SOAP/HTTP web service and the JMS messaging proxy service which exposes this to the JMS messaging system.
4 - Add the modified CurrencyConverter.wsdl and CurrencyConverterTypes.xsd to a zip file called CurrencyConverter.zip (this is not essential but will make it easier to import them into Oracle Service Bus and also save us having to manually create a reference between the XML schema and the WSDL).
5 - Login to your AquaLogic Service Bus domain and create a new project (remember to click Create in Change Center if you haven't already created a new session).
6 - Navigate into this project using Project Explorer and import the zip file created in step 4 using the Zipped Resources option from the Create Resource drop down.
You will need to browse to the zip file on the system and click Open, then click Next and Import.
7 - In the same project, create a WSDL Web Service business service called CurrencyConverterBS from the imported WSDL (the basic steps can be found in my earlier blog post).
8 - In the same project, create a new proxy service called CurrencyConverterPS by selecting Proxy Service from the Create Resource drop down and selecting the Service Type to be Messaging Service. Click Next.
9 - Set the Request Message Type to be XML and click the adjacent Browse button.
10 - Select the CurrencyConversionTypes schema by clicking on it and then select the ConversionRate element (this is the data type definition for the request message) and click Submit.
11 - Repeat steps 9 and 10 for the Response Message Type ensuring you select the ConversionRateResponse element as the data type definition for the response message and click Next.
Note: If you had left the data type definitions inline in the original WSDL file, you would not have been able to select the request and response message type definitions as you have done in steps 9-11.
12 - Choose the protocol to be JMS and ensure the hostname part of the Endpoint URI points to your host (or localhost, if you have not specified a fully qualified domain name for your AquaLogic Service Bus domain). Copy the Endpoint URI as you will need it later and then click Next.
Note: The last part of the URI refers to the JNDI name of the JMS input queue of your proxy service.
13 - Paste the Endpoint URI you copied into the Response URI field and modify the last part of the URI to be CurrencyConverterPSResponse (the JNDI name of the response JMS queue). Click Last and then Save.
15 - Click on the CurrencyConverterPS node and choose Add Route (give the route node a more sensible name and a description by left clicking on it and choosing Edit Name and Description).
16 - Click the route node and choose edit Route
17 - Click Add an Action and choose Communication>Routing.
18 - Set the Service attribute to be the CurrencyConverterBS business service.
19 - Select ConversionRate as the invoking Operation from the drop down.
20 - Click Save All.
22 - Activate your changes.
We now have a JMS messaging proxy service which fronts our SOAP/HTTP web service and uses the same data type definitions for the request and response messages. To test this, you can either use the test console by clicking on the bug icon (change the FromCurrency to GBP and the ToCurrency to USD as a good example) or by placing a message on the request queue as pointed to by the request endpoint URI (see step 12 above) ensuring your request message is in the right format. Note AquaLogic Service Bus has created the JMS resources required for your proxy service automatically so you will not need to create them yourself.
In summary, if you have data type definitions you expect to reuse in other services then you should aim to put them in external XML schemas rather than defining them inline in WSDL documents. If you have types that are specific to your web service and you don't envisage using them again, then it is fine to define them inline in the WSDL. If you wish, you can choose to have a mixture of both.