6 Using the Asynchronous Features Together

The following sections describe how to use the asynchronous features together:

Using the Asynchronous Features Together

The preceding sections describe how to use the WebLogic Web Service asynchronous features (Web Service reliable messaging, conversations, asynchronous request-response, and buffering) on their own. Typically, however, Web Services use the features together; see Example of a JWS File That Implements a Reliable Conversational Web Service and Example of Client Web Service That Asynchronously Invokes a Reliable Conversational Web Service for examples.

When used together, some restrictions described in the individual feature sections do not apply, and sometimes additional restrictions apply. The following table summarizes considerations for various feature combinations.

Table 6-1 Considerations When Using Asynchronous Features Together

Feature Combination Consideration

Asynchronous request-response with Web Service reliable messaging or buffering

  • The asynchronous response from the reliable Web Service is also reliable. This means that you must also configure a JMS server, module, and queue on the source WebLogic Server instance, in a similar way you configured the destination WebLogic Server instance, to handle the response.

    When you create the JMS queue on the source WebLogic Server instance, you are required to specify a JNDI name of weblogic.wsee.DefaultQueue; you can name the queue anything you want. You must also ensure that you specify that this JMS queue is local, typically by setting the local JNDI name.

  • The reliable or buffered operation cannot be one-way; in other words, you cannot annotate the implementing method with the @Oneway annotation.

Asynchronous request-response with Web Service reliable messaging

If you set a property in one of the asynchronous contexts (AsyncPreCallContext or AsyncPostCallContext), then the property must implement java.io.Serializable.

Asynchronous request-response with buffering

You must use the @ServiceClient JWS annotation in the client Web Service that invokes the buffered Web Service operation.

Conversations with Web Service reliable messaging

  • JWS conversations are not the same as reliable sequences, and are not linked in any way. You must consider the management of reliable sequences separately from the life cycle of a conversation. For example, when using reliable messaging to send messages between a client service and a reliable and conversational service, finishing the conversation does not terminate the reliable sequence. You must explicitly cause the reliable sequence to be terminated (using WsrmUtils.setFinalMessage() or other acceptable method) or allows the reliable sequence to remain active until it expires when the sequence lifetime is exceeded). For more information about reliable message sequence life cycle, see Managing the Life Cycle of the Reliable Message Sequence.

  • If you set the property WLStub.CONVERSATIONAL_METHOD_BLOCK_TIMEOUT on the stub of the client Web Service, the property is ignored because the client does not block.

  • At least one method of the reliable conversational Web Service must not be marked with the @Oneway annotation.

Conversations with asynchronous request-response

Asynchronous responses between a client conversational Web Service and any other Web Service also participate in the conversation. For example, assume WebServiceA is conversational, and it invokes WebServiceB using asynchronous request-response. Because WebServiceA is conversational the asynchronous responses from WebServiceB also participates in the same conversation.


Example of a JWS File That Implements a Reliable Conversational Web Service

The following sample JWS file implements a Web Service that is both reliable and conversational:

package examples.webservices.async_mega;

import java.io.Serializable;

import weblogic.jws.WLHttpTransport;
import weblogic.jws.Conversation;
import weblogic.jws.Policy;

import javax.jws.WebService;
import javax.jws.WebMethod;

@WebService(name="AsyncMegaPortType",
            serviceName="AsyncMegaService",
            targetNamespace="http://examples.org/")

@Policy(uri="AsyncReliableConversationPolicy.xml",
        attachToWsdl=true)

@WLHttpTransport(contextPath="asyncMega",
                 serviceUri="AsyncMegaService",
                 portName="AsyncMegaServicePort")

/**
 * Web Service that is both reliable and conversational.
 */

public class AsyncMegaServiceImpl implements Serializable {

  @WebMethod
  @Conversation (Conversation.Phase.START)
  public String start() {
    return "Starting conversation";
  }

  @WebMethod
  @Conversation (Conversation.Phase.CONTINUE)
  public String middle(String message) {
    return "Middle of conversation; the message is: " + message;
  }

  @WebMethod
  @Conversation (Conversation.Phase.FINISH)
  public String finish(String message ) {
    return "End of conversation; the message is: " + message;
  }

}

