Advertisements

Archive for October, 2014

Service Bus 12c – Series of Articles

Published following series of articles related Service Bus 12c. Hopefully it helps the people who want to get hands dirty.

Advertisements

Service Bus 12c – Creating Proxy Services

In Service Bus, Proxy Services provide an interface to Service Consumers. In this post, you will see different ways to create Proxy Servicse using JDeveloper based on a WSDL. And for demonstration purpose, we will consider Service Bus project and WSDL as shown below.

biz1_thumb[2]

Method 1:

Right click Service Bus project and select New –> Proxy Service. You can also select Pipeline in this context menu and check the option Expose as a Proxy Service in step2 of wizard.

clip_image001

Give a meaningful name for Proxy Service as shown below.

clip_image002

Click Browse WSDLs icon and select CustomerService WSDL.

method2ps4

Click OK to go back to Create Proxy Service wizard. Retain Generate Pipeline selection so that wizard will create both Proxy Service and Pipeline for you.

clip_image002[10]

Method 2:

Open the Service Bus overview file (file with same name as your project) and drag HTTP adapter into from Components –> Service Bus –> Technology –> HTTP into Proxy Services swim lane to bring up Create Proxy Service wizard as shown below.

adapter1_thumb[2]

method2ps1

method2ps

Give meaningful name for Proxy Service and click Next. Select WSDL option and select WSDL as shown in previous method by clicking Browse WSDLs icon.

method2ps2

method2ps3

Method 3:

Right click WSDL in Service Bus project and select Service Bus –> Generate Proxy Service as shown below. You can also select Generate Pipeline in this context menu and check the option Expose as a Proxy Service in step2 of wizard.

m3ps

Verify that Create Proxy Service wizard has come up showing WSDL and binding selected.

m3ps2

The following steps are common irrespective of above methods you choose to create Proxy Service.

Click Next and give Endpoint URI as /entity/CustomerService. So service consumers can access your proxy service using URL as given below.

:/entity/CustomerService”>http://:/entity/CustomerService

clip_image002[12]

Click Finish to bring up CustomerPS.proxy window showing properties of your Proxy Service. Go to Message Handling tab and select SOAPAction Header as Selection Algorithm. This would enable proxy service to determine operation at runtime based on SOAP Action in HTTP headers. You can retain the default option SOAP Body Type unless no 2 operations share same payload structure.

 

clip_image003

Now your Service Bus project should show both Proxy Service and Pipeline as shown below.

finalps

SOA 12c – Deploying MDS

In this post, you will learn a quick way to deploy File based MDS to database.

Assume you are using default SOA_DesignTimeRepository as shown below.

mds1

Right click SOA_DesignTimeRepository and select Transfer as shown below.

mds2

Select the Resources/Folders that you want to deploy to DB MDS.

mds3

Click + for Target Connection to bring up Create SOA-MDS Connection window. Enter Connection Name and select Connection Type, Connection and MDS partition as shown below. Typically, you would select a connection having MDS schema credentials. You can also verify the database connectivity using Test Connection.

mds4

Click OK and verify Target Connection is updated as shown below.

mds5

Click Transfer and verify that success message is shown up as below.

mds6

Click OK. In Resource Palette, verify that resources have been transferred and shown up as below.

mds7

This approach enables developer to deploy file based MDS quickly and improve the productivity and definitely one of my favorite features in 12c.

Service Bus 12c – MDS Support

In OSB 11g, sharing of resources (WSDL, XSD, XSLT etc…) typically happens using a common OSB project i.e. you create all common resources in single project and refer it from other OSB projects wherever required. In Service Bus 12c also, you would be following the same approach for sharing resources but now you can access resources from MDS. This is very much helpful when you have SOA implementation with MDS and trying to create virtualization layer on top of these services using those WSDLs.

In this post, you will learn to export your resources to MDS and refer resources (wsdl) from MDS to create Business and Proxy Services.

By default, your 12 JDeveloper has a default file based MDS repository and a MDS connection  is configured in IDE Connections to access that. The default MDS connection is called SOA_DesignTimeRepository and is shown below. You can use this connection to publish and access the resources.

Navigate to Window -> Resources -> IDE Connections -> SOA-MDS to view the configured MDS connection.

clip_image001[4]

You can observe the properties on right click of SOA_DesignTimeRepository and can see actual location of MDS repository in File System. If required, you can modify this to point to some other location.

