In cases where the invocation of web services is not interdependent, we can invoke web services in parallel. The parallel invocation shortens the BPEL process execution time. In this recipe, we will show you how to invoke web services in parallel.
For this recipe we will consume two web services. We will check for the hotel room and car availability in parallel. The availability data will give us information on hotels, where the rooms are available, and a car that is available for the date range. In order to complete the recipe, we need to deploy BookHotelService
and BookCarService
. The procedure for deploying web services can be taken from the Implementing web services with Axis2 recipe.
The following steps will cover the necessary activities to design the BPEL process for the parallel web service invocation:
<assign name = "AssignData"> <copy> <from variable = "inputVariable" part="payload" query = "/client:process/client:from"/> <to variable = "InvokeHotelSrvc_availableHotels_InputVariable" part = "parameters" query = "/ns2:availableHotels/from"/> </copy> <copy> <from variable = "inputVariable" part = "payload" query = "/client:process/client:to"/> <to variable = "InvokeHotelSrvc_availableHotels_InputVariable" part = "parameters" query = "/ns2:availableHotels/to"/> </copy> <copy> <from variable = "inputVariable" part = "payload" query = "/client:process/client:from"/> <to variable = "InvokeCarSrvc_getAvailableCar_InputVariable" part = "parameters" query = "/ns1:getAvailableCar/ns1:from"/> </copy> <copy> <from variable = "inputVariable" part = "payload" query = "/client:process/client:to"/> <to variable = "InvokeCarSrvc_getAvailableCar_InputVariable" part = "parameters" query = "/ns1:getAvailableCar/ns1:to"/> </copy> </assign>
<flow>
activity that enables the parallel processing. Inside the <flow>
activity we add two <invoke>
activities for the web service calls as shown in the following screenshot:<assign>
activity for mapping the results to the output variable as follows:<assign name = "Result"> <copy> <from expression = "concat(string(bpws:getVariableData('InvokeHotelSrvc_availableHotels_OutputVariable','parameters','/ns2:availableHotelsResponse/hotels')), ' ', bpws:getVariableData('InvokeCarSrvc_getAvailableCar_OutputVariable', 'parameters','/ns1:getAvailableCarResponse/ns1:return'))"/> <to variable = "outputVariable" part = "payload" query = "/client:processResponse/client:result"/> </copy> </assign>
The BPEL specification provides the <flow>
activity for the purpose of concurrency and synchronization. If there is a need to invoke web services in parallel, then we should use the <flow>
activity. The activity also ensures that all web services provide a reply before continuing the BPEL process.
It is possible to combine sequence and parallel execution of web services. We can bring the sequential execution into the parallel execution, and vice versa. We will show on the abstract layer how a mix of sequential and parallel processing is achieved.
Let's take our recipe and extend it with a requirement that, when we receive information about the hotel and car, we would like to confirm the reservation. We omit the details from the code and leave only the activities. The BPEL process now reads as follows:
<sequence name = "Sequence"> <flow name = "Flow1"> <sequence name = "Sequence1"> <invoke name = "InvokeCarSrvc"/> </sequence> <sequence name = "Sequence2"> <invoke name = "InvokeHotelSrvc"/> </sequence> </flow> <invoke name = "InvokeConfirmReservation"/> </sequence>
We see that the <invoke>
activities are nested into the <flow>
and <sequence>
activities.