Explain how synchronous and asynchronous interactions can be handled via BPEL.
Let's understand what's meant by synchronous and asynchronous in BPEL terms. BPEL processes can also be categorized based on how it invokes an operation of a partner service: synchronous and asynchronous. However, it is not possible to use both methods when invoking a partner service's operation, as it is dependent on the type of partner service operation also.
Asynchronous interaction - Suppose a BPEL process invokes a partner service. After this invokation of the partner process, the BPEL process will continue to carry on with its execution process while that partner service completes performing its operation. The BPEL process will receive a response from the partner service, when the partner service is completed.
Synchronous interaction - Suppose a BPEL process invokes a partner service. The BPEL process then waits for the partner service's operation to be completed, and responded. After receiving this completion response from the partner service, the BPEL process will continue to carry on its execution flow. This transmission does not apply for the In-Only operations defined in the WSDL of the partner service.
Usually you'll use asynchronous services for long-lasting operations and synchronous services for operations that return a result in a relatively short time. Typically, when you use asynchronous Web services, the BPEL process too is asynchronous.
Let's take an example where there are both synchronous and asynchronous interactions. Suppose a loan approval process, where the client request for a loan with required documents. Then the service party first retrieve the customer information and his history using CustomerInfo service, then the service party calculate the credit rate using Credit rating service. Then service party finally send a request to DILoanService with previously retrieved the client history and the credit rating where the final decision from DILoanService may take a longer time. So we invoke DILoanService asynchronously.
So what's the difference between Asynchronous and Synchronous interactions?
Here when invoking a service asynchronously, we need to define two roles(myRole and partnerRole) for the partner link. In a synchronous interaction only partnerRole is need to be defined.
These roles which are defined in partner link type. And they maps to particular port types. A partner link type binds two port types; port type process offers(myRole) to a partner and port type partner offers(partnerRole) to a process. In the above example DILoanService is invoked asynchronously and DILoanService has to provide aportType, which defines the partnerRole and another portType which definesmyRole.
Refer LoanProcess.zip
In LoanProcess.bpel,
<invoke name="InvokeCustomerInfo" partnerLink="CustomerInfoPL" operation="getCustomerSSN" portType="ns1:CustomerInfoPortType" inputVariable="customerInfoInput" outputVariable="customerInfoOutput"/>
Synchronous interaction is pretty simple compared to asynchronous interaction where correlations need to be defined and <receive/> retrieves the response from the invoked service operation.
To get a detailed view on how this done, refer http://wso2.org/library/articles/writing-simple-ws-bpel-process-wso2-bps-apache-ode#invoke-partner-service.
In LoanService.bpel
<invoke name="Invoke" partnerLink="DILoanServicePL" operation="getLoanOffer" portType="ns2:LoanServicePortType" inputVariable="diLoanServiceRequest"/> <receive name="ReceiveDILoanService" createInstance="no" partnerLink="DILoanServicePL" operation="onLoanOffer" portType="ns2:LoanServiceCallbackPortType" variable="diLoanServiceResponse"> <correlations> <correlation set="correlator" initiate="no"></correlation> </correlations> </receive>
In this interaction, two separate activities manage request sending and response retrieving from the external service. <invoke/> handles external service execution and <receive/> manages the service response.
Let's figure out what's meant by each parameter.
<invoke name="Invoke" partnerLink="DILoanServicePL" operation="getLoanOffer" portType="ns2:LoanServicePortType" inputVariable="diLoanServiceRequest"/>
This partner link is defined at <partnerLinks/> in the BPEL.
<partnerLinks> <partnerLink name="DILoanServicePL" partnerLinkType="ns2:LoanServicePT" partnerRole="LoanServiceRole" myRole="LoanServiceClientRole"/> </partnerLinks>
The two roles, are defined at LoanServicePT partner link type.
eg - In LoanService.wsdl
<plnk:partnerLinkType name="LoanServicePT"> <plnk:role name="LoanServiceRole" portType="tns:LoanServicePortType"/> <plnk:role name="LoanServiceClientRole" portType="tns:LoanServiceCallbackPortType"/> </plnk:partnerLinkType>
The assigned portType for each role is in-only portTypes which each provides the operation to handle the request or to send the response.
In LoanService.wsdl
<portType name="LoanServicePortType"> <operation name="getLoanOffer"> <input name="input" message="tns:getLoanOfferRequest"/> </operation> </portType> <portType name="LoanServiceCallbackPortType"> <operation name="onLoanOffer"> <input name="input" message="tns:getLoanOfferResponse"/> </operation> </portType>
operation determines which operation to be invoked in the particular WSDL's portType, which was determined by partnerLink attribute previously.
values of this attribute determines the incoming messages for the partner Web service. So the variable specified by the inputVariable attribute value must be compatible with the message type specified in the <wsdl:input /> element of the particular WSDL's operation.
As mentioned <receive/> manages the service response. Let's understand the functionality of each parameter and <correlations/>.
eg - In LoanProcess.bpel
<receive name="ReceiveDILoanService" createInstance="no" partnerLink="DILoanServicePL" operation="onLoanOffer" portType="ns2:LoanServiceCallbackPortType" variable="diLoanServiceResponse"> <correlations> <correlation set="correlator" initiate="no"></correlation> </correlations> </receive>
determines whether to create a process instance when a message is received, or not.
an essential attribute in a <receive /> element. This determines the WSDL's portType to be chosen based on the partnerLinkType attribute and the myRole attributes defined in the particular <partnerLink /> element.
eg - In LoanService.bpel
<partnerLinks> <partnerLink name="DILoanServicePL" partnerLinkType="ns2:LoanServicePT" partnerRole="LoanServiceRole" myRole="LoanServiceClientRole"/> </partnerLinks> ......... <receive name="ReceiveDILoanService" createInstance="no" partnerLink="DILoanServicePL" operation="onLoanOffer" portType="ns2:LoanServiceCallbackPortType" variable="diLoanServiceResponse"> <correlations> <correlation set="correlator" initiate="no"></correlation> </correlations> </receive>
an essential attribute and determines which operation's message is the matching input message.
where the incoming message will be stored as a BPEL process variable for further manipulation in the BPEL process execution. This variable should be defined in a <variable /> inside <variables /> element.
In asynchronous service invocation, correlation is compulsory to define, as it used to correlate the outgoing message from <invoke/> and incoming message to <receive/>. In this particular example, messages are correlated by CustomerID.
eg - In LoanProcess.wsdl
<bpws:propertyAlias propertyName="tns:correlatorProp" messageType="ns1:getLoanOfferResponse" part="part"> <bpws:query>/ns:CustomerInfo/ns:CustomerID</bpws:query> </bpws:propertyAlias>