clip_image003[4]

JDeveloper supports different operations like Create Folder, Export, Import and Delete of these resources from MDS. And you can also transfer MDS contents to other MDS repository. It’s highly recommended to have some standard folder structure in MDS enabling consumers to quickly locate and access the resources. We will create the following folder structure in MDS:

apps -> ServiceBus -> <<ProjectName>> -> wsdl/xsd/dvm/xslt

Right click on SOA_DesignTimeRepository, select Create Folder and give ServiceBus as folder name.

clip_image004[4]

Similarly, create folders representing your project and wsdl directory as shown below.

clip_image005[4]

Publishing Resources to MDS:

Right click on any resource like WSDL, XSD, XSLT, XQuery and DVM in your Service Bus project and select Service Bus -> Publish To SOA Designtime Repository as shown below.

clip_image007[4]

Choose the appropriate folder as shown below. You also have the option of creating new folders in this wizard.

clip_image009[4]

Click Next. Select overwrite property as per your requirements to override any existing resource with the same name. Here you can observe the resource Target URL which can be used to refer in your SOA Composites. Click Finish to complete the publish.

clip_image011[4]

Note: if you are unable to view resources in MDS repository after publish, do Refresh by selecting SOA_DesignTimeRepository on right click.

Creating Business Service using WSDL from MDS:

Right click on your Service Bus project and select New –> Business Service.

createbiz

Enter a meaningful name for business service and click Browse WSDLs icon.

createbiz1

Click SOA-MDS tab as shown below and select the WSDL.

createbiz2

Click OK and observer that Import Service Bus Resources wizard appears as shown below.

importwsdl

You can accept default location or can select different location for WSDL in your Service Bus project. Click search icon for Import Location.

importwsdl

Select the required folder and click Select to go back to Import Service Bus Resources wizard.

importwsdl1

Verify the Import Location is shown as the folder you selected and click Next.

importwsdl2

Click Next.

importwsdl3

Click Finish and verify that binding has been selected in Create Business Service wizard as shown below.

createbiz3

Click Next and enter the Endpoint URI of your actual service.

createbiz4

Click Finish and observe that selected wsdl is imported into Service Bus project and a new business service is created.

biz

Similarly, you can create Proxy Services using WSDL from MDS repository and refer resources like XQuery, XSLT and DVMs from SOA-MDS tab in Resource Chooser in message flow.

Observe that there is still no direct way to refer resources from MDS repository in Service Bus 12c and resources always gets imported into project as shown above.

Service Bus 12c – Error Handling

In this post, you will learn to do Error Handling and will incorporate in the Pipeline Template created in post.  We consider our Pipeline to return generic Fault response with error message in all possible error scenarios.

As you know, service provider can send error to consumer in 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 Service Bus is mediating, you might have to transform Error or Fault response to the Fault structure defined in WSDL. For this, you need to understand Message Context Variables that can be used.

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.

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). When HTTP response code 200 is received, Service Bus treats it as a normal response and proceeds further with message flow. When response code 500 is received, Service Bus runtime control goes to Service Error Handler if it exists or any other low level Error Handlers depending on where you received. That means Service Bus treats even Fault response as normal response when HTTP response code is 200.

Service Bus populates different message context variables with error/fault messages and is accessible in Error Handler depending on whether you used Routing or Service Callout. The following table summarizes this discussion:

Activity

Scenario

Context Variable

Routing

Raise Error activity

$fault

Routing

Fault Response from business service

$body

Routing

System fault while calling business service

$fault

Service Callout

Raise Error activity

$fault

Service Callout

Fault Response from business service

$fault

Service Callout

System fault while calling business service

$fault

So there is a possibility of 3 context variables $body, $fault and $faultVar having Error or Fault information (assuming faultVar is variable used in Raise Error activity of your message flow).

With this background, let us get back to Pipeline Template to add required Error Handler. Since your Pipeline uses both Service Callout and Routing in message flow, you can do fault handling in the following manner in Pipeline Template so that all of your concrete pipelines using this template would inherit this automatically.

  • Add Service Error Handler.
  • Add conditional branches in error handler to verify $body is populated with SOAP Fault, or faultVar or $fault is populated. Based on this, you have to extract Error Code and Error Message from $body, $faultVar and $fault variables.
  • Populate $body variable with the Fault structure as defined in WSDL.
 
