You are on page 1of 96

Oracle Service Bus Tutorial

Version 1.2
July 2014

Sivakumar Gonugunta

Contents
Overview of Tutorial ..............................................................................................................4
Scenario in Tutorial ................................................................................................................4
Business Requirements ......................................................................................................4
Installation ............................................................................................................................7
Verifying the Installation ....................................................................................................7
Getting Started .................................................................................................................... 10
Adding Weblogic Server in IDE .......................................................................................... 10
Creating OSB Configuration Project ................................................................................... 13
Creating OSB Projects ....................................................................................................... 14
Creating Business Services ................................................................................................ 15
Deploying and Testing ...................................................................................................... 19
Creating Proxy Service ...................................................................................................... 23
Creating Message Flow ..................................................................................................... 26
Create Customer Operation .......................................................................................... 29
Validating Payload .................................................................................................... 29
Validating Address .................................................................................................... 33
Defaulting................................................................................................................. 42
Getting User ID ......................................................................................................... 43
Routing..................................................................................................................... 46
Testing...................................................................................................................... 54
Update Customer Operation ......................................................................................... 59
Validating Payload .................................................................................................... 59
Routing..................................................................................................................... 60

Testing...................................................................................................................... 65
Delete Customer Operation .......................................................................................... 69
Validating Payload .................................................................................................... 69
Routing..................................................................................................................... 69
Testing...................................................................................................................... 70
Merge Customer Operation .......................................................................................... 73
Validating Payload .................................................................................................... 73
Verifying Customer Existence .................................................................................... 74
Creating Proxy with Local Transport .......................................................................... 77
Routing..................................................................................................................... 78
Testing...................................................................................................................... 79
Proxy Service Error Handling............................................................................................. 82
CustomerCommonPS .................................................................................................... 83
Testing...................................................................................................................... 86
CustomerPS .................................................................................................................. 90
Securing Proxy Service...................................................................................................... 91
Creating User................................................................................................................ 91
Attaching OWSM Policy ................................................................................................ 92
Testing ......................................................................................................................... 95

Overview of Tutorial
The purpose of this tutorial is to gain hands-on experience with Oracle Service Bus 11g
development using Eclipse IDE. The tutorial can be used as an addition exercise to the examples
available in OTN or can be practiced in standalone manner.
The tutorial assumes a little conceptual understanding of OSB such as Proxy Service, Business
Service and Message Flows. If you don't have this initial understanding, it is recommended to go
through section Oracle Service Bus Concepts at least, in the link mentioned above. By the time
you finish this tutorial, you will learn:
Creating OSB Configuration project, OSB projects, Proxy Service and Business services.
Sharing the OSB resources across OSB projects to enable reuse and modularity.
Working with resources such as WSDL, XSD, XSLT, XQuery, Service Account etc.
Configuring message flow in Proxy Services using Pipeline Pair, Stage, Routing and
Operational Branch nodes.
Enriching messages using intermediate service calls in message flows.
Using local transport in proxy services.
Routing messages to business services using Service Callout and Routing.
Using Service Error Handlers in Proxy Service.
Deploying and Testing Proxy and Business services.

Scenario in Tutorial
XYZ Bank is a Financial Services organization operates in several countries having numerous
branches. Very recently, the bank is recording disappointing results for the last few quarters
and constantly losing customers satisfaction. The top brass management identified issues with
current IT infrastructure lacking agility which is unable to meet growing business and customer
needs. The recent acquisitions also had its share of new IT systems getting added to existing
system landscape.
Because of this, the management has decided to go with revamp of existing IT infrastructure. As
part of this, an integration strategy is being chalked out using SOA as the underlying architecture
to improve agility and bring in more reusability as customers uses different channels to avail
bank services. Added to this, a new portal is also been planned to improve user experience.
In the proposed architecture, an Enterprise Service Bus plays pivotal role providing virtualization
layer to consumers and also takes care of Validation, Transformation and routing all incoming
requests to the actual services provided by end (legacy) systems. And Oracle Service Bus (OSB)
has been chosen meeting the requirements.

Business Requirements
For milestone 1, IT team wants to expose data services on different objects Customer, Accounts
etc. These services will be exposed to consumers using OSB that provides features like Service
Virtualization, Authentication, Validation, Transformation, Message Enrichment and Routing. In
this tutorial, we will develop such data services for Customer data object and the requirements
are listed below.

Create a OSB Proxy Service exposing single interface to perform the following:
CreateCustomer - Creates a new customer.
UpdateCustomer - Updates an existing customer.
DeleteCustomer - Deletes an existing customer.
MergeCustomer - Updates an existing customer if exists or create a new customer.

Common Requirements
1.
2.
3.
4.
5.
6.

Single interface (WSDL) to be exposed for all above operations.


Transform the input request to the structure expected by the actual end system.
Route the input request to appropriate business service by selecting suitable operation.
In positive case, return the output containing Customer ID and Status.
In all negative cases, return the fault containing Error Code (in any) and Error Message.
Secure the proxy service using OWSM policy so that only valid users can invoke.

CreateCustomer

The input structure should include the attributes First Name, Last Name, Email, Phone,
Date of Birth, Customer Type and Address fields. Restrict the Customer Type values to
'Individual' and 'Corporate'.
Validate the input against XSD definition and return fault on validation failure.
Validate Email element for proper format and return fault on validation failure.
Default CustomerType element to 'Individual', if it's not sent in the input.
Validate Address elements by calling the Address Validation service and return fault if
address is not valid. Address validation should be performed based on a configurable
property.
The actual legacy system expects CustomerID element to be populated in the input. Call
Create User ID service to get unique id and populate it as CustomerID.
Create User ID service expects the consumers to send credentials in SOAP header in the
following format. Use Service Accounts to store these credentials.
<usr:UserIDConfiguration
xmlns:usr=http://xmlns.xyzbank.com/User/Configuration>
<usr:UserName>admin</usr:UserName>
<usr:Password>password1</usr:Password>
</usr:UserIDConfiguration>
Complete the common requirements 3-5 mentioned above.

