Understanding asynchronous service invocations

Unlike in a synchronous web service invocation, both parties act as client and server during an asynchronous web service invocation. So when sending the request, the BPEL process acts as the client and the external service becomes the server for the particular conversation. Then when the external service sends the response, external service is the client and the BPEL process is the server for that particular conversation.

In contrast with a synchronous web service invocation, those two client-server conversations should be defined separately in an asynchronous web service invocation. Now we will analyze the difference between a synchronous and an asynchronous invocation.

If you consider the implementation of a synchronous process, then you will notice the following facts:

  • In the BPEL process, the <invoke> activity is used for the whole conversation. So it encapsulates the input and output parameters required for the synchronous communication. Refer to the sample invoke activity included in the next bullet point.
  • Within the <invoke> construct, the input variables and output variables are used to store request and response from the external web service. Refer to the following sample invoke activity:
    <invoke name="InvokeCustomerInfo" partnerLink="CustomerInfoPL" operation="getCustomerSSN" portType="ns1:CustomerInfoPortType" inputVariable="customerInfoInput" outputVariable="customerInfoOutput" />
  • During a synchronous service invocation, the complete communication happens within one TCP connection. So the partner link of such an invocation only has one role named partnerRole. This partnerRole exposes the two-way operation of the external web service, which accepts the request and sends the response back to the BPEL process. Please refer to the following three code snippets:
    <partnerLinks>
      <partnerLink name="CustomerInfoPL" partnerLinkType="ns1:CustomerInfo" partnerRole="CustomerInfoPortTypeRole" />
    </partnerLinks>
  • Because of that, the partner link type also needs to define only one role;
    <plnk:partnerLinkType name="CustomerInfo">
      <plnk:role name="CustomerInfoPortTypeRole" portType="tns:CustomerInfoPortType"/>
    </plnk:partnerLinkType>
  • The WSDL of the external web service exposes a request-response-based operation to support synchronous web service invocation. The operation invoked within the <invoke> activity is a request-response-based operation. Refer to the sample WSDL port type, which exposes the getCustomerSSN operation. This operation is used in the invoke activity that is mentioned in the previous point:
    <portType name="CustomerInfoPortType">
      <operation name="getCustomerSSN">
        <input name="input" message="tns:getCustomerSSNRequest" />
        <output name="output" message="tns:getCustomerSSNResponse" />
      </operation>
    </portType>

However, if you compare the implementation of an asynchronous web service invocation with synchronous invocation, you'll realize the following facts:

  • In the BPEL process, <invoke> is used to send the outgoing request to the external web service. And <receive> is used to retrieve the incoming response from the external web service. Refer to the sample BPEL code snippet in the next point.
  • Within the <invoke> construct, only the input variable is used and the output variable is not used as output is not handled by <invoke>. The output is captured by <receive>. So <receive> defines a variable to handle the output variable:
    <invoke name="AsynchInvoke" partnerLink="AsynchPartnerLink" portType="ns3:Server" inputVariable="AsynchInvoke_initiate_InputVariable"  operation="initiate" bpelx:invokeAsDetail="no">
    ...
    </invoke>
    <receive name="AsynchronousReceive" createInstance="no" partnerLink="AsynchPartnerLink" portType="ns3:ServerCallback" variable= Receive1_onResult_InputVariable" operation="onResult">
    ...
    </receive>
  • During an asynchronous service invocation, the request and response communication happens via separate TCP connections. The partner link of such an invocation needs to have two roles named myRole and partnerRole. This partnerRole role exposes the one-way operation of the external web service which accepts the request from the BPEL process. And myRole exposes a one-way operation of the service exposed by BPEL service in order to accept the response from the external web service, as shown in the following code:
    <partnerLinks>
      <partnerLink name="AsynchPartnerLink" partnerLinkType="ns3:Server" myRole="ServerRequester" partnerRole= ServerProvider" />
    </partnerLinks>
  • Because of this, the partner link type also needs to define two roles:
    <plnk:partnerLinkType name="Server">
      <plnk:role name="ServerProvider" portType="tns:Server" />
      <plnk:role name="ServerRequester" portType="tns:ServerCallback" />
    </plnk:partnerLinkType>
  • The WSDL of the external web service exposes a one-way operation which is invoked by the BPEL <invoke> construct. This operation defines the schema of the request message for the external web service invocation. The service exposed by the BPEL process defines another one-way operation, which is invoked by the external service. This operation defines the schema of the response message for the external web service invocation, as shown in the following code:
    <portType name="Server">
      <operation name="initiate">
        <input message="tns:ServerRequestMessage" />
      </operation>
    </portType>
    <portType name="ServerCallback">
      <operation name="onResult">
        <input message="tns:ServerResponseMessage" wsaw:Action="http://wso2.org/onResult" />
      </operation>
    </portType>