Changes in CustomerPipelineTemplate:

Drag If-Then activity into ErrorHandler stage from Flow Control and add 3 conditional branches (Else If branch) as shown below.

clip_image002

In Properties tab, set Condition for all branches in Expression Builder as shown below. Remember adding the namespace http://www.bea.com/wli/sb/stages/transform/config with con1 as alias in Namespaces.

Branch

Condition

Purpose

If

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

To handle fault received in Routing.

Else If

not(fn:empty($faultVar))

To handle error response from given in Raise Error activity.

Else If

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

To handle fault received in Service Callout or Raise Error cases.

Else

-NA-

All other cases.

Drag Replace activity from Message Processing into each of these branches and set properties as shown below.

clip_image003

Set expression in Expression Builder with following SOAP Fault structure for Replace activity in If branch. Here you are extracting Error Code and Error Message from received SOAP fault received in Routing. This way you are forwarding the actual error from Service Provider to Consumer.

<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"&gt;

<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 following SOAP Fault structure for Replace activity in Else If branch. Here you are extracting Error Code and Error Message used in Raise Error activity. Observe the usage of $fault variable to get error code given in RaiseError activity. This way you are forwarding the error message used in Raise Error activity to Consumer.

<soap-env:Fault>

<faultcode>env:Server</faultcode>

<faultstring>{$faultVar/error_message/text()}</faultstring>

<detail>

<cust:ErrorStatusMsg xmlns:cust="http://xmlns.xyzbank.com/schema/Customer"&gt;

<ErrorCode>{$fault/ctx:errorCode/text()}</ErrorCode>

<ErrorMsg>{$faultVar/error_message/text()}</ErrorMsg>

</cust:ErrorStatusMsg>

</detail>

</soap-env:Fault>

Set expression in Expression Builder with following SOAP Fault structure for Replace activity in second Else If branch. Here you are extracting Error Code and Error Message from SOAP Fault received in Service Callout. This way you are forwarding actual error from Service Provider to Consumer.

<soap-env:Fault>

<faultcode>env:Server</faultcode>

<faultstring>{$fault/ctx:reason/text()}</faultstring>

<detail>

<cust:ErrorStatusMsg xmlns:cust="http://xmlns.xyzbank.com/schema/Customer"&gt;

<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 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 possible 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"&gt;

<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 Flow Control after If-then. 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.

clip_image005

Alternatively, you can come up with a XQuery map accepting these parameters and return appropriate SOAP fault structure. Now your ErrorHandler stage should look like below.

clip_image007

Observe that the Proxy Service you created using this Pipeline Template in this post had inherited ErrorHandler stage as shown below.

clip_image009

Some times, you may want to give your specific messages or override the messages from Service Provider. You can make all this kind of changes in your Error Handler and also typically one would want to convert System Errors into generic Application Error before sending to Proxy Service consumer. You can find more about details element in $fault variable here.

Testing:

Run your Pipeline and observe Flow Trace and Variables as shown below. Observe that the Error response from your Pipeline always contains a SOAP Fault conforming to WSDL.

Following are a few of the screenshots showing different Fault responses for both Routing and Service Callout in different error scenarios.

System Error in Routing:

clip_image013

Error Response received in Routing:

clip_image015

Fault Response received in Routing:

clip_image017

Validate activity failure Error:

clip_image019

System Error received in Service Callout:

clip_image023

Error Response received in Service Callout:

clip_image024

Fault Response received in Service Callout:

clip_image026

Service Bus 12c – Securing Proxy Services

Security is one of the main aspects while developing any service and is no different from our regular web applications. Also services are reusable and can be invoked by either internal or external customers, so you should consider securing your Service Bus Proxy Services so that only valid users can invoke.

Service Bus is completely integrated with Oracle Webservices Manager (OWSM) that provides several out of the box security policies. You can use any of these OWSM policies to secure your Proxy Services based on requirements. Here in this post, you will use oracle/wss_username_token_service_policy policy to secure Proxy Service.

As a first step, you need to create users who can invoke the service. Typically an Organization will have users in LDAP directory and you have to configure one of the Authenticators in Weblogic server to access LDAP for authentication purpose. This configuration will not be discussed here in this post.

Creating User:

