Oracle BPEL: Correlation sets
Useful post on correlation sets:
http://swapnil-soa.blogspot.com/2008/01/correlation-this-post-would-effort-to.html
The thing that it took me a while to realize is this. The "properties" of the correlation set are those values which are needed to correlate messages. The way to think of it is that you need to remember which instance you are going back to, like in the example of the flight request. If a flight agent fires off ten reservation requests, with a unique ID in each, then how do you tell which response has come back? You look at the ID which is returned by the flight system, and route the response to the corresponding instance. This isn't the same as putting a correlation ID into the correlationSet even before the message has gone anywhere, it's picking an ID from the message and looking for the same ID on the way back in order to know which reply has come back (and therefore which instance to use). God that was confused, the guy who wrote the above blog post puts it better.
To put it in concrete terms. If you want to correlate a message with a particular instance, when you've got three different services working togethetr, then do the following.
Here we have three services:
CallingService - this sends a message to the WorkerService, which starts up and then waits for a second message (different operation) to tell it to finish.
WorkerService - receives an incoming message from the initiate operation, then waits pending receipt of a "stop" operation message to tell it to finish. Worker service, in its contract, includes an "id" (string or integer or whatever) to correlate on.
StopService - this sends the "stop" message to the WorkerService, using the same ID in the input message which has been set up to correlate on.
The flow proceeds as follows:
1. CallingService sets up an ID of "id0001" in the message to WorkerService
2. CallingService calls "initiate" on WorkerService, with the ID (NB: no correlationSet defined in CallingService!!)
3. CallingService now ends or does other stuff.
4. WorkerService has defined a correlationSet in which is defined a property (and property alias) pointing to the ID in its input message for the initiate operation
5. the WorkerService instance starts up, receives the input data and immediately goes into a wait, pending receipt of a "stop" message correlated on the ID. Note that the stop message has the same input request message as the "initiate" operation.
6. The StopService is invoked. (NB: no correlationSet defined in StopService!!) This invokes the WorkerService "stop" operation, which is defined to use the same input request message as the "initiate" operation, so it also has the ID field. So the ID "id0001" is set up in the request message before the "stop" is invoked.
7. The WorkerService instance is now woken up as it has correlated on the ID field in the message. This ensures that the right instance is invoked. If there are several waiting for a "stop", only the instance waiting on the ID of "id0001" will be woken up.
8. WorkerService instance for ID "id0001" now finishes its work.
Don't forget that in this scenario ONLY the service which is waiting around (WorkerService) needs to do or know anything about correlationSets. The correlation ID passed by the CallerService and the StopService are just part of the regular data passed in on the input request. No need to define correlationSets on these two services.
One other thing. I got into a problem because both my operations were using the same input request message XML element, although different SOAP Actions. You should use different request message structures (best practice!). The properties for the correlation can point to different places in different messages - i.e. same property id but different XPath depending on the message!
This post is useful BPEL background on correlation:
http://www.ibm.com/developerworks/webservices/library/ws-bpelcol6/
See also Anthony Reynolds on the subject:
http://blogs.oracle.com/reynolds/2005/12/bpel_correlation.html
http://swapnil-soa.blogspot.com/2008/01/correlation-this-post-would-effort-to.html
The thing that it took me a while to realize is this. The "properties" of the correlation set are those values which are needed to correlate messages. The way to think of it is that you need to remember which instance you are going back to, like in the example of the flight request. If a flight agent fires off ten reservation requests, with a unique ID in each, then how do you tell which response has come back? You look at the ID which is returned by the flight system, and route the response to the corresponding instance. This isn't the same as putting a correlation ID into the correlationSet even before the message has gone anywhere, it's picking an ID from the message and looking for the same ID on the way back in order to know which reply has come back (and therefore which instance to use). God that was confused, the guy who wrote the above blog post puts it better.
To put it in concrete terms. If you want to correlate a message with a particular instance, when you've got three different services working togethetr, then do the following.
Here we have three services:
CallingService - this sends a message to the WorkerService, which starts up and then waits for a second message (different operation) to tell it to finish.
WorkerService - receives an incoming message from the initiate operation, then waits pending receipt of a "stop" operation message to tell it to finish. Worker service, in its contract, includes an "id" (string or integer or whatever) to correlate on.
StopService - this sends the "stop" message to the WorkerService, using the same ID in the input message which has been set up to correlate on.
The flow proceeds as follows:
1. CallingService sets up an ID of "id0001" in the message to WorkerService
2. CallingService calls "initiate" on WorkerService, with the ID (NB: no correlationSet defined in CallingService!!)
3. CallingService now ends or does other stuff.
4. WorkerService has defined a correlationSet in which is defined a property (and property alias) pointing to the ID in its input message for the initiate operation
5. the WorkerService instance starts up, receives the input data and immediately goes into a wait, pending receipt of a "stop" message correlated on the ID. Note that the stop message has the same input request message as the "initiate" operation.
6. The StopService is invoked. (NB: no correlationSet defined in StopService!!) This invokes the WorkerService "stop" operation, which is defined to use the same input request message as the "initiate" operation, so it also has the ID field. So the ID "id0001" is set up in the request message before the "stop" is invoked.
7. The WorkerService instance is now woken up as it has correlated on the ID field in the message. This ensures that the right instance is invoked. If there are several waiting for a "stop", only the instance waiting on the ID of "id0001" will be woken up.
8. WorkerService instance for ID "id0001" now finishes its work.
Don't forget that in this scenario ONLY the service which is waiting around (WorkerService) needs to do or know anything about correlationSets. The correlation ID passed by the CallerService and the StopService are just part of the regular data passed in on the input request. No need to define correlationSets on these two services.
One other thing. I got into a problem because both my operations were using the same input request message XML element, although different SOAP Actions. You should use different request message structures (best practice!). The properties for the correlation can point to different places in different messages - i.e. same property id but different XPath depending on the message!
This post is useful BPEL background on correlation:
http://www.ibm.com/developerworks/webservices/library/ws-bpelcol6/
See also Anthony Reynolds on the subject:
http://blogs.oracle.com/reynolds/2005/12/bpel_correlation.html

0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
Links to this post:
Create a Link
<< Home