The following are the pre-requisites to initiate an asynchronous web service invocation:

  • The WSDL interface of the external web service should expose one-way operation to capture the incoming request message from the BPEL process
  • The WSDL interface of the BPEL process should expose a one-way operation to capture the outgoing response message from the external web service

The following are the steps to implement an asynchronous web service invocation in a summary:

  1. Define the partner link with myRole and partnerRole.
  2. Define the invoke activity with the initialized inputVariable that is the outgoing request message from the BPEL process.
  3. Define the receive activity to capture the response message correlated with the invoke activity.

Callbacks

In the previous section, we talked about basic building blocks required for an asynchronous web service invocation. We explained why and how a partner link should represent the two communication channels, which manage request and response separately. These two channels are named partnerRole and myRole in the BPEL world. The myRole channel is used to represent the requester of the asynchronous communication. During an asynchronous web service invocation, the requester is the BPEL process. So in the WSDL representation of the BPEL process, myRole is pointed to an operation exposed by the BPEL process to accept the response from the external web service. We name this operation a callback operation.

A callback operation is used to transfer the response message of an asynchronous web service invocation to the client end from the server end. Here, the client end is the BPEL process and the server end is the external web service. Let's see how to set up the callback to the BPEL process.

Setting up a callback

Setting up a callback happens via the <receive> activity. You can configure a <receive> activity in a way to accept messages from the external web service. The partnerLink and operation attributes of the receive activity should point to a one-way operation exposed by the BPEL process such that the external web service can send the callback (response) message back to the BPEL process, as shown in the following code:

<invoke name="AsynchInvoke" partnerLink="AsynchPartnerLink" portType="ns3:Server" inputVariable="AsynchInvoke_initiate_InputVariable" 
operation="initiate" bpelx:invokeAsDetail="no">
…
</invoke>
<receive name="AsynchronousReceive" createInstance="no" partnerLink="AsynchPartnerLink" portType="ns3:ServerCallback" 
variable="Receive1_onResult_InputVariable" operation="onResult">
…
</receive>

Mapping response messages from asynchronous invocations

When a message reaches the BPEL server from an asynchronous web service, the BPEL server is responsible to figure out the following details to correlate the <invoke> activity which sends the request and the <receive> activity that receives the response message. Once the relevant <receive> activity is found, the BPEL server routes the particular response message to the correct <receive> activity.

  • Correct process: This is determined by the request URL. The request URL contains the name of the web service that exposes the BPEL process.
  • Correct instance: The BPEL server determines this by a specification called WS-Addressing. We'll discuss this in the next section.
  • Correct receive/pick-onMessage activity: This will not be discussed in this book.

    Tip

    If the asynchronous web service is implemented using Oracle SOA Suite or according to the WS-Addressing specification, Oracle BPEL Server automatically correlates response messages from asynchronous web services. Hence, users do not need to worry about message correlation when they are modeling asynchronous interactions using Oracle SOA Suite. Next, we will discuss about correlation in detail.

Message correlation – why, when, and how is it essential?

In this section, we will discuss an advanced topic that is targeted on readers who are interested in underlying techniques on mapping asynchronous web service responses to the correct BPEL process instance.

In the preceding section, we raised the question of mapping an incoming message to the BPEL server to a particular web service invocation. In an asynchronous web service invocation, there is no relation between the outgoing request message and the incoming response message, but when a message is being received by the BPEL server, the BPEL server should be able to determine which process instance initiated the outgoing asynchronous request. The response message should be routed to that particular process instance.

Let's have a look at the following graph to get a clear idea on this routing task:

Message correlation – why, when, and how is it essential?

How a request message reaches a process instance

In the preceding figure, you'll realize that there are multiple processes (Process1, Process2, and Process3) and there are multiple instances created from Process1 (that is, Process1-Instance1, Process1-Instance2, and so on). Once an incoming message hits the BPEL server, it can determine the correct process definition by the request URL. Once the process definition is determined, the BPEL server should determine to which instance the message should be routed. This is determined by correlating a specific header element (such as a WS-Addressing header) or a body element (for example, a unique ID included in the message body) of the outgoing and incoming SOAP messages. During an asynchronous invocation, a unique ID is propagated with an outgoing request message and that unique ID is queried in and verified with the incoming response message.

