Tuesday, March 17, 2015

How to use http:relative-URI element from http header to dynamically route to Multiple REST services in OSB 11g using HTTP transport

Recently, I was working for one customer and they asked me if we can build REST based services out of SOA Suite or OSB 11g. My answer was clear, they could either use HTTP adapter from SOA Suite in composite or use HTTP transport out of OSB.  Only http POST and GET verbs are available from HTTP adapter, where as in OSB 11g we can use most of the REST verbs through HTTP transport.

So my obvious choice was to use OSB http transport because of its VERB support and we can use conditional branch to process each VERB separately in OSB pipeline. One more advantage of using OSB transport over http adapter from SOA Suite was URL. If we use http adapter from SOA Suite we need to add operationName parameter at the end of the REST URL.

So that’s all done, now customer asked one more question, can we resolve target URI dynamically based on some parameter from incoming request header?

For example:

We have a REST service deployed with two separate operations and have following URLs
and

And now we have OSB routing service which accepts the request from client and routs it to either operation1 or 2. OSB routing proxy service URL looks like this


So when client calls above proxy service they will instruct OSB routing service which operation to call.

There are few other ways to do this. Such as we can store above target service URLs as XML resource file in out OSB routing service and use conditional branch to do routing using ROUTING OPTION component by setting URI parameter.

When discussing this requirement further with the customer, they mentioned there could be N number of operations and they should be able to build and then deploy them any time. But then every time they build a new REST service they don’t want to go back and change the OSB routing service.
One good way to achieve above requirement is through http:relative-URI element of request header in HTTP transport.

If client calls the proxy service with following URL (adding TestServiceOperation1 as a post fix)



We will receive TestServiceOperation1 part of URL in http:relative-URI element as follows





And now we can in OSB routing service we can create a Business Service with base URI


And we can Insert http:relative-URI element as last child of $outbound/ctx:transport/ctx:request to outbound transport headers when routing to that business service.

That way target service URI will be automatically resolved to

Monday, March 16, 2015

Single threaded (Synchronous) JMS message processing from Distributed Queue in WebLogic Clustered Environment.

In WebLogic SOA multi-node cluster environment we technically have multiple instances of JMS consumers running.

When there is a requirement to process all the messages in sequence from distributed Queue in clustered environment infrastructure, we may run in to issues where message are not processed in order they come in and synchronously.  

Bellow you would see one way to solve this issue.

WebLogic’s Unit-Of-Order feature from JMS provides the capability of processing particular stream of messages in Order based on Unit-Of Order key. Every message in that stream will be processed in order and synchronously using single thread.

If you set JMS_BEA_UnitOfOrder property to same key for all the messages published in distributed Queue in clustered environment, this will create one UOO stream on distributed destination and all the message from that stream will be processed in order and by single thread.


You can set Unit Of Order property to all publishing message globally in JCA JMS adapter configuration wizard.


WebLogic JMS Unit of Order

There may be a requirement to process stream of messages from particular group or publisher in-order from JMS Queue or Distributed Queue in cluster environment but at the time stream of messages from all other groups should be processed in parallel, means the whole queue should not be blocked when processing particular group or UOO stream.
Good example of above requirement is when we have thousands of user sessions and each session creates some sort of events and all those events needs to be processed in order and at the same time events from other sessions shouldn’t be blocked, they should be processed in parallel.

Unit-Of-Order feature of WebLogic JMS provides the solution for above requirement. You can set UOO (Unit-Of-Order) property to some key when publishing messages in to the queue. UOO key for a message is set in JMS header and kept by the name JMS_BEA_UnitOfOrder. It will enforce processing of stream of messages with same key (group) in order (First in First out) and other group of messages with different key will be processed in parallel.

This feature works well both in cluster (Distributed Destination) and non-clustered single node (Queue) environment.

Clustered Distributed Destination:

To use UOO feature in clustered environment it is required that you use separate JMS server targeted to each node in a cluster and each JMS server use its own persistence store. Single JMS server targeted to cluster would not work.

  1.  Create Separate JMS server for each node in a cluster with its own persistence store.
  2. Create one JMS module and target it to JMS servers you created in step 1 using sub-deployment.
  3. Create Uniform Distributed Queue inside the JMS module and target it to JMS servers using sub-deployment you have created in JMS module using advance targeting.
  4. Similarly create connection factory inside the JMS module and target it to JMS servers using sub-deployment you have created in JMS module using advance targeting.

Setting UOO property in OSB

Using JMS Transport:

If you are using JMS transport in OSB, you can set JMS_BEA_UnitOfOrder property in JMS header using Transport headers in request pipeline inside route node when publishing the message, simple as that.



Using JCA JMS adapter OSB 12c:


If you are using JCA JMS adapter out of OSB 12c then setting JMS_BEA_UnitOfOrder property in transport header doesn’t work instead you would need to set jca.jms.WeblogicUnitOfOrder



Setting this property in transport headers will overrides the value specified via property UnitOfOrder in JCA adapter configuration wizard.