Tutorial 3: Data Enrichment
by Ronald van Luttikhuizen and Eric Elzinga
Published October 2009
Architect: SOA
In this tutorial we will combine the OSB Customer Service from the first tutorial and the OrderWebService to create a new composite service. The service is used when customers purchase something from Foo Inc.'s website. This way customers do not need to supply their personal information every time they make an online purchase. The information is obtained automatically using the Customer Service.
Getting to know the more advanced routing and transformation capabilities of OSB. Especially data-enrichment according to the VETO-pattern (Validate, Enrich, Transform, and Operate) using service callouts and variables. VETO is particularly difficult to achieve in Oracle ESB due to its absence of temporary variables.
Let's begin by creating a new project.
Figure 1: Oracle Workshop after creating the project and folder structure
Next step is to define the Business Service for the OrderWebService that will be used in this project.
Figure 2: OSB project after adding the WSDL's and XSD's
Figure 3: OSB project after creating the Business Services
We will now create a new Proxy Service named "OrderPS". This service looks like the OrderWebService but requires less input parameters. The customer data required by the OrderBS -first name and last name- is gathered using a Service Callout to the Customer Proxy Service.
These files describe the Order Proxy Service including its request and response payload.
Figure 4: OSB project after adding the Proxy Service
You have now defined the starting point and endpoints of this OSB project. It's time to add the routing and transformation logic.
We'll now start designing a somewhat more complex Message Flow involving data enrichment using a Service Callout.
The Proxy Service exposes the "PlaceOrder" operation. The input contains a "customerId" that is used to retrieve customer details via an invocation to the Customer Proxy Service. The original input will be enriched with the returned customer data. The enriched data is then used to invoke the "placeOrder" operation of the Order Business Service. This operation places the order and returns its status. The status is then routed as output of the OSB Order Service.
Figure 5: Message Flow, minus routing and transformation logic
We will first create a so-called Pipeline Pair. A Pipeline Pair node combines a single request pipeline and a single response pipeline in one top-level element. A Pipeline Pair node can have only one direct descendant in the Message Flow. During request processing, only the request pipeline is executed when Oracle Service Bus processes a Pipeline Pair node. The execution path is reversed when Oracle Service Bus processes the response pipeline.
Figure 6: Adding a Pipeline Pair activity
We are now going to complete the request and response flow of the Pipeline Pair among others using stages. A stage is a container of related activities to manipulate messages passing through the pipeline.
"$body/ord:PlaceOrderRequest/ord:Order/ord:customerId"
Change this expression to: " $ord:PlaceOrderRequest/ord:Order/ord:customerId /text()"
— since we are only interested in the node contents and not the element itself.
The Message Flow now looks like this:
Figure 7: Adding an Assign activity to the Message Flow
The next step is to define a Service Callout to the "GetCustomerById" operation of the CustomerProxyService to gather the required customer information. A Service Callout is used to configure a synchronous (blocking) callout to an Oracle Service Bus-registered Proxy or Business Service. When Oracle Service Bus makes a call to a service via a Service Callout action, the content of the message is constructed using the values of variables in the message context.
The header fields are left empty since there is no need to add specific processing instructions such as WS-Security information.
Figure 8: Defining a Service Callout to the Customer Business Service
Next step is to assign the correct value to the "getCustomerByIdRequestVariable" variable that is used to invoke the Customer Business Service.
<cus:GetCustomerByIdRequest xmlns:cus="http://www.waai.nl/cdm/customer">
<cus:id>{$customerId}</cus:id>
</cus:GetCustomerByIdRequest>
The expression evaluates to a request payload that contains the customer ID we previously extracted from the request.
Figure 9: Defining the request message for the Customer Proxy Service
Next we need to extract the customer detail information that is returned by the Customer Proxy Service so it can be used to invoke the Order Business Service.
" $getCustomerByIdResponseVariable/cust:Customer/cust:lastName/text()"
as "Expression"
Create another Assign activity to extract the customer's first name by providing the following properties:
" $getCustomerByIdResponseVariable/cust:Customer/cust:firstName/text()"
as "Expression"
Add the "cust" prefix and its namespace — "http://www.waai.nl/cdm/customer" (as used in the Assign expressions) — to the list of namespaces. See the first tutorial if you need help with this.
Figure 10: Message Flow after adding the Assign activities
We now have all required information to invoke the "placeOrder" operation of the Order Business Service. Next step is to create the request payload for the Business Service.
Figure 11: Message Flow after adding the Route and Routing activities
The next step is to create a valid request document for the "placeOrder" operation of the Order Business Service.
<ordSrv:placeOrder xmlns:ordSrv="http://www.waai.nl/order/service">
<order:order xmlns:order="http://www.waai.nl/order">
<customerFirstName>{$firstName}</customerFirstName>
<customerId>{$body/ord:PlaceOrderRequest/ord:Order/ord:customerId/text()}</customerId>
<customerLastName>{$lastName}</customerLastName>
<orderId>{$body/ord:PlaceOrderRequest/ord:Order/ord:orderId/text()}</orderId>
<orderName>{$body/ord:PlaceOrderRequest/ord:Order/ord:orderName/text()}</orderName>
<orderPrice>{$body/ord:PlaceOrderRequest/ord:Order/ord:orderPrice/text()}</orderPrice>
</order:order>
</ordSrv:placeOrder>
Figure 12: Defining an expression in the XQuery/XSLT Expression Editor to construct the Proxy Service's request
Make sure to add the "ord" namespace prefix and its URI "http://www.waai.nl/cdm/order".
This concludes the request flow of the OSB project. We now need to construct the response flow. This is much simpler and involves extracting the response of the "placeOrder" operation and using it to construct the response of the Order Proxy Service.
" $body/ordSrv:placeOrderResponse/return/text()"
as expression. Click "OK" to close the editor. Make sure to add a namespace with prefix "ordSrv" and URI "http://www.waai.nl/order/service".
Figure 13: Defining an expression in the XQuery/XSLT Expression Editor to retrieve the Proxy Service's response
13. Right-click the newly created Assign activity and select Insert After ? Message Processing ? Replace to add a Replace activity. Use the following settings to create a valid request payload:
<order:PlaceOrderResponse xmlns:order="http://www.waai.nl/cdm/order">
<order:return>Returned status: {$placeOrderResponse}</order:return>
</order:PlaceOrderResponse>
Figure 14: Defining the response payload of the Order Proxy Service
This completes the entire routing and transformation flow. We are now ready to test the OSB project!
Deploy the OSB project to WebLogic Server as outlined before and open Oracle Service Bus Console. Click "Project Explorer", expand the "WAAI_Case3_Order_Service" project, and browse to the "proxy" folder. Use the "Launch Test Console" icon to test the OSB project.
Figure 15: Launching Test Console in OSB Service Bus Console
Enter some valid request parameters in the new "Proxy Service Testing" dialog and click "Execute".
Figure 16: Entering a request document to test the Order Proxy Service
The test should return a valid response document indicating the status of the new order to be "OK".
Figure 17: Response document of the Order Proxy Service
You have used some of the more advanced routing and transformation capabilities of OSB in this tutorial, resulting in the creation of a VETO-pattern (Validate, Enrich, Transform, and Operate). This third and last tutorial concludes the hands-on part of this article. You are now ready to dive into OSB and get to know all its features!
Oracle Service Bus is the strategic Service Bus product for Oracle. The tutorials in this article demonstrate the capabilities of Oracle Service Bus, in particular the functionality that isn't included in Oracle ESB. The most important differences that are highlighted in the tutorials are the support for data-enrichment using temporary variables, the different adapter offering, and other types of routing and transformation.
Read more about Oracle's go-forward strategy for the Service Bus product in its Statement of Direction (SOD).
Read more about Oracle Service Bus (OSB) on OTN.
Ronald van Luttikhuizen is an Oracle ACE and architect at Approach Alliance, a Netherlands-based information and communications technology consultancy focusing on SOA and BI. ( Visit Ronald's blog)
Eric Elzinga is an Oracle integration consultant at IT-eye. a Netherlands-based specialist in Architected Integration. ( Visit Eric's blog)
.