UpdateCustomer
The input structure should be same as CreateCustomer operation.
Validate the input against XSD definition and return fault on validation failure.
Complete the common requirements 3-5 mentioned above. Since the actual end system
updates the fields for which values are sent, the elements with null values have to be
removed from input before routing the request.

DeleteCustomer

The input structure should have CustomerID as mandatory attribute.


Validate the input against XSD definition and return fault on validation failure.

Complete the common requirements 3-5 mentioned above.

MergeCustomer

The input structure should be same as CreateCustomer operation.


Call to FindCustomer service to find existence of Customer using CustomerID. The
service response element CustomerExists value Y denotes existing customer and
value N denotes non-existing customer .
For existing Customer, route request to perform Update.
In case no Customer exists, route request to perform Create. Make sure that all of the
above requirements mentioned for 'CreateCustomer' are considered.
Complete common requirements 3-5 mentioned above.

Error Handling

Convert System or Application errors to the SOAP Fault structure defined in WSDL.

Following are WSDLs to be used for Business Services creation:


Purpose
Unique ID Creation
Address Validation
Customer Object operations

Service WSDL
CreateUserIDService.wsdl
AddrValidationService.wsdl
CustomerService.wsdl

You can create SOAP UI mock services using above WSDLs or you can come up with your own
implementation using above WSDLs. This tutorial uses these mock services to demonstrate the
runtime behavior of Business and Proxy Services. Refer to SOAP UI documentation for more
information on Mock Services. The mock service used for this tutorial can be downloaded from
here. Modify payload for different operations as and when required for positive and negative
test cases described later in this tutorial.
You can download the Configuration jar of this tutorial from here.

Installation
This tutorial uses Oracle Service Bus 11.1.1.7.0 but also compatible with older versions of OSB so
you can try with your existing installation of OSB 11g as well. For detailed installation steps, you
can refer to Quick Start Guide available here. Though this guide talks about the earlier version of
OSB, the installation steps are pretty much same for 11.1.1.7.0 version as well.

Verifying the Installation


Open Eclipse IDE from OSB installation.

Go to File -> New -> Project and verify that Oracle Service Bus wizard is available.

Create a SOA domain using steps given in Quick Start guide. Navigate to DOMAIN_HOME and
start Weblogic server using startWebLogic.cmd.
Note: Going forward we will use the terms DOMAIN_HOME, WLS_HOME, and MW_HOME to
refer to domain directory, WLS installation directory and OSB installation directory respectively.

Verify OSB console using URL http://localhost:<port>/sbconsole and login with the credentials
given during domain creation.

Also verify Admin console using URL http://localhost:<port>/console and login with credentials
given during domain creation.

Note: If you are installing OSB/SOA in 64-bit machine then 64-bit JDK, Weblogic server and
OEPE have to be installed separately as Weblogic server installer does not include JDK and OEPE.
You can refer to this link for installation steps on 64-bit Windows machines. Also make sure you
install correct OEPE version as depicted below which can be downloaded from here.
OSB Release
11.1.1.6.0
11.1.1.7.0
11.1.1.5.0
11.1.1.4.0
11.1.1.3.0

Weblogic Server
10.3.6

OEPE Version
11.1.1.8.0

10.3.5
10.3.4
10.3.3

11.1.1.7.2
11.1.1.6.1
11.1.1.5

Getting Started
Adding Weblogic Server in IDE
Go to Servers window and right click to add new server. Adding server in IDE makes your
deployment and testing easier without navigating to sbconsole. If Servers window is not visible,
you can make it visible by navigating to Window -> Show View -> Servers.

Choose appropriate Weblogic version based on your OSB installation and proceed to Next. Enter
the hostname if you want to connect to remote server or retain localhost.

Verify your WLS_HOME and JAVA_HOME paths displayed and proceed to Next.

Give DOMAIN_HOME in Configuration section and click Finish. Observe that domain selection is
enabled only when Server type is selected as Local.

Make sure that server status is showing as Started. Otherwise, verify the paths given in Server
Setup wizard are valid for WLS_HOME, DOMAIN_HOME and JAVA_HOME. In case you are using
remote server, you also have to verify that server is accessible from your local machine (HTTP
Proxy or other firewall rules etc..).

Creating OSB Configuration Project


During OSB development, you will make use of several resources like Proxy Service, Business
Service, WSDL, XSD, XQuery, XSLT etc. Also there are global resources like SMTP Server, JNDI
Provider. OSB Project acts as container for all the resources you use and OSB Configuration
Project is a high-level container for all OSB Projects and Global resources.
Typically OSB development activity starts with creation of new OSB Configuration Project. So to
create one for your purpose, navigate to New -> Oracle Service Bus Configuration Project. Give
name as OSBConfiguration.

Click Finish and verify that your Project Explorer shows new Configuration Project and resource
summary as shown below.

Creating OSB Projects


Once you create the Configuration Project, you can proceed with creation of other OSB projects
based on your requirements. In OSB, using a common OSB project is best way to share resources
across different projects within Configuration Project.
So create a new OSB project by selecting New -> Oracle Service Bus Project on right click of
OSBConfiguration project and give name as XYZCommon.

Copy all WSDLs mentioned above into this XYZCommon project. You can do this by copying
WSDLs from file system and select Paste option on right click of OSB project. In similar manner,
create another OSB project XYZCustomer which will be used later in tutorial. Now your Project
Explorer should look like below.

Creating Business Services


In OSB, Business Service provides a level of abstraction and takes care of communication with
the actual Service Providers. So you have to create 3 business services using given WSDLs. Right
click on XYZCommon project and select New -> Business Service.