Login to Admin Console and click Security Realms in Domain Structure.

clip_image002

Click myrealm as shown below.

clip_image004

Navigate to Users by clicking on Users and Groups tab.

clip_image005

Click New and enter credentials as shown below.

clip_image007

Click OK. Observe that new user has been created which  can be used to invoke Proxy Service.

clip_image009

Attaching OWSM Policy:

Open your Proxy Service. Navigate to Policies tab and select option as shown below.

clip_image011

Click + icon in Security section and select policy oracle/wss_username_token_service_policy.

clip_image013

Click OK and observe that selected policy is shown up in Security section.

clip_image015

You can also attach OWSM policies to Proxy Service in sbconsole. Launch sbconsole and create a new session. Navigate to All Projects –> <<your project>> and open the Proxy service to bring up a new tab as shown below.

clip_image017

Click Security and choose the option as shown below.

clip_image019

Click Attach Policies icon (highlighted above) and select the policy as shown below and click Attach.

clip_image021

Click OK and observe that selected policy is shown up as shown below.

clip_image023

Save your changes in current tab and activate the session.

clip_image024

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 of your Proxy Service operations and paste the following in SOAP header. This represents the WS-Security header and is expected by OWSM policy i.e. attached to Proxy Service. You can observe username and password fields below.

<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&gt;

<wsse:UsernameToken>

<wsse:Username>UNAME1</wsse:Username>

<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Welcome1</wsse:Password&gt;

</wsse:UsernameToken>

</wsse:Security>

clip_image026

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

clip_image028

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

clip_image030

clip_image032

Service Bus 12c–Creating Static Split-Join

In this post, you will learn to create and use Split Join and will use the same XYZCustomer project used in previous posts.

Split Join allows you to split the request payload so that you can call multiple services concurrently as opposed to the sequential processing. This way, you will achieve improved service performance.

In this post, you use Split Join to aggregate Customer Information by invoking different business services in parallel. The Customer Information includes basic Customer Details, Orders and Accounts. You can create the business services using the WSDLs given below. Make sure that you create 3 business services named CustomerServiceBS, CustomerOrderServiceBS and CustomerAccountServiceBS using following WSDLs respectively.

Purpose

Service WSDL

Customer Object operations

CustomerService.wsdl

Customer Order operations

CustomerOrderService.wsdl

Customer Account operations

CustomerAccountService.wsdl

Split Join can only be created based on WSDL so create new WSDL in WSDLs folder, having single operation with following. You can get the WSDL used in this post from .

  • Customer ID as input.
  • Customer information including Customer, Orders and Accounts Info as output.

Copy CustMigrationSplitJoin.wsdl into WSDLs folder of XYZCustomer project from here and create a new folder SplitJoins as shown below.

clip_image002

Creating Split-Join:

Open Service Bus overview editor and drag Split Join into middle swim lane from Components -> Service Bus -> Resources and finish the creation using wizard as shown below. Make sure that you select SplitJoins folder as the location in wizard.

clip_image004

clip_image006

Click Next and select WSDL CustMigrationSplitJoin.wsdl.

clip_image008

Click OK and uncheck Expose as a Proxy Service.

clip_image010

Click Finish. Observe that your Split Join flow should look like below.

clip_image013

Drag Parallel activity after Receive as shown below from Flow Control and add another branch by clickingclip_image014. The Parallel activity allows you to invoke different services concurrently.

clip_image016

In Properties tab, modify Name for all the Scope activities as shown below. Drag Invoke Service activity into each of these Scope activities in all 3 parallel branches from Communication to invoke Business services. Also modify Name property for Invoke activities in Properties tab.

clip_image018

In Properties tab, browse and select CustomerServiceBS, CustomerOrderServiceBS and CustomerAccountServiceBS for Service property of InvokeCustomer, InvokeCustOrder, InvokeCustAccount activities respectively.

clip_image020

clip_image022

Select Operation as shown below for InvokeCustomer, InvokeCustOrder , InvokeCustAccount activities respectively.

clip_image024

clip_image026

clip_image028

For InvokeCustomer, create Request and Response variables as shown below. Request Variable can be created as local variable as you don’t use it outside the scope.

clip_image030

clip_image031

clip_image033

clip_image034

Now your properties tab for InvokeCustomer should look like below.

clip_image035