Correlation set is the standard mechanism in WS-BPEL 2.0 that defines the message parts which contain unique IDs that are used to map asynchronous requests and responses. Oracle SOA Suite supports WS-Addressing-based correlation, which doesn't require to specify correlation sets by users. We modeled the asynchronous interactions of the book warehousing process using WS-Addressing. WS-Addressing specification uses a header element in the SOAP message. This WS-Addressing-based header includes a correlation ID (that is a unique ID) and an endpoint location (for example, the URL at which a BPEL process instance is listening for the response message). By processing the WS-Addressing header content, Oracle SOA Suite can automatically route the message to the correct process instance.

In the next sections, we explain how to use correlation sets which are the standard correlation mechanism in WS-BPEL 2.0 for readers who are interested in advanced details.

Setting up a correlation set

Setting up a correlation set is a three-step process:

  1. Define the correlation set.
  2. Declare the WSDL message property and map it with the correlation set.
  3. Define the property aliases for the WSDL message property. These property aliases hold the exact message part which is to be correlated.

Understanding the correlation set

The <correlationSet/> construct is defined with a unique correlation set name. This name is referred by the <invoke> and <receive> constructs to map the outgoing request message with the incoming response message. This correlationSet construct has a properties attribute. This attribute's value can contain one or more WSDL message property names.

For example, consider the following code:

<correlationSets>
  <correlationSet name="AsynchronousServiceInvocationCorrelationSet" properties="ns4:correlationProperty" />
</correlationSets>

WSDL message property

WSDL message properties are defined in the WSDLs and they act as mappings to WSDL message parts. We can define a WSDL message property as the intermediate party which maps a correlation set to the exact message parts of the request and response. The schema of the request and response is different and the values which are used to identify the correlation between request and response can be in different places of the message. The WSDL message property should be able to represent both message parts of the request and response messages. This is achieved by message aliases such as <vprop:property name="correlationProperty" type="xsd:string"/>.

Property alias

A message alias represents the exact element of the message which is expected to be used to hold the unique ID for a particular asynchronous web service invocation. It consists of a <query/> element which can locate the elements or attributes of the message, such as:

<vprop:propertyAlias propertyName="cor:correlationProperty" element="ns1:ServerRequest" xmlns:ns1="urn:ode-apache- org:example:async:server">
  <vprop:query>/ns1:id</vprop:query>
</vprop:propertyAlias>
<vprop:propertyAlias propertyName="cor:correlationProperty" element="ns1:ServerResponse" xmlns:ns1="urn:ode-apache- org:example:async:server">
  <vprop:query>/ns1:id</vprop:query>
</vprop:propertyAlias>

Using a correlation for an asynchronous web service invocation

Now, let's see how to use the correlation defined in the previous section. For an asynchronous web service invocation, the correlation value is initiated when executing the <invoke> activity. Then this correlation value is persisted and used when a message is received to the particular BPEL process for routing operations.

A correlation is used when the request message leaves the BPEL server and when the response message reaches the BPEL server. We'll explain these two phases in the next two subsections.

Initializing a correlation at <invoke>

This is where the correlation is initiated for an asynchronous web service, as shown:

<invoke name="AsynchInvoke" partnerLink="AsynchPartnerLink" portType="ns3:Server" inputVariable="AsynchInvoke_initiate_InputVariable" operation="initiate">
  <correlations>
    <correlation set="AsynchronousServiceInvocationCorrelationSet" initiate="yes" />
  </correlations>
</invoke>

So you have to set initiate="yes" within the particular invoke activity.

Referring the initialized correlation at <receive>

This is where the previously initialized correlation is referred to realize whether the incoming message is relevant to the particular process instance, as shown in the following code:

<receive name="AsynchronousReceive" createInstance="no" partnerLink="AsynchPartnerLink" portType="ns3:ServerCallback" variable= Receive1_onResult_InputVariable" operation="onResult">
  <correlations>
    <correlation set="AsynchronousServiceInvocationCorrelationSet" initiate="no" />
  </correlations>
</receive>

So here the only difference is you don't have to initiate the correlation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset