A BPEL process can communicate with another BPEL process just like it can communicatie with any Web Service – as BPEL processes expose WebService interfaces to the world – or at least to their fellow components in the same Composite Application. When one process – the master in tis discussion – calls another one – it can have several types of interaction and dependency on that other process – we will call it the detail process for the purpose of this article:
- it is not interested at all in the detail process – its call was a one-way fire and forget
- it is interested in the response and it will wait for the response before it can continue processing (synchronous calls will always do this, asynchronous calls could have some activity going on while the detail process is churning away)
- it is interested in the fact that the detail process has reached a certain stage – but it does not actually need a response (it wants a signal but no data)
The Signal and ReceiveSignal activities are Oracle extensions to BPEL – that only work on the Oracle BPEL engine – that help us to implement the third scenario.
As part of the Invoke activity from a BPEL process to another process, we can specify that the called process should be considered a Detail process (and therefore the calling process as the Master process). When we have established this Master-Detail relationship, we can next create a Signal-ReceiveSignal connection between the two. These connections can be created in both directions: the Master sends a signal to the Detail (and the Detail waits to receive the signal) and vice versa the Detail process sends a signal that the Master is waiting for. Unfortunately, as we will see in this article, we cannot have multiple such interactions between a Master-and-Detail pair.
Typical use cases for the signal pattern are situations where a master process can only proceed when detail processes have completed or at least reached a certain state (the master process should only send the email to the customer when the detail process has handed the order to the shipping department) or when a master process calls a detail process to start processing and then needs to do some additional work before the detail process(es) can continue to their next step (master process asks detail to start gathering quotes from car rental companies, than continues to establish the credit-worthiness of the customer and when that has been taken care of indicates to the detail process that it may continue processing).
Note: there is nothing signal .and receiveSignal can do that we cannot also achieve using asynchronous, correlation driven calls. However, when we can achieve our goals using signaling, it is usually much easier to implement and lighter-weight to execute than the full blown correlation based solution.
Implementing BPEL Master-and-Detail processes
The requirement is our case is that the Master process invokes the detail process to have it start its work. Then the Master performs some additional work and when that is done it signals the detail process to indicate that it may perform the next step of its work. Then the master has to wait for the completion of that work in the detail process. The detail process informs the master of the fact that it is done and the master can continue processing.
We can implement this interaction using Signal and ReceiveSignal.
Step 1is the Invoke activity that has the check box Invoke as Detail checked. This results in a correlation being created in the BPEL engine between the Master process instance that makes the call and the Detail process instance that is being called.
<invoke name="Invoke_1" inputVariable="Invoke_1_process_InputVariable" partnerLink="DetailProcess.detailprocess_client" portType="ns1:DetailProcess" operation="process" <strong>bpelx:invokeAsDetail="true"</strong>/>
Step 2 is the Signal from the Master to the associated Detail instance – allowing the Detail process to continue processing.
<wait name="DoImportantMasterStuffThatShouldBeCompleteBeforeDetailProceeds" for="'PT30S'"/> <strong><bpelx:signal name="Signal_to_details_to_proceed" to="details" label="primary" /></strong>
Step 3 is the Receive Signal [from Detail process]in the Master: the master will at that point sit and wait until the signal is received from the correlated Detail process instance.
<strong><bpelx:receiveSignal name="receiveSignal_from_details_and_thenContinue" label="secondary" from="details"/> </strong><empty name="DoMoreWork"/>
In this example is the DoImportantMasterStuffThatShouldBeCompleteBeforeDetailProceeds activity a wait activity that lasts for 30 seconds.
The Detail process is implemented as shown in this figure:
In this case, the 1 indicates the initial creation of the Detail process instance – associated with a specific master instance. The detail process is a one-way service – no response is sent to the master process that invokes it.
The detail process starts with a first activity, ExecuteFirstStagesOfDetailProcessThatIsIndependentOfMaster.
Then at step 2 it reaches a stage where it has to have a signal from its master that is may continue processing. The ReceiveSignal activity is configured to listen for a signal from the master process. While it is waiting, processing stops in the detail process.
<bpelx:receiveSignal name="receiveSignal_doNotContinueBeforeMasterIsReady" label="primary" from="master"/>
When the signal has been received, the detail process continues with DoYourDetailThings – a wait activity in this demo that lasts for 10 seconds.
When the DoYourDetailThings step it is complete, the detail process sends out a signal to its master – step 3 Signal_to_master_that_detail_is_done - and continues processing.
<wait name="DoYourDetailThings" for="'PT10S'"/> <strong><bpelx:signal name="Signal_to_master_that_detail_is_done" label="secondary" to="master" /></strong> <empty name="DoMoreWork"/>
When we run the Master process, we also get a an instance of the detail process. The message flow trace in the SOA console looks something like this:
What is not supported
I would like to be able to have the master send multiple signals to the same detail process and vice versa. For example to have the master clear the detail process for phase 1, phase 2 and phase 3 of what it does for the master. And something similar for the master – to have it wait for the detail process to reach certain stages in its execution. A somewhat sophisticated handshake between master and detail. Like the one shown in the next picture:
Unfortunately, this does not work.
We cannot have a second signal sent to a detail process – only one Signal (and ReceiveSignal) can be associated with each Invoke of a detail process.
I tried to implement the requirement that the Master process invokes the detail, then performs some additional work and then signals the detail that it may perform stage one. Then the master has to wait for the completion of stage one in the detail process. (so far it all works fine).
These next two additional signal exchanges are not allowed: Then the master does some additional work and subsequently clears the detail process for the execution of its stage 3. The master next waits for a signal from the detail that it has completed stage 2.
Download JDeveloper 11g Application: MasterDetail.zip.
SOA Suite Developer's – Chapter 15
Blog post by Tom Hofte on Signal/Receive Signal