Give name as CustomerServiceBS and click Finish.

A new tab CustomerServiceBS.biz gets displayed where you can configure the Business service.
Select Service Type as 'WSDL Web Service'. Click Browse to choose CustomerService.wsdl and
select binding as shown below. Click Yes if you get any warnings as selecting WSDL will always
override existing Business service configuration.

Note: While creating WSDL based business service, you can select binding or port (if available)
with a little difference. When you select port, endpoint URL given in WSDL will be defaulted in
Transport tab and the same is not defaulted when you select binding.
Now General tab of your Business service should look like below.

Click Transport tab, enter Endpoint URI of actual service (can be either SOAP UI mock service or
you own implementation) and click Add.

Note: '*' on tab denotes that the resource in the current context is not saved yet.
Retain default values for all parameters in all other tabs (HTTP Transport, Binding, Message
Handling and Policy) of Business service and Save.
In similar manner, create Business services AddrValidationServiceBS and UserIDServiceBS in
using AddrValidationService.wsdl and CreateUserIDService.wsdl respectively. Now your Project
Explorer should look like below.

Deploying and Testing


It's always recommended to test business services to make sure that you are able to call service
provider and their service is functioning as expected. Typically, if service provider is external to
your organization, then Business service has to be configured to use HTTP proxy.
Note: HTTP Proxy Server is a global resource in OSB (to be created in OSB Configuration project)
and can be attached to business service in Advanced Settings of HTTP Transport tab.
To test/run the business/proxy service, right click business/proxy service and select Run as ->
Run on Server. Before running business/proxy service, make sure that OSB server is Started.

Click Next and verify that OSBConfiguration project is added to 'Configured' list and do Finish.
Otherwise use Add to shuttle configuration project.

Verify that Test console is opening as shown below. The Test console will show you all available
operations (based on WSDL), Request section (to enter payload), Transport section (to enter
transport headers) and Attachments section.

Enter CUST as value and click Execute. After execution, the Test console shows both request and
response documents as shown below. You can use Back button to go back to request screen and
Close button to close.

In similar manner, you can run and test other business services as well. You can also verify that
your projects are deployed in sbconsole as shown below.

Alternatively, you can also export OSB projects as Configuration jar and import into sbconsole.
Note: Developer can choose any of these two options to test business/proxy services.
To export OSB projects, right click configuration project and select Export -> Oracle Service Bus Configuration Jar.

Select all projects to be deployed. Browse the location to store Configuration jar and click Finish.

Creating Proxy Service


In this section, you will learn about creating and configuring Proxy Services and you will use
XYZCustomer project for this purpose.
At first, create different folders XQueries, XSLTs, WSDLs and ProxyServices in XYZCustomer
project as shown below.

As per Business Requirements, your proxy service should expose operations like Create, Update,
Delete and Merge. So you need to create a WSDL for this purpose and is available here. You can
either use this WSDL or create on your own that suits the requirements.

Right click ProxyServices folder and select New -> Proxy Service.

Give name as CustomerPS.

Click Finish to bring up a new tab CustomerPS.proxy where you can configure your Proxy
service. Select Service Type as 'WSDL Web Service'. Browse to choose CustomerPS.wsdl and
select binding as shown below. Click Yes if you get any warnings as modifying/selecting a WSDL
will always override your existing Proxy Service configuration.

Go to Transport tab and give Endpoint URI as /entity/CustomerService. So service consumers


can access your proxy service using URL http://<host>:<port>/entity/CustomerService.

Go to Operation tab and select SOAPAction Header as Selection Algorithm. This would enable
your Proxy service to consider SOAP Action in the received request to determine operation.

Creating Message Flow


In this section, you will learn creating message flow for your Proxy Service.
When consumers call your Proxy service, you need to perform some actions based on operation.
OSB provides Operational Branch catering to this requirement.
Go to Message Flow tab of Proxy service, drag Operational Branch node from Nodes section.
Note: All Nodes or Activities used in message flow are available in the Design Palette under
different sections. If you are not able to view Design Palette, make it visible by selecting Window
-> Show View -> Design Palette.

Now your Message flow should look like below.

Click Operational Branch node in the message flow and set label as CustomerOperation in
Properties tab. As a best practice, you should always give meaningful labels for nodes and other
activities (wherever applicable). Select the first branch and choose CreateCustomer operation in
Properties tab as shown below.

Click icon
to add three more branches and select UpdateCustomer, DeleteCustomer and
MergeCustomer operations respectively.

Create Customer Operation


In this section, you will complete CreateCustomer message flow. Drag Pipeline Pair node from
Nodes into CreateCustomer branch and set name as CreatePipeline in Properties tab.

Validating Payload
In this section, you will learn do payload validation against XSD and Email element validation.
Drag Stage node into Request Pipeline and set name as Validation in Properties tab.

Drag Validate activity into Validation stage from Stage Actions->Message Processing.

In Properties tab, set In Variable property value as body and bring up Expression Editor for
XPath property. Drag Customer element into Expression field as shown below.

For Against Resource property, select Customer element from Proxy service WSDL as shown
below.

Set 'Raise Error' option in Properties tab, so that validate activity throws an exception if the
payload validation fails. Now your properties tab for Validate activity should look like below.

To validate Email input element, drag If-Then activity into Validation stage from Stage Actions>Flow Control. In properties tab, bring up expression editor for Condition property and give
Expression as:
not(fn:matches($body/cus:Customer/Email/text(), '[a-zA-Z0-9]+@[a-zA-Z]+\.[a-z A-Z]{2,3}'))
Alternatively, you can drag fn:matches XQuery function as shown below and Email element
from Variable Structures -> body -> $body - Create Customer (request) -> Email (as shown
earlier) and modify expression to above condition.

