This implies that we need some way to serialize requests for that resource (probably on a first in first out basis). A common design pattern for achieving this is the Singleton, first documented in the Gang of Four's patterns book (where they use a print spooler as an example).
Now BPEL doesn’t explicitly support the notion of a Singleton, however it does allow you to simulate one, which for the purpose of what we are trying to achieve is good enough.
The basic idea is to have an explicit initiateSingleton operation which is used to instantiate a single process instance, and then have a separate invokeSingleton operation which is used to submit each actual request. The invoke operation is then placed in a loop, so as soon as it’s processed one request it loops back round for the next one.
For this example, I’ve just created a simple process which keeps track of the number of times it’s been called. It takes a single parameter, name and returns a string of the following format:
Hello <name>. You are caller number <count> of this singleton.
Pretty simple, but it illustrates the point. The basic process is shown in the screenshot below:

InvokeSingleton – This receives the next request to be processed by the singleton. Wait – This waits for a period of 5 seconds. It is just to simulate going out to an external system. It also enables us to see how multiple requests for the singleton are queued up by the Oracle BPEL PM Server. SetResult – Here we just set the result and increment the count by one. CallbackClient – Finally we just send back the result to the client; before looping back round to process the next request.
Message Correlation
At first glance this all looks deceptively simple, however the complexity comes when you try and call the invokeSingleton operation.The reason is that when we invoke an operation on a BPEL Process, the message is received by the Oracle BPEL PM Message Handler, depending on the operation it will either invoke a new process to handle it (as with the initiateSingleton operation) or route it through to the appropriate instance of an already running process.
This is where it gets a bit convoluted, when we receive the message for the invokeSingleton operation, even though we only have a single instance of the BPEL process running how does BPEL PM know that it is the correct instance to route the message to? The answer is it doesn’t.
Now under “normal” circumstances, where we have an asynchronous interaction between two processes, Oracle BPEL PM defaults to using WS-Addressing to ensure that messages are successfully routed between two process instances. However in these cases, it’s typical that the interaction between the two processes (say A and B) began by process A initiating process B and passing it details (using WS-Addressing) about itself so that when process B sends back a response it contains sufficient information for it to be routed to the appropriate instance of process A.
However with our Singleton process, any process calling the invokeSingleton operation will have no prior knowledge of that process, so for our purposes we can’t use WS-Addressing to correlate the message.
Fortunately for situations where WS-Addressing isn’t appropriate or available BPEL provides the concept of correlation sets. Essentially correlation sets allow you to use a unique value present in the message body of all exchanged messages (e.g. orderId) to link that exchange of related messages together.
You do this in BPEL by first defining a property which corresponds to the unique value, and then defining a property alias for each message in the exchange, that defines where that property is located within the message. Next you define a correlation set which can consist of one or more properties (see the product documentation or the Oracle SOA Suite Developer's Guide
For our purpose, I’ve defined a simple element called singletonId which is contained in both the initiateSingleton and invokeSingleton operations.
Next we have defined a correlation set SingletonCS which is used in the InitiateSingleton and InvokeSingelton operations.
On the initiateSingleton operation I’ve defined this to initiate the correlation set (see screenshot below), this means whatever value is contained with the singletonId in the start operation must be present in the invokeSingleton operation for it to be routed through to this process instance.

Now you’ve probably already guessed that we need to use correlation sets again (as we have disabled WS-Addressing for this Partner Link). This time the calling process will need to generate a unique key that it passes in the request (requestId) to the singleton. The singleton will then return this in the response to the requester.
If we look at the SingeltonAccessor process, we use the XPath operator generateGUID to generate this value.
Specifying the Reply to Address
So now everything looks fine, so we can go ahead and run the process; well not quite! If you do you will notice that request from the SingeltonAccessor successfully reaches our Singleton process. But for some reason the response from the Singleton never reaches the SingeltonAccessor, in fact if you take a closer examination of the Singleton Audit trail for the callback activity you will see that it actually skipped the callback!Now it turns out that this is quite a rational behaviour for the simple reason that the Singleton doesn’t actually know where to send its callback to. This is because at design time the caller of an asynchronous process typically isn’t known, and thus the callback address needs to be specified at runt time. In fact if you log into the BPEL Console and examine the WSDL for the call back operation, you will see that the soap:address location for the endpoint is defined as:
http://set.by.caller
Now by default Oracle BPEL PM uses WS-Addressing to handle this, thus when I invoke an asynchronous process, part of the SOAP payload contains a return address for the asynchronous process, however we’ve just disabled WS-Addressing for this message exchange as we are using correlation sets.
So how do we provide the reply to address? Well one way would be to pass this in as part of the request message and then use dynamic partner links to set the replyToAddress.
However a simpler way is to define the replyToAddress property on the partnerlink to point to the reply address. This takes the format:
<wsdl endpoint>/partnerLinkTypeName/[rollName]
So in our case:
http://server:port/orabpel/default/SingletonAccessor/1.0/Singleton/SingletonRequester
Now if we deploy this it should finally work. To run the example, first go into the BPEL Console and initiate the Singleton process (set Singleton Id to "Singleton/1.0").
From the console initiate the SingletonAccessor entering whatever value you like for the name. You could kick off a number of these to see what happens.
Loose Ends
So that all works, however there are two basic problems with this approach:Firstly to invoke the Singleton you need to know the value of the SingletonId. This in our case is fixed within the SingltonAccessor process. Secondly, the Singleton process will only ever return a result to the SingletonAccessor process (as this is fixed by specifying the replyToAddress). What if we want to call it from another process or web service client?
Thus the client never needs to know the SingletonId, and secondly as WS-Addressing remains turned on between the “real” client and the SingletonAccesor the client doesn’t need to worry about correlation sets or specifying a replyToAddress.
One final question you may have is how do I prevent multiple instances of the Singleton process being kicked-off by mistake? Well why not try it? You will see that as long as you specify the same value for the SingletonId, BPEL PM will throw a “Conflicting Receive” fault as an equivalent receive activity has already been enabled by the original Singleton.
Conclusion
As we can see, implementing a Singleton within BPEL is relatively straight forward. Whilst this is not a totally clean solution, it does achieve the desired effect.
Click here to download working example.





16 comments:
Is there a way to dinamically define replyToAddress via Oracle Service Registry (UDDI)?
The while loop which is waiting endlessly for any new request actually keeps generating the audit trail(in BPEL Console). Is there a way we can limit this audit trail, so that whenever a new request is received by the InvokeSingleton only then the audit trail is generated.
The baseline is that we don't want the audit trail to be generated until there is a request to InvokeSingleton.
Hi Matt,
I am seeing the while and Receive and a wait. Once the BPEL process started, is it going to stay in memory or will get dehydrated until the next wait is ready?
What would be a good reason to solve this in a service orchestration language ? I'd think a JCA adapter may be a better place to host such functionality.
Unfortunately this approach doesn't work in High Availability environment. In that case term "singleton" is not suitable because two or more singletons should be somehow synchronized.
Zoran, can you explain why you think that a single BPEL instance will have multiple active threads?
Hi Antony,
The problem with HA environment is load balancing. Since there are 2+ instances of application servers in HA environment there will be 2+ active threads of one sigleton waiting on different app servers. If those threads are not synchronized somehow, you will have a serious problem if you have, for example, some internal counter which counts total number of received requests.
Hope it helps.
Zoran
I have a requirement where my SingletonAccessor BPEL process should invoke Singleton BPEL process for every 3 hours. But when i try to do that Singleton Accessor is erroring out saying 'correlation property cannot be initiated more than once.' Can anyone please help.
Hi Matt,
What would be the value for the replyToAddress property, if we migrate this project to 11g and I tried to give similar kind of value but no luck.
This property is available in the Properties tab of the Callback activity.
This approach requires to kick off an instance by invoking a separate method. Is it possible to just use one message? If I send a request to process an order for client A, if an instance is already serviceing client A, let that instance process it it, otherwise create a new instance to process client A requests? Is there such a thing as Grouping via correlation?
Hi Matt,
Thanks for the info and we have an issue with the singleton process.
We have an sinlgeton process which is running fine and it suddenly sops for every 2-3 days and manually we need to delete th e instance and initiate a new instance by passing singleton to initiate the Singleton.
We dont want to do it manually so we kept and count value in the Singleton proces so that after the count the running instance will automitically complete th e instance and start new instance using some table poling mechanism.
Can you pelase let us know how to set the correlation to initiate new singleton process.
Thanks,
Nagaraju D
Hi Matt,
Are there any directions as of how 11g replyToAddress works?
Matt,
We are invokgin the Singleton process in while loop adn it is not working.
can you please help m eout in this issue.
Thanks,
Nagaraju D
Hi',
How to do this in 11G, after migrating it to 11G, there seems to be an issue, the Singleton process is not returning the response back to Singleton accessor. Please advice, The replyToAddress is not working here.
Post a Comment