Pages

Jarvis Pizzeria: Second step in Implementing the Order Processing, Multi Instance Subprocess

In our previous blog we introduced the Pizza Order process. In this blog we will implement the next part of the Order Preparation process. We will add the call out to the Pizza Preparation process from the multi instance subprocess.

The first thing we need to do is feed every instance of the subprocess with the details of one pizza. For the outcome of the subprocesses we also need a storage location.

As a recap, an order consists of customer details and a list of pizzas to be made:
The order outcome is a list of status outcomes for each pizza.
We had already defined the data objects (DO’s) for these BO’s. Now we are going to associate them with the subprocess. For this we open the properties of the subprocess. Associated the DO’s to the consume and result of the subprocess (as shown on the right side of the image below). Now also make sure that the subprocess instantiates sequentially.

Next step is calling the Pizza Preparation process. Set the process call in the properties of the send activity.
Do the same for the receive activity.
Now we can feed the called subprocess with data. Go to the Data Association of the send activity. In here select the details of a specific pizza (by using the loopCounter over the list of pizzas) and associate it to the payloadIn of the Pizza Preparation process.
Next we do something similar for the receive activity.
And that was it again, how easy can it be? So let's deploy and see if everything works properly. But unfortunately the result of the test run surprised us. The first instance of the subprocess became suspended at the final step.

The EXECUTION_LOGGING shows the following message

And in more detail:
<auditQueryPayload auditId="1725" ciKey="366" xmlns="http://xmlns.oracle.com/bpmn/engine/audit">
<dataState>
<dataObject name="InstanceCount" isBusinessIndicator="false">
<value>
<![CDATA[1]]>
</value>
</dataObject>
<dataObject name="LoopCount" isBusinessIndicator="false">
<value>
<![CDATA[1]]>
</value>
</dataObject>
<dataObject name="FaultMessage" isBusinessIndicator="false">
<value>
<![CDATA[oracle.bpm.bpmn.engine.model.runtime.microinstructions.TrappableException: faultName: {{http://schemas.xmlsoap.org/ws/2003/03/business-process/}selectionFailure} messageType: {{http://schemas.oracle.com/bpel/extension}RuntimeFaultMessage} cause: {faultName: {{http://schemas.xmlsoap.org/ws/2003/03/business-process/}selectionFailure} messageType: {{http://schemas.oracle.com/bpel/extension}RuntimeFaultMessage}
parts: {{
summary=<summary>XPath query string returns multiple nodes.
The assign activity part and query bpmn:getActivityInstanceAttribute('ACT8ab29e4034addb8071bc8eb9960d7ffc', 'loopDataOutput')[1] are returning multiple nodes.
The assign activity part and query named in the error message returned multiple nodes. It should return single node.
According to BPEL4WS specification 1.1 section 14.3, the assign activity part and query named in the error message should not return multiple nodes. Verify the part and xpath query named in the error message at line number -1 in the BPEL source.
</summary>}
}
]]>
</value>
</dataObject>
</dataState>
</auditQueryPayload>
We used the ‘loopCounter’ and the details in the subprocess proves that it works fine for the input (loopDataInput[loopCounter]’) so how could it be possible that we selected multiple nodes on the output (loopDataOutput[loopCounter]) side? Why is this?

If we take a closer look to the data available in the subprocess then we see that it is not necessary to access the data via an index in the array, but that a separate variable has become available. it therefore seems that we are not approaching the data in the right way.
After changing both the send and receive activities to the InputDataItem and OutputDataItem, we rerun the test. Now we get the expected outcome. Three times ‘Preparation Finished’ as we ordered three pizzas.
Does the ordering process now work as desired? No, not yet. It is not the case that someone on his own is baking pizzas somewhere. We are a growing company with ambitions where we want to prepare several pizzas simultaneously. So far, however, the pizzas are prepared one by one (sequential). Let's run the preparation in parallel.

Would changing to parallel processing be enough to arrange this? Let’s try and see what is happening.
Go to the properties of the subprocess and switch to ‘In Parallel’. Redeploy again and perform a new test.
As we can see, three subprocess threads are started and the order process becomes faulted. Why is the order process faulted? Opening the fault gives the explanation
We have got a conflicting receive. All subprocess instances are waiting for a response of the called ‘Pizza Preparation Process’. But which call is correlated to which response? To use the subprocesses in parallel we need custom correlation. That is the subject of one of our coming blogs.

No comments:

Post a Comment