Drag Raise Error activity into If branch from Stage Actions->Flow Control, and set properties as
shown below. You can remove Else branch by selecting Delete on right click as its not required
here.

Validating Address
In this section, you will perform Address Validation by calling AddrValidationServiceBS based
on a configurable property. You will use XQuery resource to store these configurable properties.
Drag Stage node into Request Pipeline and give name as AddrValidation in Properties tab. Right
click on XQueries folder in XYZCustomer project and select New -> XQuery Transformation.

Give Config as file name.

Click Next and select anyType element to shuttle it to right side using Add.

Click Next and again select anyType element as target and shuttle it to right side using Add.

Click Finish to bring up XQuery Transformation Editor. Remove all the file contents and paste
following XML snippet.
<ProxyServices>
<Proxy name="CustomerPS">
<Parameters name="ValidateAddress">Y</Parameters>
</Proxy>
</ProxyServices>

Now source for your XQuery transformation file should look like below.

Drag Assign activity into AddrValidation stage from Stage Actions->Message Processing. In
Properties tab, bring up Expression Editor for Expression property and navigate to XQuery
Resources tab. Click Browse and select Config.xq.

Click OK. Set Variable property value as ConfigVar.

Drag another Assign activity and set the values fn:tokenize($inbound/@name,'\$')[last()] and
proxyname for Expression and Variable properties respectively in Properties tab. The
expression $inbound/@name gives Proxy Service name having complete path starting from
Configuration Project with $ as delimiter. This is the reason for tokenizing and picking up last
token as Proxy Service name.

Address Validation business service should be called only when this configuration property value
is Y. So drag If Then activity from Stage Actions->Flow Control and set expression as below.
$ConfigVar/Proxy[@name=$proxyname]/Parameters[@name="ValidateAddress"]/text()='Y'
OSB provides Service Callout, Routing and Publish activities to route incoming requests to
appropriate Business services. Routing and Service Callout are used for Synchronous where as
Publish activity is used for One-way communication.
In OSB, Routing node depicts the end of message flow so you can't place any other activities
after Routing node. Hence Service Callout has to be used for all intermediate service calls in
your message flow. Drag Service Callout from Stage Actions->Communication into If Then
branch as shown below.

In Properties tab, browse and select AddrValidationServiceBS for Service property and select
validate_address operation. Set other properties of Service Callout as shown below.

Here, you should populate addrReqBody variable with payload for valdiate_address operation
and addrRespBody variable stores response payload returned by Business service. Since you are
using 'Configure Soap Body' option, request variable has to be populated with complete
payload including SOAP Body element (soap-env:Body). In same way, response variable will
always have SOAP Body element when returned by Business service.
Now create XQuery Transformation to transform address fields in Proxy Service input to input
structure required by Business service. Give file name as AddrToAddrBSInput.

Click Next and select Customer element as shown below and shuttle it to right using Add.

Click Next and select addrval_input element as shown below and shuttle it to right using Add.

Click Finish to bring up transformation editor and finish mapping as shown below. You can map
the fields by connecting Source element to Target element.

Address Validation service expects address lines with ',' as delimiter, so go to Source tab and
modify it to use concat function as shown below.

Go to Test tab and test your XQuery Transformation to see whether it's working as expected.

Drag Assign activity into Service Callout from Stage Actions -> Message Processing.

In Properties tab, bring up Expression Editor for Expression property and navigate to XQuery
Resources tab. Browse and select above XQuery Resource as shown below.

Click OK and give $body/Customer as bind variable value.

Click OK and set addrReqBody as value for Variable property.

Now use another Assign activity to enclose payload with soap-env:Body element.

Once response is received from Business service, you have to raise error or proceed further in
message flow depending on the status. So drag If-Then activity into AddrValidation stage after
Service Callout from Stage Actions->Flow Control and give condition as shown below.

The red mark denotes that namespace alias addr is not recognized by OSB. So you need to
register this namespace. Go to Namespace Definition tab on right and click Add. Enter prefix as
addr and URI as urn:xyzbank:cust:schema:address which is the namespace used by address
validation service for response schema.

Click OK and observe that red mark is no longer visible. Return to Proxy service and drag Raise
Error activity into If branch from Stage Actions -> Flow Control and set properties as below.

Defaulting
In this section, you will default CustomerType element provided it's not received in request.
Create another Stage after AddrValidation stage and set name as Defaulting in Properties tab.
Drag If-Then activity into this stage from Stage Actions -> Flow Control and give the condition as
shown below. Alternatively, you can select fn:empty function by navigating to XQuery Functions
-> Sequences -> General Functions from right side of expression editor.

Drag Insert activity into If branch from Stage Actions -> Message Processing and set properties
as shown below.

Getting User ID
In this section, you will call CreateUserID service to generate Unique ID to use it as CustomerID.
This service expects credential information in SOAP header. Instead of hard-coding these values
OSB provides a feature called Service Account to store credentials. Now create a new folder and
name it as Utilities in XYZCustomer project. Right click and select New->Service Account and
name it as UserIDSvcCred.

Select Resource Type as Static and give username and password in configuration section.

Drag Service Callout into Defaulting stage from Stage Actions -> Communication after If-Then
activity. In Properties tab, browse and select the business service UserIDServiceBS and
operation create_uniqueid.
Set other properties as shown below including Request Header property as you have to send
credential information in SOAP Header. Choosing option 'Configure Payload Document' allows

you to send request and receive response payload without soap-env:Body tag and OSB will add
SOAP Body element at runtime while calling the business service.

The XQuery function fn-bea:lookupBasicCredentials() can be used to get the credentials stored
in Service Account. This function returns the following XML fragment.
<con:UsernamePasswordCredential xmlns:con="http://www.bea.com/wli/sb/services/security/config">
<con:username>Username value given in service account</con:username>
<con:password>Password value given in service account</con:password>
</con:UsernamePasswordCredential>

