Programming WebLogic Web Services
The following sections describe how to use reliable SOAP messaging, both as a sender and a receiver of a SOAP message, between WebLogic Server instances:
Warning: Reliable SOAP Messaging is not supported in a clustered environment.
Reliable SOAP messaging is a framework whereby an application running in one WebLogic Server instance can asynchronously and reliably invoke a Web Service running on another WebLogic Server instance. Reliable is defined as the ability to guarantee message delivery between the two Web Services.
Note: Reliable SOAP messaging works between two Web Services deployed on a single WebLogic Server instance. Typically this setup is used for development. However, in real-life, reliable SOAP messaging is meant to be used between two WebLogic Server instances, both of which must be configured to use reliable SOAP messaging.
The sender WebLogic Server has an application that asynchronously invokes a reliable Web Service operation running on the receiver WebLogic Server. The sender sends the receiver a SOAP message that has reliable SOAP messaging information in its header. The Web Service operation being invoked has been configured for reliable SOAP messaging. Due to the asynchronous nature of the invoke, the sender does not immediately know whether the relevant operation has been invoked, but it has the guarantee that it will get one of two possible notifications:
Note: This does not mean that the Web Service operation on the receiver WebLogic Server was invoked successfully; the operation might fail due to an application exception. The exception is included in the notification to the sender. For details about transactions, see Receiver Transactional Context.
Using the Weblogic Web Services asynchronous API, the sender can either poll the receiver for notification, or register a callback to be notified. Eventually, either the sender receives a notification that the message was received, or it receives notification that the message was not delivered.
Reliable SOAP messaging is transport-independent. By default, it uses HTTP/S. However, you can also use JMS if you configure the receiving Web Service appropriately and use the JMS port when the sender invokes the Web Service. For details on using JMS transport, see Using JMS Transport to Invoke a WebLogic Web Service.
The following terms are used in this section:
The following diagram and corresponding steps describe the architecture of the reliable SOAP messaging feature.
Figure 10-1 Reliable SOAP Messaging Architecture
Note: Only the message ID, and not the entire message itself, is persisted in the receiver's store.
The actions performed by the receiver execute within the context of a transaction. See Receiver Transactional Context.
Because only void
operations can be invoked reliably, the receiver does not return any values to the sender. If the invoked operation throws an application exception, the exception is, however, sent back to the sender. System exceptions (from EJBs, but not from Java classes) roll back the transaction started by a receiver. For details, see Receiver Transactional Context.
The sender is configured to retry sending the message if it does not receive notification of receipt. You configure the number of retries, and amount of time between retries, of the sender using the Administration Console. Once sender runtime has resent the message the maximum number of retries, it removes the message from its store.
When the receiver runtime receives a message from a sender, it starts a transaction, and the following subsequent receiver actions execute within the context of this transaction:
The main reason the receiver executes all its actions within the context of a transaction is to preserve the integrity of the message IDs in its persistent store. For example, suppose WebLogic Server crashes right after the receiver saves a message ID in its store, but before it invokes the operation; in this case, the transaction is rolled back and the saved message ID is removed from the store. Later, when the sender resends the message (because it has not yet received an acknowledgement that the operation was invoked), the receiver has no history of the message and will correctly go through the whole process again. If the receiver had not executed within the context of a transaction, it would never invoke the operation in this case because of the incorrect presence of the message ID in its store.
The transaction started by the receiver is rolled back if any of the following events occurs during the transaction:
RemoteException
.The following events do not cause a rollback of the transaction:
WithdrawalErrorException
, which is thrown by a method when a user tries to withdraw too much money from their account.When creating a stateless session EJB-implemented Web Service whose operations can be invoked reliably, follow these guidelines when programming the EJB:
Set the transactional attribute of an EJB method with the <trans-attribute>
element in the ejb-jar.xml
deployment descriptor.
EJBContext.setRollbackOnly()
method.RemoteException
) thrown by the EJB container or the EJB application method will roll back the transaction. Application exceptions (such as WithdrawalErrorException
thrown by the EJB when a user tries to withdraw too much money from an account) do not roll back the transaction.For more information, see Programming WebLogic Enterprise JavaBeans and Programming WebLogic JTA.
When creating a Java class-implemented Web Service whose operations can be invoked reliably, follow these guidelines when programming the Java class:
For more information, see Programming WebLogic JTA.
Use the Administration Console to configure the following transaction attributes:
Configuration settings for JTA transactions are applicable at the domain level. This means that configuration attribute settings apply to all servers within a domain. For details, see Configuring Transactions.
void
can be configured to be invoked reliably.
The following procedure describes the main steps for configuring reliable SOAP messaging to invoke a WebLogic Web Service operation. The procedure describes configuration and code-writing tasks that take place in both the sender and receiver WebLogic Server instances.
Note: It is assumed that you have already implemented and assembled a WebLogic Web Service and you want to enable one or more of its operations to be invoked reliably. Additionally, it is assumed that you have already coded a server-side application (such as a servlet in a Web application) that invokes the Web Service in a non-reliable way and you want to update the application to invoke the Web Service reliably.
For details about these tasks, see Implementing WebLogic Web Services, Assembling WebLogic Web Services Using Ant Tasks, and Invoking Web Services from Client Applications and WebLogic Server.
<servicegen
destEar="ears/myWebService.ear"
warName="myWAR.war"
contextURI="web_services" >
<service
ejbJar="jars/myEJB.jar"
targetNamespace="http://www.bea.com/examples/Trader"
serviceName="TraderService"
serviceURI="/TraderService"
generateTypes="True"
expandMethods="True" >
<reliability duplicateElimination="True"
persistDuration="60"
/>
</service>
</servicegen>
In the example, the Web Service ignores duplicate invokes from the same sender application and persists messages for at least 60 seconds. For more information on the attributes of the <reliability>
element, see servicegen.
Note: When you regenerate your Web Service using this build.xml
file, every operation that returns void
will be enabled for reliable invocation. If you want only certain operations to be invoked reliably, or you prefer not to regenerate your Web Service using servicegen
, you can update the web-services.xml
file of your WebLogic Web Service manually. For details, see Updating the web-services.xml File Manually for Reliable SOAP Messaging.
clientgen
Ant task, specifying the generateAsyncMethods="True"
attribute, to generate a new Web Service-specific client JAR file that contains the asynchronous operation invocations. This new client JAR file will be used with the server-side application running in the sender WebLogic Server.For an example, see Writing the Java Code to Invoke an Operation Reliably.
This section describes how to configure reliable SOAP messaging attributes for a WebLogic Server instance in its role as a sender of a reliable SOAP message.
Note: Part of the reliable SOAP messaging configuration involves configuring, if it does not already exist, a JMS File or JDBC store.
The following table describes the reliable SOAP messaging attributes.
To configure these attributes:
Warning: This value should be larger than the corresponding value of any Web Service operation being invoked reliably. Later sections describe how to configure his value in the Web Service's web-services.xml
file by updating the persist-duration
attribute of the <reliable-delivery>
subelement of the invoked <operation>
.
This section describes how to configure reliable SOAP messaging attributes for a WebLogic Server instance in its role as a receiver of a reliable SOAP message.
Note: Part of the reliable SOAP messaging configuration involves configuring, if it does not already exist, a JMS File or JDBC store.
The following table describes the reliable SOAP messaging attributes.
To configure these attributes:
Later sections in this document describe how each Web Service operation can override this default value. See Updating the web-services.xml File Manually for Reliable SOAP Messaging.
You specify that a WebLogic Web Service operation is reliable by updating its definition in the web-services.xml
file, adding the <reliable-deliver>
child element to the corresponding <operation>
element. You can do this using the servicegen
Ant task (see Using Reliable SOAP Messaging: Main Steps), or by updating the web-services.xml
file manually (see Updating the web-services.xml File Manually for Reliable SOAP Messaging). A client application, however, is not required to invoke a reliable operation in a reliable manner. There are three ways to invoke a reliable operation:
Writing the Java code to invoke a Web Service operation reliably from a sender application is very similar to invoking an operation asynchronously, as described in Writing an Asynchronous Client Application. The asynchronous invoke of an operation is split into two methods: start
Operation
()
and end
Operation
()
.
In addition to the standard asynchronous client Java code, to invoke an operation reliably you must:
AsyncInfo.setReliableDelivery(true)
method.This method also checks for correct JMS configuration and throws an exception if it finds any errors in the configuration.
AsyncInfo.setResultListener(listener)
method. The listener class implements the ResultListener
interface, which in turn defines the onCompletion()
listener callback method in which you define what happens when the asynchronous reliable operation invocation completes. The following example shows the simplest way to invoke the processOrder()
operation asynchronously and reliably by specifying the setReliableDeliver(true)
method and using the asynchronous API to split the operation into two invocations: startProcessOrder()
and endProcessOrder()
. You tell the clientgen
Ant task to generate these two methods in the stubs by specifying the generateAsyncMethods
attribute.
import weblogic.utils.Debug;
import weblogic.webservice.async.AsyncInfo;
import weblogic.webservice.async.FutureResult;
public final class ReliableSender {
public void placeOrder(String order) {
try {
// set up Web Service port
MarketService market = new MarketService_Impl();
MarketServicePort marketPort = marketService.getMarketServicePort();
// enable reliable delivery
AsyncInfo asyncCtx = new AsyncInfo();
asyncCtx.setReliableDelivery(true);
// call the Web Service asynchronously
FutureResult futureResult = marketPort.startProcessOrder(order, asyncCtx);
marketPort.endProcessOrder(futureResult);
} catch (Exception e) {
Debug.say("Exception in ReliableSender: " + e);
}
}
}
The following more complex example builds on the previous by setting a result listener to listen for the completion of the asynchronous and reliable operation invoke. The implementation of the onCompletion()
method specifies what happens when the invoke completes; in the example, a message is printed if the invoke failed.
import java.io.Serializable;
import weblogic.webservice.async.AsyncInfo;
import weblogic.webservice.async.FutureResult;
import weblogic.webservice.async.InvokeCompletedEvent;
import weblogic.webservice.async.ResultListener;
import weblogic.webservice.async.ReliableDeliveryFailureEvent;
import weblogic.utils.Debug;
public final class ReliableSender {
public void placeOrder(String order) {
try {
// set up Web Service port
MarketService market = new MarketService_Impl();
MarketServicePort marketPort = marketService.getMarketServicePort();
// enable reliable delivery
AsyncInfo asyncCtx = new AsyncInfo();
asyncCtx.setReliableDelivery(true);
// set up the result listener
RMListener listener = new RMListener();
asyncCtx.setResultListener(listener);
// call the Web Service asynchronously
FutureResult futureResult = marketPort.startProcessOrder(order, asyncCtx);
while ( !futureResult.isCompleted()) {
Debug.say("async polling ..."); // do something else
Thread.sleep(3000);
}
marketPort.endProcessOrder(futureResult);
} catch (Exception e) {
Debug.say("Exception in ReliableSender: " + e);
}
}
}
class RMListener implements ResultListener, Serializable {
public void onCompletion(InvokeCompletedEvent event) {
if (event instanceof ReliableDeliveryFailureEvent) {
ReliableDeliveryFailureEvent rdEvent =
(ReliableDeliveryFailureEvent) event;
Debug.say("Reliable delivery failed with the following message: " +
rdEvent.getErrorMessage());
}
}
}
The application that invokes an operation reliably must handle the case where the sender server crashes in the middle of retrying SOAP message delivery. Once the sender server restarts, it will check its persistent store for any messages that have not yet been successfully delivered, and if it finds any, it will continue trying to send the message to the receiver server. The problem, however, is that due to the sender server crash, the application that initially invoked the operation reliably may not be deployed anymore, and when the receiver server sends back an acknowledgement after the sender server restarts, there will be no application to accept the acknowledgment.
To handle this situation correctly, code your application to follow these guidelines:
ResultListener
interface. This class listens for the completion of the reliable operation invoke. See the second example Writing the Java Code to Invoke an Operation Reliably for a sample of writing this class.ResultListener
interface to also implement the Serializable
interface to ensure that, in case of a sender server crash, the class will be serialized and stored on disk. Then, once the sender server restarts, the result listener class will also be invoked and will handle subsequent acknowledgment messages from the receiver. If you regenerated your Web Service using the servicegen
Ant task, every operation that returns void
is enabled for reliable invocation. If you want only certain operations to be invoked reliably, or you prefer not to regenerate your Web Service using servicegen
, you can update the web-services.xml
file of your WebLogic Web Service manually, as described in this section.
The web-services.xml
file is located in the WEB-INF
directory of the Web application of the Web Services EAR file. See The Web Service EAR File Package for more information on locating the file.
To update the web-services.xml
file to enable reliable SOAP messaging for one or more operations:
<reliable-delivery>
subelement and specify the following optional attributes:duplicate-elimination
- Boolean that specifies whether the WebLogic Web Service should ignore duplicate invokes with the same message ID from the same sender application. Default value is True
.persist-duration
- Integer value that specifies the minimum number of seconds that the Web Service should persist the history of the reliable SOAP message (received from the sender that invoked the Web Service) in its storage. When persist-duration seconds have elapsed, the receiver WebLogic Server deletes the history of the message from its store. The value of this attribute, if you set it, should be greater than the product of the retry interval and the retry count of the sender.This attribute overrides the default server value you set in Configuring the Receiver WebLogic Server. The default if neither is set is 360 seconds.