This chapter includes the following sections:
Synchronous web services provide an immediate response to an invocation. BPEL can connect to synchronous web services through a partner link, send data, and receive the reply in the same synchronous invocation.
A synchronous invocation requires the following components:
Defines the location and the role of the web services with which the BPEL process service component connects to perform tasks, and the variables used to carry information between the web service and the BPEL process service component. A partner link is required for each web service that the BPEL process service component calls. You can create partner links in several ways, including the following:
In the SOA Composite Editor, when you drag a SOAP service from the Technology section of the Components window into the Exposed Services or External References swimlane. For more information, see Adding Service Binding Components or Adding Reference Binding Components.
In Oracle BPEL Designer, when you drag a Partner Link icon from the BPEL Constructs section of the Components window into the Partner Links swimlane. This second method is described in this chapter.
Opens a port in the BPEL process service component to send and receive data. For example, this port is used to retrieve information verifying that a customer has acceptable credit using a credit card authorization service. For synchronous callbacks, only one port is needed for both the send and receive functions.
This section examines a synchronous invocation operation using a file named
To invoke a synchronous web service:
Figure 7-1 shows the diagram for a scope activity named Scope_AuthorizeCreditCard of a BPEL process named OrderProcessor, which defines a simple set of actions.
Figure 7-1 Diagram of OrderProcessor.bpel
The following actions take place:
The Assign_CreditCardCheckInput assign activity packages the data from the client. The assign activity provides a method for copying the contents of one variable to another. In this case, it takes the credit card type, credit card number, and purchase amount and assigns them to the input variable for the CreditCardAuthorizationService service.
The InvokeCheckCreditCard invoke activity calls the CreditCardAuthorizationService service. Figure 7-2 shows the CreditCardAuthorizationService web service, which is defined as a partner link.
Figure 7-2 CreditCardAuthorizationService Partner Link
Figure 7-3 shows the InvokeCheckCreditCard invoke activity.
Figure 7-3 InvokeCheckCreditCard Invoke Activity
An if activity (for BPEL 2.0) or a switch activity (for BPEL 1.1) checks the results of the credit card validation. For information about if and switch activities, see Defining Conditional Branching with the If or Switch Activity.
The BPEL 2.0 if activity replaces the BPEL 1.1 switch activity.
When you create a partner link and invoke activity, the necessary BPEL code for invoking a synchronous web service is added to the appropriate BPEL and Web Services Description Language (WSDL) files.
OrderProcessor.bpel code, the partner link defines the link name and type, and the role of the BPEL process service component in interacting with the partner service.
From the BPEL source code, the
CreditCardAuthorizationService partner link definition is shown below:
<partnerLink name="CreditCardAuthorizationService" partnerRole="CreditAuthorizationPort" partnerLinkType="ns2:CreditCardAuthorizationService"/>
Variable definitions that are accessible locally in the
Scope_AuthorizeCreditCard scope are shown in the following example. The types for these variables are defined in the WSDL for the process itself.
<variable name="lCreditCardInput" messageType="ns2:CreditAuthorizationRequestMessage"/> <variable name="lCreditCardOutput" messageType="ns2:CreditAuthorizationResponseMessage"/>
The WSDL file defines the interface to your BPEL process service component:
The messages that it accepts and returns
The operations that are supported
The web service's
.wsdl file contains two sections that enable the web service to work with BPEL process service components:
Defines the following characteristics of the conversion between a BPEL process service component and the credit card authorization web service:
The role (operation) played by each
portType provided by each for receiving messages within the conversation
A collection of related operations implemented by a participant in a conversation. A port type defines which information is passed back and forth, the form of that information, and so on. A synchronous invocation requires only one port type that both initiates the synchronous process and calls back the client with the response. An asynchronous callback (one in which the reply is not immediate) requires two port types:
One to send the request
Another to receive the reply when it arrives
In this example, the
CreditAuthorizationPort receives the credit card type, credit card number, and purchase amount, and returns the status results.
The following provides an example of
<plnk:partnerLinkType name="CreditCardAuthorizationService"> <plnk:role name="CreditAuthorizationPort"> <plnk:portType name="tns:CreditAuthorizationPort"/> </plnk:role> </plnk:partnerLinkType>
The invoke activity includes the
lCreditCardInput local input variable. The credit card authorization web service uses the
lCreditCardInput input variable. This variable contains the customer's credit card type, credit card number, and purchase amount. The
lCreditCardOutput variable returns status results from the
CreditCardAuthorizationService service. The following example provides details.
<invoke name="InvokeCheckCreditCard" inputVariable="lCreditCardInput" outputVariable="lCreditCardOutput" partnerLink="CreditCardAuthorizationService" portType="ns2:CreditAuthorizationPort" operation="AuthorizeCredit"/>
The BPEL code shown in the following example performs the synchronous invocation.
<assign name="Assign_CreditCheckInput"> <copy> <from variable="gOrderInfoVariable" query="/ns4:orderInfoVOSDO/ns4:OrderTotal"/> <to variable="lCreditCardInput" part="Authorization" query="/ns8:AuthInformation/ns8:PurchaseAmount"/> </copy> <copy> <from variable="gOrderInfoVariable" query="/ns4:orderInfoVOSDO/ns4:CardTypeCode"/> <to variable="lCreditCardInput" part="Authorization" query="/ns8:AuthInformation/ns8:CCType"/> </copy> <copy> <from variable="gOrderInfoVariable" query="/ns4:orderInfoVOSDO/ns4:AccountNumber"/> <to variable="lCreditCardInput" part="Authorization" query="/ns8:AuthInformation/ns8:CCNumber"/> </copy> </assign> <invoke name="InvokeCheckCreditCard" inputVariable="lCreditCardInput" outputVariable="lCreditCardOutput" partnerLink="CreditCardAuthorizationService" portType="ns2:CreditAuthorizationPort" operation="AuthorizeCredit"/>
You can specify transaction timeout values with the property SyncMaxWaitTime in the System MBean Browser of Oracle Enterprise Manager Fusion Middleware Control. The SyncMaxWaitTime property applies to durable synchronous processes that are called in an asynchronous manner. If the BPEL process service component does not receive a reply within the specified time, then the activity fails. For more information, see What You May Need to Know About SyncMaxWaitTime and Durable Synchronous Requests Not Timing Out.
To specify transaction timeout values:
The SyncMaxWaitTime property applies to durable synchronous processes that are called in an asynchronous manner.
Assume you have a BPEL process with the definition shown in the following example. The process is not durable because there are no breakpoint activities.
<receive name="receiveInput" partnerLink="client" variable="input" createInstance="yes" /> <assign> ... </assign> <reply name="replyOutput" partnerLink="client" variable="output" />
If a Java client or another BPEL process calls this process, the assign activity is performed and the reply activity sets the output message into a HashMap for the client (actually the delivery service) to retrieve. Since the reply is the last activity, the thread returns to the client side and tries to pick up the reply message. Since the reply message was previously inserted, the client does not wait and returns with the reply.
Assume you have a BPEL process with a breakpoint activity, as shown in the following example:
<receive name="receiveInput" partnerLink="client" variable="input" createInstance="yes" /> <assign> ... </assign> <wait name="Wait1"> <for>'PT10S'</for> </wait> <reply name="replyOutput" partnerLink="client" variable="output" />
While it is not recommended to have asynchronous activities inside a synchronous process, BPEL does not prevent this type of design.
When the client (or another BPEL process) calls the process, the wait (breakpoint) activity is executed. However, since the wait is processed after some time by an asynchronous thread in the background, the executing thread returns to the client side. The client (actually the delivery service) tries to pick up the reply message, but it is not there since the reply activity in the process has not yet executed. Therefore, the client thread waits for the SyncMaxWaitTime seconds value. If this time is exceeded, then the client thread returns to the caller with a timeout exception.If the wait is less than the SyncMaxWaitTime value, the asynchronous background thread then resumes at the wait and executes the reply. The reply is placed in the HashMap and the waiter (the client thread) is notified. The client thread picks up the reply message and returns.
Therefore, SyncMaxWaitTime only applies to synchronous process invocations when the process has a breakpoint in the middle. If there is no breakpoint, the entire process is executed by the client thread and returns the reply message.
You can expose a synchronous interface in the front end while using an asynchronous callback in the back end to simulate a synchronous reply. This is the default behavior in BPEL processes with the automatic setting of the
bpel.config.transaction property to
requiresNew in the
composite.xml file. The following example provides details.
<component name="BPELProcess1"> <implementation.bpel src="BPELProcess1.bpel"/> <property name="bpel.config.transaction" type="xs:string" many="false">requiresNew</property> </component>
requiresNew value is recommended. If you want to participate in the client's transaction, you must set the
bpel.config.transaction property to