Drag Assign activity into Request Action of Service Callout from Stage Actions->Message
Processing and set properties as shown below. Alternatively, you can select this XQuery function
by navigating to XQuery Functions -> Service Bus Functions from right side of expression editor.

Drag another Assign activity and set properties as below to populate SOAP header. Note the
inclusion of <soap-env:Header> which has to be included irrespective of Configure option.
Expression:
<soap-env:Header>
<usr:UserIDConfiguration xmlns:usr="urn:xyzbank:cust:schema:userid">
<usr:UserName>{$varSA/con:username/text()}</usr:UserName>
<usr:Password>{$varSA/con:password/text()}</usr:Password>
</usr:UserIDConfiguration>
</soap-env:Header>

Variable:
userIDReqHdr

Drag another Assign activity and set properties as shown below to populate payload.
Expression:
<usr:user_input xmlns:usr="urn:xyzbank:cust:schema:userid">
<usr:system>LEGACY</usr:system>
</usr:user_input>

Variable:
userIDReq

Drag If-Then activity after Service Callout from Stage Actions->Flow Control and set expression
as shown below to verify status of UserID Creation.

Drag RaiseError activity into If branch from Stage Actions->Flow Control. Set properties as
shown below in Properties tab.

Routing
In this section, you will route request to business service CustomerServiceBS and finish the
message flow for Create Customer operation. Proxy Service sends fault response if the customer
creation fails or returns CustomerID in case of successful creation.
Drag Route Node after CreatePipeline from Nodes and name it as CreateCustomerRoute.

Drag Routing activity into Route node from Route Actions->Communication. Browse to select
CustomerServiceBS business service and create_customer operation for Service and Invoking
properties respectively.

Create new XQuery Transformation and name it as CustomerPSToCreateCustomer.

Click Finish and do mappings as shown below.

Go to Source tab and do modifications as highlighted below.