Similarly create variables CustOrderReq, CustOrderResp for InvokeCustOrder and CustAccReq, CustAccResp for InvokeCustAccount respectively. Local variables created for each Scope activity should look like below.

clip_image037

Your global variables would be shown at Split Join level.

clip_image039

Drag Assign activity from Assign Operations into each of the scope activity and name them as AssignCustInfoReq, AssignCustOrderReq and AssignCustAccReq respectively in Properties tab.

clip_image041

In Properties tab, set properties for AssignCustInfoReq as shown below. This populates request variable with payload for CustomerServiceBS. Since there are not many fields to map, we have chosen this way to populate the payload avoiding new transformations.

Value:

<cust:customerid_input xmlns:cust="urn:xyzbank:cust:schema:customer">

<customer_id>{$request.parameters/customer_id/text()}</customer_id>

</cust:customerid_input>

clip_image042

In Properties tab, set properties for AssignCustOrderReq as shown below. This populates request variable with payload for CustomeOrderServiceBS.

Value:

<ordr:order_input xmlns:ordr="urn:xyzbank:cust:schema:order">

<ordr:customer_id>{$request.parameters/customer_id/text()}</ordr:customer_id>

</ordr:order_input>

clip_image044

In Properties tab, set properties for AssignCustAccReq as shown below. This populates request variable with  payload for CustomeAccountServiceBS.

Value:

<acc:account_input xmlns:acc="urn:xyzbank:cust:schema:account">

<acc:customer_id>{$request.parameters/customer_id/text()}</acc:customer_id>

</acc:account_input>

clip_image045

This would fetch Customer, Order and Account information concurrently by invoking respective business services. And you have to aggregate all these responses before returning back to caller. So you need a transformation to do this.

Create a XQuery map in XQueries folder of XYZCustomer project as shown below. Give name as CustOrderAccountToCustInfo.xqy.

clip_image047

Choose the Source for XQuery map using steps shown below.

clip_image049

clip_image051

clip_image053

clip_image055

clip_image057

Go back to Create XQuery Map window by clicking OK twice.

clip_image059

Similarly add 2 more parameters as shown below to accept Account and Orders information as the input.

clip_image061

clip_image062

clip_image064

clip_image066

Your Create XQuery Map screen should look like below.

clip_image067

Select Target using steps mentioned below.

clip_image068

clip_image070

Click OK twice to finish XQuery map creation and should be visible in XQueries folder as shown below.

clip_image071

Observe the Sources and Target structures and finish the mapping as required and as shown below.  You may want to test your XQuery map using the steps mentioned in this post.

clip_image073

Next step is using this XQuery map in Split Join. Drag Assign after Parallel activity from Assign Operations and set properties as shown below.

clip_image074

clip_image075

clip_image077

clip_image079

clip_image081

With this, you are done with message flow for Split Join and let us finish error handling as well before proceeding with testing. The WSDL used for split join has generic fault structure and you will use the same structure to return all types of faults to caller. So we will do fault handling at Split Join level. Right click CustMigrationSplitJoin and select CatchAll as shown below.

clip_image083

clip_image085

In Properties tab, give the fault variable name as shown below.

clip_image087

Drag Reply activity into Catch All branch from Communication.

clip_image088

In Properties tab, set properties as shown below by creating the new fault variable. This enables Split Join to return fault in case of any error to Pipeline.

clip_image089

Drag Assign activity into Catch All branch before Reply activity from Assign Operations. Modify name to AssignFault and set properties as shown below.

Value:

<custinfo:fault_msg xmlns:custinfo="urn:xyzbank:cust:schema:customerinfo">

<custinfo:error_code>XYZ-0009</custinfo:error_code>

<custinfo:error_message>Error in join operation.</custinfo:error_message>

</custinfo:fault_msg>

clip_image090

Testing Split Join:

Test your Split Join in similar to Proxy service/Pipeline. For my testing, I have used SOAP UI Mock Service to send sample responses to Split Join.

clip_image091

Positive Case:

clip_image093

clip_image095

clip_image097

clip_image099

Negative Case:

clip_image101

Invoking Split Join:

Drag Stage into Request Pipeline of your message flow and set the name as CallSplitJoin. Drag Service Callout from Communication as shown below.

clip_image001

In Properties tab, browse and select CustMigrationSplitJoin for Service property.

clip_image003

