Tutorial 1: First Spin
by Ronald van Luttikhuizen and Eric Elzinga
Published October 2009
Architect: SOA
Getting to know Oracle Service Bus by exposing a simple service
The multinational Foo Inc. wants to reuse a service from its local Dutch subsidiary that exposes and retrieves customer information. The Dutch payload has to be transformed into Foo Inc.'s canonical data model that is in English.
In this tutorial we will develop an OSB project that invokes the KlantWebService; "klant" means customer in Dutch. The returned payload will be transformed into the English canonical data model using Assign and Replace activities. Deployment of the KlantWebService is described in the Installation and Configuration Guide.
Getting to know OSB basics such as Business and Proxy Services and basic routing rules and transformation capabilities that are based on XQuery. Oracle ESB mainly uses XSLT for transformation. OSB supports XSLT next to XQuery. Getting to know Oracle Workshop as IDE. OESB development is done in JDeveloper.
Let's start by creating a new Oracle Service Bus project.
Figure 1: OSB project in Oracle Workshop after creating the folders
OSB uses the notion of Business Services to define access to enterprise services such as Web Services, JMS destinations, and EJB's. A Business Service is configured by specifying its interface, type of transport it uses, its security requirements, and other characteristics. We will create a new Business Service for the "KlantWebService" based on its deployed WSDL.
First we need to import the WSDL and associated XSD's in our OSB project.
Right-click the business/wsdl folder and select Import → Oracle Service Bus - Resources from URL. Enter the URL of the deployed "KlantWebService" WSDL as "URL" and "KlantWebService" as "Resource Name". Select "WSDL" as "Resource Type" and click "Finish".
Use the Oracle WebLogic Administration Console — normally located at http://host:7001/console — in case you don't know the WSDL's URL. Log into Oracle WebLogic Management Console and browse to Deployments ? KlantWebServiceEAR. Expand the KlantWebServiceEAR deployment and select Web Services ? KlantWebService. Select the "Testing" tab, expand "KlantWebService", and click "?WSDL" to inspect the WSDL and its location.
Figure 2: Importing the WSDL of the KlantWebService
The "Review Resources" dialog shows the resources that will be imported: "KlantWebSerice.wsdl" and two referenced XSD's. Click "Finish". The wizard will import the WSDL and XSD's.
Note that the XSD filenames are based on the URL's in the WSDL. These XSD filenames might include question marks that are not well understood by Oracle Workshop. We need to rename these XSD's if this is the case; otherwise you can skip this step.
We continue by creating the Business Service that is based on the imported resources.
Figure 3: Creating the Business Service
Figure 4: Selecting the imported WSDL of the KlantWebService during creation of the Business Service
You have now exposed the deployed Web Service as Business Service in the OSB project and made it available as endpoint to route to. Next step is to create a Proxy Service that exposes the OSB Service to service consumers.
Proxy Services are the interface that service consumers use to connect with managed back-end services. Proxy Services are definitions of intermediary Web Services that the Oracle Service Bus implements locally. Proxy Services are configured by defining its interface using a WSDL and the type of transport it uses. Message processing logic is specified in message flow definitions when defining a Proxy Service.
The resources archive contains the WSDL and XSD of the Proxy Service we will be creating in the next steps.
Figure 5: Selecting the binding of the Customer Proxy Service's WSDL
Figure 6: Configuring the Proxy Service
You have now created both the Business and Proxy Service. We continue by wiring these together and defining the transformation between the English canonical data model and the Dutch Web Service payload.
The implementation of a Proxy Service is specified by a Message Flow definition. A Message Flow defines the flow of request and response messages through the Proxy Service. The following elements are used to construct a Message Flow: pipeline pair (sequence of stages for request and response flows), branch node (branching based on message content or operation), route node (definition of message destinations such as Business Services), and start nodes. Message Flow elements can be combined in arbitrary ways to form a tree structure with the start node always (and only) occurring as the root of the tree and the route nodes. The last nodes in a branch (leaf nodes) may be Route nodes or Echo nodes.
We need to transform the input from the Proxy Service to the input of the Business Service and vice versa for the response. We're going to add activities to the Message Flow of the newly created Proxy Service to achieve this.
The "KlantWebService" Business Service has 3 operations: "getAllKlanten", "getKlantById", and "addKlant". The "CustomerPS" Proxy Service has three matching operations: "GetAllCustomers", "GetCustomerById", and "AddCustomer". These will be routed to their Dutch equivalents using an Operational Branch.
Oracle Workshop now creates a branch for the "GetAllCustomers" operation and a "Default" branch that is chosen in case of any other operation.
Figure 7: Message Flow after adding branches for all of the Proxy Service's operations
We continue by defining the routing logic for each operation using Route Nodes and Routing activities. The transformation logic will be added afterwards. We'll leave the "Default" branch as is.
A Route Node performs request/response communication with another service. It represents the boundary between request and response processing for the Proxy Service. When the Route Node dispatches a request message, the request processing is considered complete. When the Route Node receives a response message, the response processing begins. The Route Node supports conditional routing as well as request and response transformations. Because a Route Node represents the boundary between request and response processing, it cannot have any descendants in the Message Flow.
Add a Route Node to all three operational branches by right-clicking a branch and selecting Insert Into ? Route. Add a Routing Node to all newly created Route Nodes by right-clicking the Route Node and selecting Insert Into → Communication → Routing .
Select the endpoint to be invoked in every Routing activity by clicking the Routing node and specifying the "Service" in the "Properties" tab. Browse to the "KlantWebServiceBS" Business Service and click "OK". A dropdown list displaying all operations of the Business Service will appear. Select the corresponding operation and save the Proxy Service.
Note that you can enter more meaningful names for the added nodes if you want.
Figure 8: Selecting the Business Service and operation to invoke
After adding all routing activities the Message Flow looks like the following:
Figure 9: The final result of the Message Flow in which all operations are mapped
You have now defined the entire routing logic for the OSB project. We'll continue adding the required transformation logic using XQuery and OSB activities such as Assign and Replace. We need to transform the input of every Proxy Service operation to the input of the corresponding Business Service operation and vice versa for the output.
Figure 10: XPath expression extracting the customer id
Oracle Workshop might warn the expression is invalid since the "cus" namespace prefix that is used in the expression cannot be resolved. If this is the case you need to declare the namespace prefix. Select the "Namespaces" tab and add a user namespace with "cus" as prefix and "http://www.waai.nl/CustomerService" as URI. Save and refresh the project.
We have now extracted the customer id from the incoming payload of the "GetCustomerById" operation and assigned it to the "customerId" variable. Next we need to construct the appropriate request payload for the "getKlantById" operation.
Figure 11: Inspecting the deployed KlantWebServiceEAR project in Oracle Weblogic Management Console
Expand the deployment and select Web Services ? KlantWebService. Select the "Testing" tab and use the WebLogic Test Client to view the payload of the operation. Execute the operation to view the response payload. Note that the KlantWebService is a dummy WebService and always returns the same customer details.
Figure 12: Testing the KlantWebService operations using the Test Client
Next step is to construct the request payload.
<getKlantById
xmlns="http://www.waai.nl/klant/service"
xmlns:klant="http://www.waai.nl/klant">
<klant:klantId>{$customerId}</klant:klantId>
</getKlantById>
Finally you need to declare the "klant" namespace prefix which is also used later on in this tutorial. Select the "Namespaces" tab and add a user namespace with "klant" as prefix and "http://www.waai.nl/klant/service" as URI.
Figure 13: Adding the "klant" namespace to the default list of namespaces
You have now replaced the entire node contents (indicated by ".") of the request body (indicated by "body") with the "getKlantById" request payload using the value of the "customerId" variable. This completes the Request Action flow!
We continue by completing the Response Action flow of the "GetCustomerById" operation using an XQuery transformation.
Figure 14: Creating a new XQuery transformation
Figure 15: Selecting the Source Type of the XQuery transformation
Figure 16: Selecting the Target Type of the XQuery transformation
Click "Finish". This will open a new window in which the mapping can be graphically defined.
You might notice that the mappings for "firstName" and "lastName" are trivial since both source and target elements are of the same type: "xsd:string". The "age" and "customerId" elements however have different source and target types: "xsd:long", "xsd:int", and "xsd:nonNegativeInteger".
Select the "Source" tab to view the XQuery transformation. Add the following expression between the "<ns1:Customer>" and "<ns1:firstName>" elements: <ns1:customerId>{ xs:nonNegativeInteger(data($getKlantByIdResponse1/return/klantId)) }</ns1:customerId> Add the following expression between the "<ns1:lastName>" and "</ns1:Customer>" elements:{ xs:nonNegativeInteger(data($getKlantByIdResponse1/return/leeftijd)) }
You have now applied a type conversion. Inspect the XQuery code in the "Source" tab. This should resemble the corresponding XQuery file in the projects archive containing the finished tutorials.
Switch back to the "Design" tab. All elements are now mapped. You can use the "Test" tab to test the XQuery transformation.
Figure 17: Final result of the XQuery mapping
Next step is to use the XQuery transformation to create the response content with it.
20. Right-click the Response Action flow and select Insert Into ? Message Processing ? Assign to add an Assign activity. Click "Expression", select the "XQuery Resources" tab, and browse to the newly created XQuery file. Enter "$body/klant:getKlantByIdResponse" as "Binding" which specifies the response of the Business Service that will be transformed. Click "OK". Back in the "Properties" window enter "transformedResponse" as "Variable Name".
The outcome of the transformation is now assigned to the "transformedResponse" variable. The final step is to assign this value to the response payload.
Figure 18: Assigning the result of the XQuery transformation to the "transformedResponse" variable
Right-click the newly added Assign activity and select Insert After → Message Processing → Replace . Click "XPath" in the new Replace activity and enter "." as "Expression". Back in the "Properties" tab, enter "body" as "In Variable", and select the "Replace node contents" option. Click "Expression" to open the XQuery/XSLT Expression Editor and enter "$transformedResponse" in the "Expression" tab.
Figure 19: Replacing the body with the contents of the "transformedResponse" variable
The complete routing and transformation flow for the "GetCustomerById" branch is finished! Complete the other two branches using the same approach.
When all activities are added the Message Flow looks like the following:
Figure 20: Final result of the Message Flow
You have now completed the OSB project. It's time to take the project for a spin by deploying and testing it!
Go to the server tab, right-click on the server connection, and select "Add and Remove Projects...". Add the "OSB Configuration" project and click "Finish" to deploy the OSB project. We will use Oracle Service Bus Console to test our project.
Oracle Service Bus Console enables you to control the service and policy configurations, and monitor system and operations tasks. Oracle Service Bus built-in test console is a browser-based test environment used to validate resources and inline XQuery expressions used in the Message Flow. It is an extension of the Oracle Service Bus Console. Using the test console, it is possible to configure the test object (Proxy Service, Business Service, XQuery, XSLT, MFL resource), execute the test, and view test results. It allows message flow tracing when testing a service, to examine the state of the message at specific trace points.
Log into Oracle Service Bus Console to view and test the OSB project. Click "Project Explorer", select the "WAAI_Case1_Customer_Service" project, and browse to the Customer Proxy Service you want to test. Click the "Launch Test Console" icon in the Actions dialog and test all operations of the Proxy Service.
Figure 21: Testing the Customer Proxy Service using Oracle Service Bus Console
The Testing Console shows the correct output of the Customer Proxy Service's operations. You can view the outcome of all individual steps in the "Invocation Trace" window.
You have completed the first tutorial in which you have developed an OSB project in Oracle Workshop that reuses a local Dutch service and exposes it using the English canonical data model. You should now have an understanding of OSB basic building blocks such as Business and Proxy Services, routing rules and transformation capabilities based on XQuery.