Drag Replace activity into Request Action of Routing from Stage Actions->Message Processing.
In Properties tab, bring up expression editor to choose the above transformation and give bind
variable value as $body/*.

Set other properties as shown below. This action will replace contents of $body context variable
with payload structure as expected by business service.

Drag another Replace activity into Request Action of Routing to replace contents of Customer ID
with Unique ID that we got from UserIDServiceBS. In Properties tab, bring up expression editor
and give bind variable value as $userIDResp/unique_user_id/text() and set other properties as
shown below.

Drag If-Then activity into Response Action of Routing activity from Stage Actions->Flow Control
to verify the status returned by business service and set the condition as shown below. Don't
forget to add namespace alias cust with namespace urn:xyzbank:cust:schema:customer in
Namespace Definitions tab as shown earlier.

Drag Assign activity into If branch from Stage Actions->Message Processing and set properties
as shown below to store unsuccessful response in faultVar variable. Drag RaiseError activity
from Stage Actions->Flow Control and give error code as XYZ-0004. The actual Fault Response
will be sent from Proxy Service Error Handler that will be discussed later in this tutorial.

Create new XQuery Transformation and name it as CustStatusMsgToCustomerPSOutput, to


transform response of business service to response structure of the Proxy Service in case of
successful customer creation.

Click on Finish and do mapping as shown below.

Drag Replace activity into Response Action of Routing activity from Stage Actions->Message
Processing. In Properties tab, choose the above XQuery transformation and give $body/* as
bind variable value.

Set other properties as shown below. This action will replace contents of $body variable which
will be ultimately send to consumer of the proxy service.

Testing
Deploy both projects or run proxy service directly as shown in section Deploying and Testing.
You may want to frequently test proxy service during your development. Run your proxy service
with sample payloads given in this file and observe Flow Trace and Variables as shown in
following screenshots.
CustomerType Input Element Validation:

Email Input Element Validation:

Positive Case, Validate Address Configuration Variable value Y:

Positive Case, Validate Address Configuration Variable value N:

Negative Case (Status is E in business service response):

Update Customer Operation


In this section, you will complete message flow for UpdateCustomer operation. Since we have
discussed about each and every step extensively in previous section, we will go with very brief
explanation from here onwards.

Validating Payload
Drag Pipeline Pair node into UpdateCustomer operational branch from Nodes and name it as
UpdatePipeline. Finish Validation stage for validating the Payload Structure and Email element
similar to what you did for the CreateCustomer operation.
In this case, Email validation should be done only when it's sent in request payload. Complete
this step using 2 If-Then conditions as shown below. Give following expression in top-level IfThen condition.
not(fn:empty($body/cus:Customer/Email)) and
fn:string-length(fn-bea:trim($body/cus:Customer/Email/text()))>0
Give the following expression in inner If-Then condition:
not(fn:matches($body/cus:Customer/Email/text(),
'[a-zA-Z0-9]+@[a-zA-Z]+\.[a-zA-Z]{2,3}'))

CustomerID is a mandatory input element as this is Update operation and message flow should
enforce the same. So drag If-Then activity into Validation stage from Stage Actions->Flow
Control and set expression as shown below.

Drag Raise Error activity into If branch from Stage Actions->Flow Control and set properties as
shown below.

You can also do Address Validation similar to CreateCustomer operation, as user can always
update the address. But we are not going to discuss again in this section.

Routing
In this section, you will route request to CustomerServiceBS to finish the message flow for
UpdateCustomer operation. Again Proxy Service sends fault response if customers update fails
or returns CustomerID in case of successful update.
Drag Route Node after UpdatePipeline from Nodes and name it as UpdateCustomerRoute.
Drag Routing activity from into Route node from Route Actions->Routing. In Properties tab,
browse to select CustomerServiceBS and update_customer operation for Invoking property.

In this section, you will use XSLT for transforming input instead of XQuery. Right click on XSLTs
folder in project explorer and select New -> XSLT File. Give name as shown below.

Click Finish to bring up XSLT editor and you can observe that no design time support is available
for creating XSLT transformation similar to XQuery. You can use JDeveloper to create required
XSLT mapping or can write XSLT source if you are well versed. This section shows you how to
make use of JDeveloper design time capability to create XSLT transformation.
Create a JDeveloper project and copy CustomerPS.wsdl and CustomerService.wsdl. Create new
XSLT transformation by selecting File->New->XSL Map and finish as shown below.

Click OK to bring up XSLT Transformation editor.

Do mapping as shown below and use concat XSLT function to concatenate elements FirstName,
Lastame and State, Country and ZipCode.

Since we are doing the update, you should not send null values to business service, so target
elements have to be mapped only if corresponding source element is available. So go to Source
tab and modify XSLT by adding if conditions for each source element as shown below.

Now copy xsl contents from JDeveloper to XSLT CustomerPSToUpdateCustomer.xsl in Eclipse.


Drag Replace activity into Request Action of Routing from Stage Actions->Message Processing.
In Properties tab, bring up expression editor to choose above transformation in XSLT Resources
and give bind variable value as $body/*.

Set other properties as shown below. This action will replace contents of $body context variable
with payload structure as expected by business service.

Finish response action in Routing similar to the routing done for CreateCustomer operation as
output structure of business service is same. You should reuse existing XQuery transformation
CustStatusMsgToCustomerPSOutput for transforming business service output to proxy service
output.

Testing
Deploy both projects or run proxy service directly as shown in section Deploying and Testing.
You may want to frequently test proxy service during your development. Run your proxy service
with sample payloads given in this file and observe Flow Trace and Variables as shown in
following screenshots.
CustomerType Input Element Validation:

Email Input Element Validation:

CustomerID Input Element Validation:

Positive Case, Passing FirstName, LastName, Phone, DOB and Email update:

Positive Case, Passing Address fields update:

Negative Case (Status is E in business service response):

Delete Customer Operation


In this section, you will complete message flow for DeleteCustomer operation.

Validating Payload
Drag Pipeline Pair node into DeleteCustomer operational branch and from Nodes and name it
as DeletePipeline. Finish Validation stage for validating the Payload Structure similar to what
you did for other operations. Also finish CustomerID mandatory attribute validation similar to
UpdateCustomer operation.

Routing
In this section, you will route request to business service CustomerServiceBS to finish message
flow for DeleteCustomer operation. Again Proxy Service sends fault response if customer delete
fails or returns CustomerID in case of successful deletion.
Drag Route Node after DeletePipeline from Nodes and name it as DeleteCustomerRoute. Drag
Routing activity into this node from Route Actions->Routing. In Properties tab, browse to select
CustomerServiceBS and delete_customer operation for Invoking property. Finish request and
response actions similar to previous operations. Response action is similar to previous
operations and the XQuery transformation CustStatusMsgToCustomerPSOutput can be reused.
But for the request action you should create new XQuery transformation.

Testing
Deploy both projects or run proxy service directly as shown in section Deploying and Testing.
You may want to frequently test proxy service during your development. Run your proxy service
with sample payloads given in this file and observe Flow Trace and Variables as shown in
following screenshots.
No CustomerID element in Input:

No value for CustomerID Input element:

Positive Case:

Negative Case (Status is E in business service response):

Merge Customer Operation


In this section, you will complete message flow for MergeCustomer operation. As per business
requirements, merge operation should create customer if it does not exist in system otherwise
update existing customer. So you should reuse the existing message flow created for Create and
Update customer operations. This can be achieved by creating a local proxy. The message flow
should perform following:
Verify that CustomerID is mandatorily present in input payload.
Call find_customer operation of business service to find whether customer exists or not.
This operation returns Y for existing customer and N otherwise.
Create new proxy service CustomerCommonPS with local transport using same wsdl as
CustomerPS.
Move CreateCustomer and UpdateCustomer message flows to this new proxy service.
Modify CreateCustomer and UpdateCustomer pipelines to call respective operations of
this new proxy service.
Modify MergeCustomer pipeline to call CreateCustomer or UpdateCustomer operation
of new proxy based on whether customer is an existing customer or not.

Validating Payload
Drag Pipeline Pair node into MergeCustomer operational branch from Nodes and name it as
MergePipeline. Finish Validation stage for validating Payload Structure similar to what you did
for other operations. Also finish CustomerID mandatory validation similar to UpdateCustomer
operation.

Verifying Customer Existence


Drag another stage node into Request Pipeline of MergePipeline from Nodes, after Validation
stage and name it as VerifyCustomer. You can verify customer existence only when CustomerID
is present in input payload. So drag If-Then activity from Message Processing->Flow Control and
set condition as shown below.

Now drag a Service Callout in If branch from Stage Actions->Communication. In Properties tab,
browse to select CustomerServiceBS and find_customer as operation. Set other properties as
shown below and choose 'Configure Payload Document' option.

Create new XQueryTransformation CustomerPSToFindCustomer as shown below.

Finish transformation as shown below by mapping only the CustomerID.

Drag Assign activity into Request Action from Stage Actions->Message Processing and select
above XQuery transformation in expression editor. Give verifyCustReq as value for Variable
property.

Now your VerifyCustomer stage should look like below.

Creating Proxy with Local Transport


Using steps mentioned in previous sections, create new proxy service CustomerCommonPS
using the same WSDL as CustomerPS and select local transport. When local transport is used,
the proxy can only be invoked from other proxy services and cant be invoked by external
consumers. This way you can reuse the message flow.
Drag Operational Branch from Nodes and names it as CustomerOperation. Create 2 branches
for Create and Update operations.

To move message flow to new proxy service you can use Cut and Paste options available in
context menu on right click. So move CreatePipeline, CreateCustomerRoute, UpdatePipeline
and UpdateCustomerRoute to their respective operational branches in new proxy service.

Now in CustomerPS, modify CreateCustomer and UpdateCustomer branches by adding Routing


node and Routing activity. In properties tab, browse to select CustomerCommonPS and set
Invoking property as CreateCustomer and UpdateCustomer operations respectively.

Routing
In this section, you will route request to business service CustomerCommonPS to finish message
flow for MergeCustomer operation.
Drag Route Node after MergePipeline from Nodes and name it as MergeCustomerRoute. Since
you two different routings possible you can use the Routing Table activity. So drag Routing
Table activity in Routing node from Route Actions->Communication and set expression value as
$verifyCustResp/CustomerExists.

Click on Case in Routing Table activity, and select operator as = and set value as Y as shown
below.

Finish Routing activity in both Case and default branches by selecting CustomerCommonPS and
choose CreateCustomer and UpdateCustomer operations respectively.

Testing
Deploy both projects or run proxy service directly as shown in section Deploying and Testing.
You may want to frequently test proxy service during your development. Run your proxy service
with sample payloads given for both CreateCustomer and UpdateCustomer operations. For
error scenarios, observe the error returned from common proxy as shown below. You can
observe that flow trace does not show details of common proxy service message flow. But you
can always run CustomerCommonPS alone.

Also repeat UpdateCustomer test cases by sending CustomerID but find_customer response is
N so MergeCustomer will always invoke CreateCustomer operation. You can verify outbound
variable to determine which operation being called.

Negative Case (Status is E in business service response):

Proxy Service Error Handling


In this section, you will learn how to do error handling in Proxy Service. As shown in previous
sections, the Proxy Service is not returning any fault message or error with fault structure
defined in WSDL for both application/business and system errors. From the flow trace, you can
also observe that default System Error Handler is handling all the faults that arise in message
flow.
As you know, service provider can send error to consumer in the following ways:
As a normal response, by populating fields like ErrorNumber and ErrorMesssage
(assuming that these fields are defined in response message of operation in WSDL).
As a SOAP fault
Typically when OSB is mediating, you might have to transform error or fault response to the
fault structure defined in WSDL. So you need to understand the message context variables that
can be used for this transformation.
As per WS-I BP, the service provider should send the HTTP response code as 200 when the error is
sent as normal response and 500 should be sent when the error is sent as SOAP fault.
When HTTP response code 200 is received, OSB treats it as a normal response and proceeds
further with message flow. When response code 500 is received, OSB runtime control goes to
Service Error Handler if it exists or any other low level Error Handlers depending on where you
received. That means OSB treats even Fault response as normal response when HTTP response
code is 200. In message flow, Error Handler can be defined for Stage node, Pipeline Pair node
(both Request Pipeline and Response Pipeline individually), Routing node and for entire Pipeline
(called Service Error Handler).
OSB populates different message context variables with error/fault messages and is accessible
in Error Handler depending on whether you used Routing or Service Callout. When Routing is
used, the variable $body will have Fault response and when Service Callout is used, variable
$fault will have Fault response. The following table summarizes this discussion:
Activity
Routing
Routing
Routing
Service Callout
Service Callout
Service Callout

Scenario
Raise Error activity
Fault Response from business service
System fault while calling business service
Raise Error activity
Fault Response from business service
System fault while calling business service

Context Variable
$fault
$body
$fault
$fault
$fault
$fault

With this background, let us go back to your Proxy Service to add required Error Handlers. In
this case, the business service WSDL does not define any Fault structure and all errors will be
sent as normal response but with status E. But you should consider all possible cases for Error
Handling. So there is a possibility of 3 variables having the error/fault information and they are
$body, $fault and $faultVar (populated in your message flow on receiving status E in Routing).

Your Proxy Service uses both Service Callout and Routing in message flow so you can do the
fault handling in CustomerCmnPipeline in following manner:
Add Service Error Handler. Note that you can add error handler for Routing node, Stage,
Request Pipeline and Response Pipeline of Pipeline Pair nodes.
Add conditional branches to verify $body is populated with SOAP Fault, or variable
faultVar is populated, or $fault. Based on this you need to extract Error Code and Error
Message from $body, $faultVar and $fault variables.
Populate $body variable with fault structure (as per WSDL).

CustomerCommonPS
Drag ErrorHandler from Nodes in proxy service also drag a Stage node into it and name it as
ErrorHandler.

Add If-Then activity and two conditional branches (Else If branch) and set condition as below.
Remember adding namespace http://www.bea.com/wli/sb/stages/transform/config as con1
alias in Namespace definitions.
Branch
If

Condition
not(fn:empty($body/soap-env:Fault))

Else If

not(fn:empty($faultVar))

Else If

not(fn:empty($fault/ctx:details/con1:ReceivedFaultDetail))

Else

-NA-

Purpose
To handle fault received
in Routing.
To handle error response
received in Routing.
To handle fault received
in Service Callout.
All other possible cases.

Drag Replace activity from Stage Actions -> Message Processing into each of these branches
including else branch and set properties as below.

Set expression in expression editor with the following SOAP Fault structure for Replace activity
in If branch. Here you are extracting the error code and error message from received SOAP fault
received in Routing, this way you are forwarding actual error from service provider to consumer
of your proxy service.
<soap-env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>{$body/soap-env:Fault/faultstring/text()}</faultstring>
<detail>
<cust:ErrorStatusMsg xmlns:cust="http://xmlns.xyzbank.com/schema/Customer">
<ErrorCode>{$body/soap-env:Fault/faultcode/text()}</ErrorCode>
<ErrorMsg>{$body/soap-env:Fault/faultstring/text()}</ErrorMsg>
</cust:ErrorStatusMsg>
</detail>
</soap-env:Fault>

Set expression in expression builder with the following SOAP Fault structure for Replace activity
in Else If branch. Here you are extracting the error code and error message from error response
received in Routing, this way you are forwarding actual error from service provider to consumer
of your proxy service. Observe the usage of $fault variable to get error code given in RaiseError
activity.
<soap-env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>{$faultVar/error_message/text()}</faultstring>
<detail>
<cust:ErrorStatusMsg xmlns:cust="http://xmlns.xyzbank.com/schema/Customer">
<ErrorCode>{$fault/ctx:errorCode/text()}</ErrorCode>
<ErrorMsg>{$faultVar/error_message/text()}</ErrorMsg>
</cust:ErrorStatusMsg>
</detail>
</soap-env:Fault>

Set expression in expression builder with the following SOAP Fault structure for Replace activity
in second Else If branch. Here you are extracting the error code and error message from SOAP
Fault received in Service Callout, this way you are forwarding actual error from service provider
to the consumer of proxy service.
<soap-env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>{$fault/ctx:reason/text()}</faultstring>
<detail>
<cust:ErrorStatusMsg xmlns:cust="http://xmlns.xyzbank.com/schema/Customer">

<ErrorCode>{$fault/ctx:details/con1:ReceivedFaultDetail/con1:faultcode/text()}</ErrorCode>
<ErrorMsg>{$fault/ctx:details/con1:ReceivedFaultDetail/con1:faultstring/text()}</ErrorMsg>
</cust:ErrorStatusMsg>
</detail>
</soap-env:Fault>

Set expression in expression builder with the following SOAP fault structure for Replace activity
in Else branch. Here you are extracting error code and error message from $fault to take care of
other error scenarios.
<soap-env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>{$fault/ctx:reason/text()}</faultstring>
<detail>
<cust:ErrorStatusMsg xmlns:cust="http://xmlns.xyzbank.com/schema/Customer">
<ErrorCode>{$fault/ctx:errorCode/text()}</ErrorCode>
<ErrorMsg>{$fault/ctx:reason/text()}</ErrorMsg>
</cust:ErrorStatusMsg>
</detail>
</soap-env:Fault>

Now drag Reply activity into ErrorHandler stage from Stage Actions -> Flow Control after Ifthen activity. In Properties tab, select property as With Failure. This would send HTTP response
code as 500 along with SOAP fault. Selecting With Success will send HTTP response code as 200.

Alternatively, you can come up with XQuery map and take care of all these scenarios based on
variables populated on receiving error/fault response.
Now your error handler should look like below.

Testing
Deploy both projects or run proxy service directly as shown in section Deploying and Testing.
You may want to frequently test proxy service during your development. Run your proxy
services for error scenarios with sample payloads mentioned in previous sections and observe
the Flow Trace and Variables as shown in following screenshots. Observe that error response
from your proxy service should always have SOAP fault containing your error message.
Routing System Error:

Routing Error Response:

Routing Fault Response:

Validation Error (Validate activity):

Service Callout System Error:

Service Callout Error Response:

Service Callout Fault Response:

CustomerPS
Finish Service Error Handler similar to CustomerCommonPS as it has combination of Routing
and Service Callout. Do the testing and see how the final response is being sent to consumer of
proxy service. You can verify $fault or other context variables and can modify or choose the
right XPath expression for populating SOAP fault response in your Service Error Handler.

Securing Proxy Service


Security is one of the main aspects while developing any service and is no different from our
regular web applications. Also these services are reusable and can be invoked by either internal
or external customers, so you should consider securing your OSB proxy services so that only
valid users will be able to invoke.
OSB 11g is completely integrated with Oracle Webservices Manager (OWSM) which provides
several out of the box security policies and you can use these OWSM policies to secure your
proxy services. In this tutorial, you will use policy oracle/wss_username_token_service_policy
to secure the proxy service.
First step is creating users. Here you will see how to create users using sbconsole. But this is not
the recommended way and typically an Organization will have users in some LDAP directory and
you have to configure one of the Authenticators in Weblogic to access that LDAP. This
configuration and options will not be discussed here and beyond the scope this tutorial.

Creating User
Login to sbconsole. Click Create for new OSB session.

Navigate to Security Configuration. This will bring up the list of existing users.

Enter new user information and click Save.

Attaching OWSM Policy


Open CustomerPS by navigating to Project Explorer -> XYZCustomer-> Proxy Service and click
on Policies tab.

Click Add and select oracle/wss_username_token_service_policy from list of available policies.

Click Submit which brings up below screen showing all the attached policies.

Navigate to Security tab and make sure that Process WS-Security Header is set to Yes. This
enables the OSB runtime to enforce security as per attached policies otherwise the proxy service
just acts as pass-through without enforcing security.

Activate this session in Change Center and now your proxy service is ready to test.

You can also attach OWSM policies in Eclipse. To do this, open the proxy service in eclipse and
navigate to Policy tab. Make sure that you deploy your OSB project at least once to OSB server.
Then only eclipse will be able to show the list of available OWSM policies.

Select proxy service and click Add to enable OWSM Policy Configuration.

Click Browse and select oracle/wss_username_token_service_policy from the list of available


policies.

Go to Security tab and make sure that Process WS-Security Header is set to Yes.

Testing
You can use SOAP UI for testing. Create a test suite in SOAP UI using your proxy service WSDL.
Refer to http://soapui.org for any additional help.
Open request editor for any operation and paste the following as one of the SOAP headers. This
represents WS-Security header and is required by OWSM policy attached to your Proxy Service
above. You can also observe username and password fields.
<wsse:Security
soap:mustUnderstand="1"
xmlns:wsse="http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>UNAME1</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-tokenprofile-1.0#PasswordText">Welcome1</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>

Test using wrong credentials and observe the output showing security error.

Test using credentials created in previous section and observe the output.

Request

Response

You might also like