Friday, August 15, 2014

Unwritten Rule with Oracle BPM Parallel Gateway with Multi-Instance processing

There are numerous scenarios that requires the usage of the multi-instance sub-process in BPM. Lets consider an example of an Order entity with multiple OrderLines. For each status we require to do different processing and once all the processing is complete, we require to merge the final outcome into the Order entity.

The implementation pattern we will follow is to use the parallel gateway connecting different multi-instance sub-process each filtering their respective order lines and do the processing. Once everything is done they will converge at the outgoing parallel gateway.

The below xsd represents  a simple schema for Order entity:

<?xml version= '1.0' encoding= 'UTF-8' ?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     xmlns:qt="http://www.mycompany.com/ns/order" targetNamespace="http://www.mycompany.com/ns/order"
     elementFormDefault="qualified">
    <annotation>
        <documentation xml:lang="en">Order</documentation>
    </annotation>
    <element name="order" type="qt:OrderType"/>
    <element name="orderLine" type="qt:OrderLineType"/>
    <complexType name="OrderType">
        <sequence>
            <element name="orderID" type="string"/>
            <element name="customerName" type="string"/>
            <element name="customerAddress" type="string"/>
            <element name="orderLine" maxOccurs="unbounded" minOccurs="0" type="qt:OrderLineType"/>
        </sequence>
    </complexType>
    <xsd:complexType name="OrderLineType">
        <xsd:sequence>
            <xsd:element name="orderLineID" maxOccurs="1" type="xsd:string"/>
            <xsd:element name="itemId" maxOccurs="1" type="xsd:string"/>
<xsd:element name="quantity" maxOccurs="1" type="xsd:int"/> <xsd:element name="status" maxOccurs="1" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </schema>

Lets create the business process for the scenario mentioned.


 Add 'order' element as the input to the bpmn process


Associate the input to the process to the 'order' data object created.


A draft process could look like below:


Lets make it interesting, lets configure each sub-process to filter only their respective order lines. First for Pending Orders 


XPATH expression to filter the pending order lines is shown below(we need to put the expression for both input & output loop data output) - 


Similarly, do the same for approved orders also. The final process would look like :


Now lets deploy the bpm process and test the process with the below input :-


<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
 <soap:Body>
  <ns1:start
   xmlns:ns1="http://xmlns.oracle.com/bpmn/bpmnProcess/MultiInstanceProcess"
   xmlns:ns2="http://www.mycompany.com/ns/order">
   <ns2:order>
    <ns2:orderID>1</ns2:orderID>
    <ns2:customerName>Ganesh</ns2:customerName>
    <ns2:customerAddress>Melbourne</ns2:customerAddress>
    <ns2:orderLine>
     <ns2:orderLineID>100</ns2:orderLineID>
     <ns2:itemId>10</ns2:itemId>
     <ns2:quantity>2</ns2:quantity>
     <ns2:status>APPROVED</ns2:status>
    </ns2:orderLine>
    <ns2:orderLine>
     <ns2:orderLineID>101</ns2:orderLineID>
     <ns2:itemId>33</ns2:itemId>
     <ns2:quantity>1</ns2:quantity>
     <ns2:status>APPROVED</ns2:status>
    </ns2:orderLine>
    <ns2:orderLine>
     <ns2:orderLineID>102</ns2:orderLineID>
     <ns2:itemId>34</ns2:itemId>
     <ns2:quantity>10</ns2:quantity>
     <ns2:status>PENDING</ns2:status>
    </ns2:orderLine>
   </ns2:order>
  </ns1:start>
 </soap:Body>
</soap:Envelope>

The audit trail for the above test is shown below. There are two threads processing the 'APPROVED' orders and one Thread for the 'PENDING' order.


So far so good.. now lets MIX THE STATUSES in the input and test the process again. The input used is :-


<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
 <soap:Body>
  <ns1:start
   xmlns:ns1="http://xmlns.oracle.com/bpmn/bpmnProcess/MultiInstanceProcess"
   xmlns:ns2="http://www.mycompany.com/ns/order">
   <ns2:order>
    <ns2:orderID>1</ns2:orderID>
    <ns2:customerName>Ganesh</ns2:customerName>
    <ns2:customerAddress>Melbourne</ns2:customerAddress>
    <ns2:orderLine>
     <ns2:orderLineID>101</ns2:orderLineID>
     <ns2:itemId>33</ns2:itemId>
     <ns2:quantity>1</ns2:quantity>
     <ns2:status>APPROVED</ns2:status>
    </ns2:orderLine>
    <ns2:orderLine>
     <ns2:orderLineID>102</ns2:orderLineID>
     <ns2:itemId>34</ns2:itemId>
     <ns2:quantity>10</ns2:quantity>
     <ns2:status>PENDING</ns2:status>
    </ns2:orderLine>
    <ns2:orderLine>
     <ns2:orderLineID>100</ns2:orderLineID>
     <ns2:itemId>10</ns2:itemId>
     <ns2:quantity>2</ns2:quantity>
     <ns2:status>APPROVED</ns2:status>
    </ns2:orderLine>
   </ns2:order>
  </ns1:start>
 </soap:Body>
</soap:Envelope>



The process fails with the error :- 

Error Message: {http://docs.oasis-open.org/wsbpel/2.0/process/executable}mismatchedAssignmentFailure
default/MultiInstanceProcess!1.0*soa_00de7c84-1a46-4324-a7f2-2071ef7a680f/MultiInstanceProcess/830003-ACT10651136503013MultiInstanceBlock_ACT10651136503013_End-ACT10651136503013MultiInstanceBlock_ACT10651136503013.3-2
Aug 15, 2014 10:49:09 PM
Non Recoverable System Fault :
<bpelFault><faultType>0</faultType><mismatchedAssignmentFailure xmlns="http://docs.oasis-open.org/wsbpel/2.0/process/executable"></mismatchedAssignmentFailure></bpelFault>


Why is the mismatchedAssignmentFailure error thrown in this case, if the order status are mixed. This is because bpm internally uses an function similar to the bpelx:copyList to copy the nodes and unless the list used to filter the status are contiguous, the above pattern will not work.

From documentation -
http://docs.oracle.com/cd/E23943_01/dev.1111/e10224/bp_manipdoc.htm#CIHICJGH

6.14.6.1 bpelx:copyList in BPEL 1.1

Example 6-65 provides an example of bpelx:copyList in a BPEL project that supports BPEL version 1.1.

Example 6-65 bpelx:copyList Extension in BPEL 1.1
<bpel:assign> 
    <bpelx:copyList>
       <bpelx:from ... />
       <bpelx:to ... /> 
    </bpelx:copyList>
</bpel:assign>
The from-spec query can yield a list of either all attribute nodes or all element nodes. The to-spec query can yield a list of L-value nodes: either all attribute nodes or all element nodes.
All the element nodes returned by the to-spec query must have the same parent element. If the to-spec query returns a list of element nodes, all element nodes must be contiguous.


No comments:

Post a Comment