Monday, October 15, 2012

Part 2: Developing a WS-BPEL Process using WSO2 Developer Studio


Tutorial 1 is a step by step instruction to implement a bpel process using WSO2 Developer Studio and deploy on WSO2 Business Process Server.

Today with tutorial 2, I am going to develop a BPEL process (let's call it as FunctionProcess) which has multiple service invocations. This is also going to be a synchronous  process as it does not involve any long-lasting operations. If you have already followed-up tutorial 1, then follow up of tutorial 2 is real easy.

The following flowchart illustrates the bpel process that we are going to develop in this tutorial.


Figure 1

This can simply be shown using an equation as follows.

f(x) = [(a * b) - (a + b) ]^2

Now we are going to design it using WSO2 Developer Studio, BPEL editor. 

Here, we have four service invocations, meaning that four Invoke activities such as InvokeMultiplyService, InvokeAdderService, InvokeSubtractService and InvokeSquareService.

Multiply and Adder activities are not depending on each other, or in other words, these activities can be invoked concurrently. So that they will be defined inside a flow activity (<flow/>) as shown in Figure 2.

Figure2
Open the FunctionProcessArtifacts.wsdl and click on the arrow next to FunctionProcessRequest.  Add two integer elements as shown in Figure 3.
Figure 3

Open the FunctionProcessArtifacts.wsdl and click on the arrow next to FunctionProcessResponse. Add resulting integer element.
Figure4

Let's configure four Assign activities. The source is given for each assign activity below, if you need to know how to do this with Developer Studio Graphical Editor, please follow-up tutorial 1.

AssignActivityInputParams Configuration
<bpel:assign validate="no" name="AssignInputParams">
            <bpel:copy>
                <bpel:from>
                    <bpel:literal>
                        <ns:add xmlns:ns="http://demo.carbon.wso2.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                            <ns:a>0</ns:a>
                              <ns:b>0</ns:b>
                        </ns:add>
                    </bpel:literal>
                </bpel:from>
                <bpel:to variable="adderPLRequest" part="parameters"></bpel:to>
            </bpel:copy>
            <bpel:copy>
                <bpel:from>
                    <bpel:literal>
                        <ns:multiply xmlns:ns="http://demo.carbon.wso2.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                            <ns:a>0</ns:a>
                              <ns:b>0</ns:b>
                        </ns:multiply>
                    </bpel:literal>
                </bpel:from>                
                <bpel:to variable="multiplyPLRequest" part="parameters"></bpel:to>
            </bpel:copy>            
            <bpel:copy>
                <bpel:from part="payload" variable="input">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:a]]></bpel:query>
                </bpel:from>
                <bpel:to part="parameters" variable="multiplyPLRequest">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:a]]></bpel:query>
                </bpel:to>
            </bpel:copy>          
            <bpel:copy>
                <bpel:from part="payload" variable="input">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:b]]></bpel:query>
                </bpel:from>
                <bpel:to part="parameters" variable="multiplyPLRequest">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:b]]></bpel:query>
                </bpel:to>
            </bpel:copy>
            <bpel:copy>
                <bpel:from part="payload" variable="input">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:a]]></bpel:query>
                </bpel:from>
                <bpel:to part="parameters" variable="adderPLRequest">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:a]]></bpel:query>
                </bpel:to>
            </bpel:copy>
            <bpel:copy>
                <bpel:from part="payload" variable="input">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:b]]></bpel:query>
                </bpel:from>
                <bpel:to part="parameters" variable="adderPLRequest">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:b]]></bpel:query>
                </bpel:to>
            </bpel:copy>
        </bpel:assign>




 AssignActivity2 Configuration
<bpel:assign validate="no" name="AssignActivity2">
            <bpel:copy>
                <bpel:from>
                    <bpel:literal>
                        <ns:substract xmlns:ns="http://demo.carbon.wso2.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                            <ns:a>0</ns:a>
                            <ns:b>0</ns:b>
                        </ns:substract>
                    </bpel:literal>
                </bpel:from>
                <bpel:to variable="subtractPLRequest" part="parameters"></bpel:to>
            </bpel:copy>            
            <bpel:copy><bpel:from part="parameters" variable="multiplyPLResponse">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:return]]></bpel:query>
                </bpel:from>
                <bpel:to part="parameters" variable="subtractPLRequest">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
                        <![CDATA[ns:a]]>
                    </bpel:query>
                </bpel:to>            
            </bpel:copy>
            <bpel:copy><bpel:from part="parameters" variable="adderPLResponse">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
                        <![CDATA[ns:return]]>
                    </bpel:query>
                </bpel:from>
                <bpel:to part="parameters" variable="subtractPLRequest">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
                        <![CDATA[ns:b]]>
                    </bpel:query>
                </bpel:to>            
            </bpel:copy> </bpel:assign>



 AssignActivity3 Configuration

             <bpel:assign validate="no" name="AssignActivity3"> 
              <bpel:copy>
                <bpel:from>
                    <bpel:literal>
                        <ns:square xmlns:ns="http://demo.carbon.wso2.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                            <ns:a>0</ns:a>
                        </ns:square>
                    </bpel:literal>
                </bpel:from>
                <bpel:to variable="squarePLRequest" part="parameters"></bpel:to>
            </bpel:copy>
            <bpel:copy>
                <bpel:from part="parameters" variable="subtractPLResponse">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:return]]></bpel:query>
                </bpel:from>
                <bpel:to part="parameters" variable="squarePLRequest">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:a]]></bpel:query>
                </bpel:to>
            </bpel:copy>            
        </bpel:assign>



AssignOutputParams Configuration
      <bpel:assign validate="no" name="AssignOutputParams">
            <bpel:copy>
                <bpel:from>
                    <bpel:literal>
                        <tns:FunctionProcessResponse xmlns:tns="http://wso2.org/bps/sample" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                            <tns:result>0</tns:result>
                        </tns:FunctionProcessResponse>
                    </bpel:literal>
                </bpel:from>
                <bpel:to variable="output" part="payload"></bpel:to>
            </bpel:copy>
            <bpel:copy>
                <bpel:from part="parameters" variable="squarePLResponse">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[ns:return]]></bpel:query>
                </bpel:from>
                <bpel:to part="payload" variable="output">
                    <bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"><![CDATA[tns:result]]></bpel:query>
                </bpel:to>
            </bpel:copy>
        </bpel:assign>


Now we have completed, implementation of the business logic  of our work flow.
 
Figure 5

Configuring deployment descriptor(deploy.xml)

This process has 4 service invocations, therefore there should have four partnerlinks in the outbound interface section.

Figure 6

Now we have completed the bpel process development. Let's deploy it on WSO2 BPS and test the flow.
Make sure to deploy four external(partner) services on a AppServer.

Testing the bpel process with TryIt (or with any other testing tool) gives the answer as;
  eg: f(x) = [(4*9) - (4+9)]^2 = 529


Figure 7

3 comments:

  1. Hi Ishaka,
    If these four services are in a single service i.e for example a mathematical operation service containing these four services then how to do the same example? Looking forward to your answers. Thanks in advance.

    ReplyDelete
  2. Hi Amit,
    In that case you have one external service wsdl, need only one partner link (PL). At each invoke activity you can select the appropriate operation using the created PL.

    ReplyDelete
  3. Hey Ishaka,
    Can you look into this question that i have asked on stackoverflow
    http://stackoverflow.com/questions/16811022/invoke-a-service-multiple-times-using-foreach-in-wso2-bpel

    ReplyDelete