Select GetCustomerInfo operation and set other properties of Service Callout as shown below.

clip_image005

sJoinReq is variable to be populated with the payload for GetCustomerInfo operation and sJoinResp is variable that contains response returned by split join after service call. Since you are using ‘Configure Payload Document‘ option, you just need to populate the request variable with required payload.

Drag Assign activity from Message Processing into Request Action of Service Callout and set properties as shown below.

Value:

<urn:customerid_input xmlns:urn="urn:xyzbank:cust:schema:customerinfo">

<customer_id>{$body/cus:CustomerIDInput/CustomerID/text()}</customer_id>

</urn:customerid_input>

clip_image007

Now your CallSplitJoin stage should look like below.

clip_image008[4]

Service Bus 12c – Using XSL map

In this post, you will learn to create and use XSL maps in message flow using the same Service Bus project used in previous posts.

clip_image002[4]_thumb[2]

And here we are creating XSLT map for Customer transformation. The Source WSDL CustomerPS.wsdl and Target WSDL CustomerService.wsdl  are available here and here respectively. Make sure that you have these WSDLs copied in your project before proceeding with XSL map creation.

Creating XSL map:

Right click XSLTs folder in XYZCustomer project and select New -> XSL Map and give File Name as CustomerPSToUpdateCustomer.

clip_image001

Click Browse for Primary Source to bring up Select Schema screen.

clip_image003

Retain default selection and click Browse to select the source element.

clip_image004

Click OK twice to go back to Create XSL Map screen. Now click Browse for Target to bring up Select Schema screen again. And click Browse for Select Schema and select the target element as shown below.

clip_image006

Click OK twice and observe Source and Target elements.

clip_image008

Click OK to finish that brings up XSLT Transformation editor as shown below.

clip_image010

Here we are planning to do update of Customer Information, so you should not send null values in payload to business service; hence Target elements should be mapped only when corresponding Source element is available.

You can achieve this behavior automatically in XSL Map editor by setting a preference. Go to Tools -> Preferences and set property as shown below.

clip_image012

Now go back to XSL Map editor and do the initial mapping as shown below by connecting respective Source and Target elements. Observe that xsl:if condition gets added automatically when source element is defined as optional in schema.

clip_image014

Drag concat function into middle swim lane from Components-> General XPath -> String Functions to concatenate FirstName, Lastame and map to full_name. Also concatenate State, Country and ZipCode and map to addr_line4 as shown below.

clip_image016

Click concat functions and modify them to add  ‘,’ between elements as shown below.

clip_image018

clip_image020

Now go to Source and modify full_name and addr_line4 elements mapping to include xsl:if conditions so that Target will be mapped only when all of the  corresponding Source elements are present.

clip_image022

clip_image024

Testing XSL map:

It’s always advisable to test your XSL map to see whether mapping is working as expected. Click Test XSL Map icon in editor to bring up the following screen.

clip_image026

Click OK and observe that mapping is working as expected as shown below. You can also verify that both Source and Target xml files are generated. You can modify source xml and retest your XSL map again.

clip_image028

Using XSL map in Message Flow:

Drag Replace activity from Message Processing into message flow at place wherever you require transformation. In Properties tab, bring up expression editor for Value property and choose XSL map as shown below.

clip_image030

clip_image032