Example of Client Web Service That Asynchronously Invokes a Reliable Conversational Web Service

The following JWS file shows how to implement a client Web Service that reliably invokes the various conversational methods of the Web Service described in Example of a JWS File That Implements a Reliable Conversational Web Service; the client JWS file uses the asynchronous request-response feature as well.

package examples.webservices.async_mega;

import weblogic.jws.WLHttpTransport;
import weblogic.jws.ServiceClient;
import weblogic.jws.AsyncResponse;
import weblogic.jws.AsyncFailure;

import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.xml.rpc.Stub;

import weblogic.wsee.async.AsyncPreCallContext;
import weblogic.wsee.async.AsyncCallContextFactory;
import weblogic.wsee.async.AsyncPostCallContext;
import weblogic.wsee.reliability.WsrmUtils;

import examples.webservices.async_mega.AsyncMegaPortType;
import examples.webservices.async_mega.AsyncMegaService;
import examples.webservices.async_mega.AsyncMegaService_Impl;

import java.rmi.RemoteException;

@WebService(name="AsyncMegaClientPortType",
            serviceName="AsyncMegaClientService",
            targetNamespace="http://examples.org/")

@WLHttpTransport(contextPath="asyncMegaClient",
                 serviceUri="AsyncMegaClient",
                 portName="AsyncMegaClientServicePort")

/**
 * Client Web Service that has a conversation with the AsyncMegaService
 * reliably and asynchronously.
 */

public class AsyncMegaClientImpl {

  @ServiceClient(
     wsdlLocation="http://localhost:7001/asyncMega/AsyncMegaService?WSDL",
     serviceName="AsyncMegaService",
     portName="AsyncMegaServicePort")

  private AsyncMegaPortType port;

  @WebMethod
  public void runAsyncReliableConversation(String message) {

    AsyncPreCallContext apc = AsyncCallContextFactory.getAsyncPreCallContext();
    apc.setProperty("message", message);

    try {
      port.startAsync(apc);
      System.out.println("start method executed.");

      port.middleAsync(apc, message );
      System.out.println("middle method executed.");

      // Since this service is not conversational, any state kept in the port
      // field will be lost when this method returns. In the case of reliable
      // messaging, this state includes the ID of the reliable sequence being
      // used to send messages. The setFinalMessage method specifies
      // that this is the final message to be sent on this sequence. This
      // will allow the reliable messaging subsystem to proactively clean up
      // the reliable sequence instead of timing out.
      WsrmUtils.setFinalMessage((Stub)port);
      port.finishAsync(apc, message );
      System.out.println("finish method executed.");

    }
    catch (RemoteException e) {
      e.printStackTrace();
    }

  }

  @AsyncResponse(target="port", operation="start")
  public void onStartAsyncResponse(AsyncPostCallContext apc, String message) {
    System.out.println("-------------------");
    System.out.println("Got message " + message );
    System.out.println("-------------------");
  }

  @AsyncResponse(target="port", operation="middle")
  public void onMiddleAsyncResponse(AsyncPostCallContext apc, String message) {
    System.out.println("-------------------");
    System.out.println("Got message " + message );
    System.out.println("-------------------");
  }

  @AsyncResponse(target="port", operation="finish")
  public void onFinishAsyncResponse(AsyncPostCallContext apc, String message) {
    System.out.println("-------------------");
    System.out.println("Got message " + message );
    System.out.println("-------------------");
  }

  @AsyncFailure(target="port", operation="start")
  public void onStartAsyncFailure(AsyncPostCallContext apc, Throwable e) {
    System.out.println("-------------------");
    e.printStackTrace();
    System.out.println("-------------------");
  }

  @AsyncFailure(target="port", operation="middle")
  public void onMiddleAsyncFailure(AsyncPostCallContext apc, Throwable e) {
    System.out.println("-------------------");
    e.printStackTrace();
    System.out.println("-------------------");
  }

  @AsyncFailure(target="port", operation="finish")
  public void onFinishAsyncFailure(AsyncPostCallContext apc, Throwable e) {
    System.out.println("-------------------");
    e.printStackTrace();
    System.out.println("-------------------");
  }
}