Click OK and give Input Document Expression as $body/*.

clip_image034

Set other properties as shown below. This action will replace the contents of $body context variable with transformed payload.

clip_image036

Service Bus 12c – Using XQuery map

In this post, you will learn to create and use XQuery maps in message flow using the same Service Bus project used in previous posts.

clip_image002[4]

And here we are creating XQuery map for Address transformation. The Source WSDL CustomerPS.wsdl and Target WSDL AddrValidationService.wsdl  are available here and here respectively. Make sure that you have these WSDLs copied in your project before proceeding with XQuery map creation.

Creating XQuery map:

Right click XQueries folder in XYZCustomer project and select New -> XQuery File ver1.0 to create new XQuery. Give both file and function name as AddrToAddrBSInput as shown below.

clip_image002

Click + icon to add Source parameter and give name as inputAddr.

clip_image004

Click pencil icon for Sequence Type to bring up Function Parameter Type window. Click browse icon and select Customer element in CustomerPS.wsdl as shown below. Here Customer element has address fields.

clip_image006

Click OK and retain default values for all the other properties in Function Parameter Type window as shown below.

clip_image008

Go back to Create XQuery Map window by clicking OK twice. Now click pencil icon for Target to bring up Function Result Type window. Click browse icon and select addrval_input element as shown below. Observe that the WSDL being used is AddrValidationService.wsdl.

clip_image010

Click OK thrice to bring up the Transformation editor and also do the initial mapping of attributes as shown below. You can map the fields by connecting Source and Target elements directly.

clip_image012

Drag concat function from Components -> XQuery Functions -> String Functions into Mappings swim lane. Connect Address2 and Address3 input elements to this function as shown below, as Target element expects concatenation of all address lines.

clip_image014

Address Validation service expects address lines with ‘,’ as delimiter, so go to XQuery Source tab and modify concat function as shown below.

clip_image016

Testing XQuery map:

It’s always advisable to test your XQuery to verify that mapping is working as expected. So right click XQuery file in XYZCustomer project and select Run XQuery.

clip_image017

clip_image019

Click List of variables button (highlighted above) to bring Edit Variable screen and select options as shown below.  This will generate the sample inputs automatically.

clip_image021

Click save icon and give file name as SampleCustomerInput.xml and click Add to Sequence.

clip_image023

Click OK and go back to Run XQuery screen. Give Target file name as AddrServiceInput by clicking Save icon.

clip_image025

Click Run and verify output of XQuery map to see mapping is working as you expected. You can observe that all address elements in Source concatenated and assigned to single element address_line in Target. You can also verify sample Source and Target files created in your XQueries folder.

clip_image027

Using XQuery map:

Drag Assign activity into Service Callout from Message Processing or place it at any other place in your Message Flow depending on where you want to use this transformation.

clip_image029

In Properties tab, select XQuery Resources for Value property.

clip_image031

In Expression Builder, click Browse icon and select the XQuery mapping.

clip_image033

Click OK. Use the following steps to set value for Binding property.

clip_image035

clip_image037

Click OK twice and set addrReqBody as the value for Variable property. This variable will contain the transformed value of address and can be used in your message flow later.

clip_image039

Service Bus 12c – Using Domain Value Maps (DVM)

In this post, you will learn to use Domain Value Maps (DVM) in message flow.

We consider the business requirement of performing Address Validation in message flow based on a configurable property and we use DVM to store this Configurable Property.

Creating Domain Value Map (DVM)

Create a new folder named DVM in XYZCustomer project. Right click DVM folder and select New -> Domain Value Map.

clip_image001 

Give Config as File Name and give DVM entries as shown below. The domain name PropertyName represents Configurable Properties and the domain PropertyValue represents configurable property values respectively.

Using this DVM, you can extend the same logic to any number of configurable properties in your Service Bus Application. For our requirement, give property name as ValidateAddress and set it’s initial value as Y.

clip_image003

Click OK to bring up DVM editor.

clip_image005

You can use JDeveloper to modify DVM or you can also modify it in sbconsole. Remember you need to create a session before modifying anything.

clip_image007

Using DVM in Message Flow

Drag Stage node into Stages placeholder of Request Pipeline and set name as AddrValidation in Properties tab.

clip_image009

Drag Assign activity into AddrValidation stage from Message Processing. Bring up expression builder for Value property and give expression as shown below. Alternatively you can select the function from Functions -> Custom XPath Functions -> Dvm functions. Make sure that you give complete qualified path of DVM containing Service Bus Project name too.

clip_image011

Set Variable property as ConfigVar. Now your Properties tab should look like below.

clip_image013

Address Validation business service should be invoked only when the value of this configuration property ‘Y’. So drag If Then activity into AddrValidation stage after Assign from Flow Control and set condition as $ConfigVar=’Y’.

clip_image015

Service Bus provides Service Callout, Routing and Publish activities to route incoming request to an appropriate business service. Routing and Service Callout are used for Synchronous where as Publish activity is used for one-way communication.

Routing node always depicts end of message flow so you can’t place any activities after Routing node. Hence use Service Callout for all intermediate service calls in pipeline. Drag Service Callout from Communication into If Then branch as shown below.

clip_image017

In Properties tab, browse and select AddrValidationServiceBS for Service property.

clip_image019


Advertisements

Pages

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 342 other followers

Enter your email address to follow this blog and receive notifications of new posts by email.