3 Invoking Web Services Asynchronously

The following sections describe how to invoke Web services asynchronously:

Overview of Asynchronous Web Service Invocation

To support asynchronous Web services invocation, WebLogic Web services can use an asynchronous client programming model, asynchronous transport, or both.

Table 3-1 provides a description and key benefits of the asynchronous client programming model and transport types, and introduces the configuration options available to support asynchronous Web service invocation.

Note:

The method of generating a WSDL for the asynchronous Web service containing two one-way operations defined as two portTypes—one for the asynchronous operation and one for the callback operation—is not supported in the current release.

Table 3-1 Support for Asynchronous Web Service Invocation

Type Description Benefits

Client programming model

Describes the invocation semantics used to call a Web service operation: synchronous or asynchronous.

When you invoke a Web service synchronously, the invoking client application waits for the response to return before it can continue with its work. In cases where the response returns immediately, this method of invoking the Web service might be adequate. However, because request processing can be delayed, it is often useful for the client application to continue its work and handle the response later on.

By calling a Web service asynchronously, the client can continue its processing, without interruption, and be notified when the asynchronous response is returned.

To support asynchronous invocation, you generate automatically an asynchronous flavor of each operation on a Web service port using the clientgen Ant task, as described later in Building the Client Artifacts for Asynchronous Web Service Invocation. Then, you add methods in your client, including your business logic, that handle the asynchronous response or failures when it returns later on. Finally, to invoke a Web service asynchronously, rather than invoking the operation directly, you invoke the asynchronous flavor of the operation. For example, rather than invoking an operation called addNumbers directly, you would invoke addNumbersAsync instead.

Asynchronous invocation enables Web service clients to initiate a request to a Web service, continue processing without blocking, and receive the response at some point in the future.

Transport

There are three transport types: asynchronous client transport, MakeConnection transport, and synchronous transport. For a comparison of each transport type, see Table 3-2.

Asynchronous client transport and MakeConnection transport deliver the following key benefits:

  • Improves fault tolerance in the event of network outages.

  • Enables servers to absorb more efficiently spikes in traffic.

Configuration

Configure Web service persistence and buffering (optional) to support asynchronous Web service invocation.

For more information, see Configuring Your Servers for Asynchronous Web Service Invocation.

Benefits of configuring the Web service features include:

  • Persistence supports long running requests and provides the ability to survive server restarts.

  • Buffering enables all requests to a Web service to be handled asynchronously.


Table 3-2 summarizes the transport types that WebLogic Server supports for invoking a Web service asynchronously (or synchronously, if configured) from a Web service client.

Table 3-2 Transport Types for Invoking Web Services Asynchronously

Transport Types Description

Asynchronous Client Transport

Provides a scalable asynchronous client programming model through the use of an addressable client-side asynchronous response endpoint and WS-Addressing.

Asynchronous client transport decouples the delivery of the response message from the initiating transport request used to send the request message. The response message is sent to the asynchronous response endpoint using a new connection originating from the Web service. The client correlates request and response messages through WS-Addressing headers.

Asynchronous client transport provides improved fault tolerance and enables servers to better absorb spikes in server load.

For details about using asynchronous client transport, see Developing Scalable Asynchronous JAX-WS Clients (Asynchronous Client Transport).

Asynchronous client transport supports the following programming models:

MakeConnection Transport

Enables asynchronous Web service invocation from behind a firewall using Web Services MakeConnection 1.1 or 1.0.

MakeConnection is a client polling mechanism that provides an alternative to asynchronous client transport. As with asynchronous client transport, MakeConnection enables the decoupling of the response message from the initiating transport request used to send the request message. However, unlike asynchronous client transport which requires an addressable asynchronous response endpoint to forward the response to, with MakeConnection typically the sender of the request message is non-addressable and unable to accept an incoming connection. For example, when the sender is located behind a firewall.

MakeConnection transport provides improved fault tolerance and enables servers to better absorb spikes in server load.

For details about MakeConnection transport, see Using Asynchronous Web Service Clients From Behind a Firewall (MakeConnection).

MakeConnection transport is recommended as a best practice when using asynchronous invocation from behind a firewall due to its scalability and ability to survive a JVM restart. It supports the following programming models:

Use of MakeConnection transport with AsyncClientHandlerFeature is recommended as a best practice when using asynchronous invocation due to its scalability and ability to survive a JVM restart.

Synchronous Transport

Provides support for synchronous and asynchronous Web service invocation with very limited support for WS-Addressing. For details, see Using the JAX-WS Reference Implementation.

Synchronous transport is recommended when using synchronous invocation. It can be used for asynchronous invocation, as well, though this is not considered a best practice. It supports the following programming models:


Steps to Invoke Web Services Asynchronously

This section describes the steps required to invoke Web services asynchronously.

It is assumed that you have set up an Ant-based development environment and that you have a working build.xml file to which you can add targets for running the jwsc Ant task and deploying the Web services. For more information, see Getting Started With JAX-WS Web Services for Oracle WebLogic Server.

Table 3-3 Steps to Invoke Web Services Asynchronously

#
Step Description

1

Configure Web service persistence to support asynchronous Web service invocation.

Configure Web service persistence on the servers hosting the Web service and client to retain context information required for processing a message at the Web service or client. For more information, see Configuring Your Servers for Asynchronous Web Service Invocation.

Note: This step is not required if you are programming the Web service client using the standard JAX-WS RI implementation and synchronous transport (in Step 3), as described in Using the JAX-WS Reference Implementation.

2

Configure Web service buffering to enable the Web service to process requests asynchronously. (Optional)

This step is optional. To configure the Web service to process requests asynchronously, configure buffering on the server hosting the Web service. Buffering enables you to store messages in a JMS queue for asynchronous processing by the Web service. For more information, see Configuring Your Servers for Asynchronous Web Service Invocation.

3

Build the client artifacts required for asynchronous invocation.

To generate asynchronous polling and asynchronous callback handler methods in the service endpoint interface, create an external binding declarations that enables asynchronous mappings and pass the bindings file as an argument to the clientgen when compiling the client. See Building the Client Artifacts for Asynchronous Web Service Invocation.

4

Implement the Web service client based on the transport and programming model required.

Refer to one of the following sections based on the transport and programming model required:

When using Web services in a cluster, review the guidelines described in Clustering Considerations for Asynchronous Web Service Messaging.

5

Compile the Web service client and package the client artifacts.

For more information, see "Compiling and Running the Client Application" in Getting Started With JAX-WS Web Services for Oracle WebLogic Server.

6

Deploy the Web service client.

See "Deploying and Undeploying WebLogic Web Services" in Getting Started With JAX-WS Web Services for Oracle WebLogic Server.

7

Monitor the Web service client.

You can monitor runtime information for clients that invoke Web services asynchronously, such as number of invocations, errors, faults, and so on, using the Administration Console or WLST. See Monitoring Asynchronous Web Service Invocation.


Configuring Your Servers for Asynchronous Web Service Invocation

Note:

This step is not required if you are programming the Web service client using the standard JAX-WS RI implementation and synchronous transport, as described in Using the JAX-WS Reference Implementation.

To support asynchronous Web service invocation, you need to configure the features defined in the following table on the servers to which the Web service and client are deployed.

Table 3-4 Configuration for Asynchronous Web Service Invocation

Feature Description

Persistence

Web service persistence is used to save the following types of information:

  • Client identity and properties

  • SOAP message, including its headers and body

  • Context properties required for processing the message at the Web service or client (for both asynchronous and synchronous messages)

The MakeConnection transport protocol makes use of Web service persistence as follows:

  • Web service persistence configured on the MC Receiver (Web service) persists response messages that are awaiting incoming MakeConnection messages for the MakeConnection anonymous URI to which they are destined. Messages are persisted until either they are returned as a response to an incoming MakeConnection message or the message reaches the maximum lifetime for a persistent store object, resulting in the message being cleaned from the store.

  • Web service persistence configured on the MC Initiator (Web service client) is used with the asynchronous client handler feature to recover after a VM restart.

You can configure Web service persistence using the Configuration Wizard to extend the WebLogic Server domain using a Web services-specific extension template. Alternatively, you can configure the resources required for these advanced features using the Oracle WebLogic Administration Console or WLST. For information about configuring Web service persistence, see Configuring Web Service Persistence for Web Service Clients. For information about the APIs available for persisting client and message information, see Propagating Request Context to the Response.

Message buffering

When a buffered operation is invoked by a client, the request is stored in a JMS queue and WebLogic Server processes it asynchronously. If WebLogic Server goes down while the request is still in the queue, it will be processed as soon as WebLogic Server is restarted. Message buffering is configured on the server hosting the Web service. For configuration information, see Chapter 7, "Configuring Message Buffering for Web Services".

Note: Message buffering is enabled automatically on the Web service client.


Building the Client Artifacts for Asynchronous Web Service Invocation

Using the WebLogic Server client-side tooling (for example, clientgen), you can generate automatically the client artifacts required for asynchronous Web service invocation. Specifically, the following artifacts are generated:

  • Service endpoint interfaces for invoking the Web service asynchronously with or without a per-request asynchronous callback handler. For example, if the Web service defined the following method:

    public int addNumbers(int opA, int opB) throws MyException
    

    Then the following methods will be generated:

    public Future<?> addNumbersAsync(int opA, int opB,
                      AsyncHandler<AddNumbersResponse>)
    public Response<AddNumbersResponse> addNumbersAsync(int opA, int opB)
    
  • Asynchronous handler interface for implementing a handler and setting it on the port using AsyncClientHandlerFeature. The asynchronous handler interface is named as follows: portInterfaceNameAsyncHandler, where portInterfaceName specifies the name of the port interface.

    For example, for a Web service with a port type name AddNumbersPortType, an asynchronous handler interface named AddNumbersPortTypeAsyncHandler is generated with the following method:

    public void onAddNumbersResponse(Response<AddNumbersResponse>)
    

    The AsyncClientHandlerFeature is described later, in Developing the Asynchronous Handler Interface.

To generate asynchronous client artifacts in the service endpoint interface when the WSDL is compiled, enable the jaxws:enableAsyncMapping binding declaration in the WSDL file.

Alternatively, you can create an external binding declarations file that contains all binding declarations for a specific WSDL or XML Schema document. Then, pass the binding declarations file to the <binding> child element of the wsdlc, jwsc, or clientgen Ant task. For more information, see "Creating an External Binding Declarations File Using JAX-WS Binding Declarations" in Getting Started With JAX-WS Web Services for Oracle WebLogic Server.

The following provides an example of a binding declarations file (jaxws-binding.xml) that enables the jaxws:enableAsyncMapping binding declaration:

<bindings
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    wsdlLocation="AddNumbers.wsdl"
    xmlns="http://java.sun.com/xml/ns/jaxws">
    <bindings node="wsdl:definitions">
        <package name="examples.webservices.async"/>
        <enableAsyncMapping>true</enableAsyncMapping>
    </bindings>
</bindings>

Then, to update the build.xml file to generate client artifacts necessary to invoke a Web service operation asynchronously:

  1. Use the taskdef Ant task to define the full classname of the clientgen Ant tasks.

  2. Add a target that includes a reference to the external binding declarations file containing the asynchronous binding declaration, as defined above. In this case, the clientgen Ant task generates both synchronous and asynchronous flavors of the Web service operations in the JAX-WS stubs.

For example:

<taskdef name="clientgen"
    classname="weblogic.wsee.tools.anttasks.ClientGenTask" />

<target name="build_client">

<clientgen
      type="JAXWS"
      wsdl="AddNumbers.wsdl"
      destDir="${clientclasses.dir}"
      packageName="examples.webservices.async.client">
      <binding file="jaxws-binding.xml" />
    </clientgen>
    <javac
      srcdir="${clientclass-dir}" destdir="${clientclass-dir}"
      includes="**/*.java"/>
    <javac
      srcdir="src" destdir="${clientclass-dir}"
      includes="examples/webservices/async/client/**/*.java"/>

</target>

Developing Scalable Asynchronous JAX-WS Clients (Asynchronous Client Transport)

The asynchronous client transport feature provides a scalable asynchronous client programming model. Specifically, this feature:

  • Publishes a client-side asynchronous response endpoint, shown in Figure 3-1.

  • Creates and publishes a service implementation that invokes the requested asynchronous handler implementation.

  • Automatically adds WS-Addressing non-anonymous ReplyTo headers to all non-one-way, outbound messages. This header references the published response endpoint.

  • Correlates asynchronous request and response messages using the facilities listed above.

When the asynchronous client transport feature is enabled, all other JAX-WS client programming models (such as asynchronous polling, callback handler, dispatch, and so on) continue to be supported. Synchronous Web service operations will, by default, use synchronous transport, unless explicitly configured to use asynchronous client transport feature when enabling the feature.

The following figure shows the message flow used by the asynchronous client transport feature.

Figure 3-1 Asynchronous Client Transport Feature

Surrounding text describes Figure 3-1 .

As shown in the previous figure:

  1. The client enables the asynchronous client transport feature on the client proxy and invokes an asynchronous Web service operation.

  2. The Web service operation is invoked via the client proxy.

  3. The Web service processes the request and sends a response message (at some time in the future) back to the client. The response message is sent to the client's asynchronous response endpoint. The address of the asynchronous response endpoint is maintained in the WS-Addressing headers.

  4. The response message is forwarded to the appropriate client via the client proxy.

  5. The client asynchronous handler is invoked to handle the response message.

The following sections describe how to develop scalable asynchronous JAX-WS clients using asynchronous client transport:

Enabling and Configuring the Asynchronous Client Transport Feature

Note:

The MakeConnection and asynchronous client transport features are mutually exclusive. If you attempt to enable both features on the same Web service client, an error is returned. For more information about MakeConnection, see Using Asynchronous Web Service Clients From Behind a Firewall (MakeConnection).

To enable the asynchronous client transport feature on a client, pass an instance of weblogic.jws.jaxws.client.async.AsyncClientTransportFeature as a parameter when creating the Web service proxy or dispatch. The following sections describe how to enable and configure the asynchronous client transport feature on a client:

The asynchronous response endpoint described by the AsyncClientTransportFeature is used by all client instances that share the same client ID and is in effect from the time the first client instance using the client ID is published. The asynchronous response endpoint remains published until the client ID is explicitly disposed or the container for the client is deactivated (for example, the host Web application or EJB is undeployed). For more information about managing the client ID, see "Managing Client Identity" in Getting Started With JAX-WS Web Services for Oracle WebLogic Server.

The asynchronous response endpoint address is generated automatically using the following format:

http://contextAddress:port/context/targetPortResponse

In the above:

  • contextAddress:port—Specifies one of the following:

    • If clustered application, cluster address and port.

    • If not clustered application, default WebLogic Server address and port for the selected protocol.

    • If no default address is defined, first network channel address for the given protocol. For more information about network channels, see "Configuring Network Resources" in Configuring Server Environments for Oracle WebLogic Server.

  • context—Current servlet context, if running within an existing context. Otherwise, a new context named by the UUID and scoped to the application.

  • targetPortResponse—Port name of the service accessed by the client appended by Response.

You can configure the asynchronous client transport feature, as described in the following sections:

For more information about the AsyncClientTransportFeature() constructor formats, see the WebLogic Server Javadoc.

Configuring the Address of the Asynchronous Response Endpoint

You can configure an address for the asynchronous response endpoint by passing it as an argument to the AsyncClientTransportFeature, as follows:

String responseAddress = "http://myserver.com:7001/myReliableService/myClientCallback";
AsyncClientTransportFeature asyncFeature = new AsyncClientTransportFeature(responseAddress);
BackendService port = _service.getBackendServicePort(asyncFeature);

The specified address must be a legal address for the server or cluster (including the network channels or proxy addresses). Ephemeral ports are not supported. The specified context must be scoped within the current application or refer to an unused context; it cannot refer to a context that is scoped to another deployed application, otherwise an error is thrown.

The following tables summarizes the constructors that can be used to configure the address of the asynchronous response endpoint.

Table 3-5 Constructors for Configuring the Address of the Asynchronous Response Endpoint

Constructor Description

AsyncClientTransportFeature(java.lang.String address)

Configures the address of the asynchronous response endpoint.

AsyncClientTransportFeature(java.lang.String address, boolean doPublish)

Configures the following:

AsyncClientTransportFeature(java.lang.String address, boolean doPublish, boolean useAsyncWithSyncInvoke)

Configures the following:


Configuring the ReplyTo and FaultTo Headers of the Asynchronous Response Endpoint

You can configure the address to use for all outgoing ReplyTo and FaultTo headers of type javax.xml.ws.wsaddressing.W3CEndpointReference for the asynchronous response endpoint by passing them as arguments to the AsyncClientTransportFeature.

For example, to configure only the ReplyTo header address:

W3CEndpointReference replyToAddress = "http://myserver.com:7001/myReliableService/myClientCallback";
AsyncClientTransportFeature asyncFeature = new AsyncClientTransportFeature(replyToAddress);
BackendService port = _service.getBackendServicePort(asyncFeature);

To configure both the ReplyTo and FaultTo header addresses:

W3CEndpointReference replyToAddress = "http://myserver.com:7001/myReliableService/myClientCallback";
W3CEndpointReference faultToAddress = "http://myserver.com:7001/myReliableService/FaultTo";
AsyncClientTransportFeature asyncFeature = new AsyncClientTransportFeature(replyToAddress, faultToAddress);
BackendService port = _service.getBackendServicePort(asyncFeature);

The following tables summarizes the constructors that can be used to configure the endpoint reference address for the outgoing ReplyTo and FaultTo headers.

Table 3-6 Constructors for Configuring the ReplyTo and FaultTo Headers

Constructor Description

AsyncClientTransportFeature(javax.xml.ws.wsaddressing.W3CEndpointReference replyTo)

Configures the endpoint reference address for the outgoing ReplyTo headers.

AsyncClientTransportFeature(javax.xml.ws.wsaddressing.W3CEndpointReference replyTo, boolean doPublish)

Configures the following:

AsyncClientTransportFeature(javax.xml.ws.wsaddressing.W3CEndpointReference replyTo, boolean doPublish, boolean useAsyncWithSyncInvoke)

Configures the following:

AsyncClientTransportFeature(javax.xml.ws.wsaddressing.W3CEndpointReference replyTo, javax.xml.ws.wsaddressing.W3CEndpointReference faultTo)

Configures the endpoint reference address for the outgoing ReplyTo and FaultTo headers

AsyncClientTransportFeature(javax.xml.ws.wsaddressing.W3CEndpointReference replyTo, javax.xml.ws.wsaddressing.W3CEndpointReference faultTo, boolean doPublish)

Configures the following:

AsyncClientTransportFeature(javax.xml.ws.wsaddressing.W3CEndpointReference replyTo, javax.xml.ws.wsaddressing.W3CEndpointReference faultTo, boolean doPublish, boolean useAsyncWithSyncInvoke)

Configures the following:


Configuring the Context Path of the Asynchronous Response Endpoint

When a client is running within a servlet or Web application-based Web service, it can use its ServletContext and context path to construct the asynchronous response endpoint. You pass the information as an argument to the AsyncClientTransportFeature, as follows:

  • When running inside a servlet:

    AsyncClientTransportFeature asyncFeature =
          new AsyncClientTransportFeature(getServletContext());
    
  • When running inside a Web service or an EJB-based Web service:

    import com.sun.xml.ws.api.server.Container;
    ...
    Container c = ContainerResolver.getInstance().getContainer();
    ServletContext servletContext = c.getSPI(ServletContext.class);
    AsyncClientTransportFeature asyncFeature =
        new AsyncClientTransportFeature(servletContext);
    

The specified context must be scoped within the current application or refer to an unused context; it cannot refer to a context that is scoped to another deployed application.

Note:

When you use the empty constructor for AsyncClientTransportFeature, the Web services runtime attempts to discover the container in which the current feature was instantiated and publish the endpoint using any available container context.

The following tables summarizes the constructors that can be used to configure the context path of the asynchronous response endpoint.

Table 3-7 Constructors for Configuring the Context Path of the Asynchronous Response Endpoint

Constructor Description

AsyncClientTransportFeature(java.lang.Object context)

Configures the context path of the asynchronous response endpoint.

AsyncClientTransportFeature(java.lang.Object context, boolean useAsyncWithSyncInvoke)

Configures the following:


Publishing the Asynchronous Response Endpoint

You can configure whether to publish the asynchronous response endpoint by passing the doPublish boolean value as an argument to AsycnClientTransportFeature() when configuring the following properties:

  • Address of the asynchronous response endpoint. See Table 3-5.

  • ReplyTo and FaultTo headers. See Table 3-6.

  • Context path of the asynchronous response endpoint. See Table 3-7.

If doPublish is set to false, then the asynchronous response endpoint is not published automatically, but WS-Addressing headers will be added to outbound non-one-way messages. This scenario supports the following programming models:

  • Asynchronous polling (with no attempt to access the Response object)

  • Dispatch asynchronous polling (with no attempt to access the Response object)

  • Dispatch one-way invocation

  • Synchronous invocation using synchronous transport option (default)

For all other asynchronous programming models, the availability of a asynchronous response endpoint is required and the Web service client is responsible for publishing it prior to making outbound requests if doPublish is set to false.

The following example configures the asynchronous response endpoint address and publishes the asynchronous response endpoint:

String responseAddress = "http://localhost:7001/myReliableService/myReliableResponseEndpoint";
boolean doPublish = true;
AsyncClientTransportFeature asyncFeature = 
      new AsyncClientTransportFeature(responseAddress, doPublish);
BackendService port = _service.getBackendServicePort(asyncFeature);

Configuring Asynchronous Client Transport for Synchronous Operations

You can enable or disable asynchronous client transport for synchronous operations using the useAsyncWithSyncInvoke boolean flag when configuring the following properties:

  • Address of the asynchronous response endpoint. See Table 3-5.

  • ReplyTo and FaultTo headers. See Table 3-6.

  • Context path of the asynchronous response endpoint. See Table 3-7.

The following example configures the asynchronous response endpoint address and enables use of asynchronous client transport for synchronous operations:

String responseAddress = "http://localhost:7001/myReliableService/myReliableResponseEndpoint";
boolean useAsyncWithSyncInvoke = true;
AsyncClientTransportFeature asyncFeature = 
      new AsyncClientTransportFeature(responseAddress, useAsyncWithSyncInvoke);
BackendService port = _service.getBackendServicePort(asyncFeature);

Developing the Asynchronous Handler Interface

Note:

If you set a single asynchronous handler instance on the port, as described in this section, and subsequently attempt to configure a per-request asynchronous handler, as described in Using the JAX-WS Reference Implementation, then a runtime exception is returned.

As described in Building the Client Artifacts for Asynchronous Web Service Invocation, the asynchronous handler interface, weblogic.jws.jaxws.client.async.AsyncClientHandlerFeature, sets a single asynchronous handler instance on the port rather than on a per-request basis.

For example, when you build the client classes using clientgen, as described in Building the Client Artifacts for Asynchronous Web Service Invocation, the asynchronous handler interface is generated, as shown below.

Example 3-1 Example of the Asynchronous Handler Interface

import javax.xml.ws.Response;
 
 
/**
 * This class was generated by the JAX-WS RI.
 * Oracle JAX-WS 2.1.5
 * Generated source version: 2.1
 *
 */
public interface BackendServiceAsyncHandler {
 
 
    /**
     *
     * @param response
     */
    public void onDoSomethingResponse(Response<DoSomethingResponse> response);
 
}

The asynchronous handler interface is generated as part of the same package as the port interface and represents the methods required to accept responses for any operation defined on the service. You can import and implement this interface in your client code to provide a way to receive and process asynchronous responses in a strongly-typed manner.

To set a single asynchronous handler instance on the port, pass an instance of the weblogic.jws.jaxws.client.async.AsyncClientHandlerFeature as a parameter when creating the Web service proxy or dispatch. You specify the name of the asynchronous handler that will be invoked when a response message is received.

The following example shows how to develop an asynchronous handler interface. The example demonstrates how to initialize the AsyncClientHandlerFeature to connect the asynchronous handler implementation to the port used to make invocations on the backend service. This example is excerpted from Example 2-2, "Asynchronous Web Service Client Best Practices Example".

Example 3-2 Example of Developing the Asynchronous Handler Interface

import weblogic.jws.jaxws.client.async.AsyncClientHandlerFeature;
...
    BackendServiceAsyncHandler handler = new BackendServiceAsyncHandler() {
        public void onDoSomethingResponse(Response<DoSomethingResponse> res) {
            // ... Handle Response ...
            try {
                DoSomethingResponse response = res.get();
                _lastResponse = response.getReturn();
                System.out.println("Got async response: " + _lastResponse);
            } catch (Exception e) {
                _lastResponse = e.toString();
                e.printStackTrace();
              }
        }
      };
    AsyncClientHandlerFeature handlerFeature = new AsyncClientHandlerFeature(handler);
    features.add(handlerFeature);
    _features = features.toArray(new WebServiceFeature[features.size()]);
    BackendService anotherPort = _service.getBackendServicePort(_features);
...
    // Make the invocation. Our asynchronous handler implementation (set 
    // into the AsyncClientHandlerFeature above) receives the response.
    String request = "Dance and sing";
    System.out.println("Invoking DoSomething asynchronously with request: " + request);
    anotherPort.doSomethingAsync(request);
 

Propagating User-defined Request Context to the Response

The weblogic.wsee.jaxws.JAXWSProperties API defines the following properties that enables users to propagate user-defined request context information to the response message, without relying on the asynchronous handler instance state.

The asynchronous handler instance may be created at any time; for example, if the client's server goes down and is restarted. Therefore, storing request context in the asynchronous handler interface will not be useful.

The JAXWSProperties properties are defined in the following table.

Table 3-8 Properties Supported by the JAXWSProperties API

This property . . . Specifies . . .

MESSAGE_ID

Message ID for the request. The client can set this property on the request context to override the auto-generation of the per-request Message ID header.

PERSISTENT_CONTEXT

Context properties required by the client or the communication channels. Web service clients can persist context properties, as long as they are Serializable, for the request message. These properties will be available in the response context map available from the Response object when the asynchronous handler is invoked. For more information, see Propagating Request Context to the Response.

RELATES_TO

Message ID to which the response correlates.

REQUEST_TIMEOUT

For synchronous operations using asynchronous client transport, maximum amount of time to block and wait for a response. This property default to 0 indicating no timeout.


In addition, Web service clients can persist context properties, as long as they are Serializable, for the request message. Context properties can include those required by the client or the communication channels. Message properties can be stored as part of the weblogic.wsee.jaxws.JAXWSProperties.PERSISTENT_CONTEXT Map property and retrieved after the response message is returned. For complete details, see Propagating Request Context to the Response.

Using Asynchronous Web Service Clients From Behind a Firewall (MakeConnection)

Web Services MakeConnection is a client polling mechanism that provides an alternative to asynchronous client transport, typically to provide support for clients that are behind a firewall. WebLogic Server supports WS-Make Connection version 1.1, as described in the MakeConnection specification at: http://docs.oasis-open.org/ws-rx/wsmc/200702, and is backwards compatible with version 1.0.

Specifically, MakeConnection:

  • Enables the decoupling of the response message from the initiating transport request used to send the request message (similar to asynchronous client transport).

  • Supports Web service clients that are non-addressable and unable to accept an incoming connection (for example, clients behind a firewall).

  • Enables a Web service client to act as an MC-Initiator and the Web service to act as an MC-Receiver, as defined by the WS-MakeConnection specification.

The following figure, borrowed from the Web Services MakeConnection specification, shows a typical MakeConnection message flow.

Figure 3-2 MakeConnection Message Flow

Description of Figure 3-2 follows
Description of "Figure 3-2 MakeConnection Message Flow"

As shown in the previous figure, the MakeConnection message flow is as follows:

  1. The getQuote() request message is sent from the Web service client (MC Initiator) to the Web service (MC Receiver). The ReplyTo header contains a MakeConnection anonymous URI that specifies the UUID for the MC Initiator.

    The MC Receiver receives the getQuote() message. The presence of the MakeConnection anonymous URI in the ReplyTo header indicates that the response message can be sent back on the connection's back channel or the client will use MakeConnection polling to retrieve it.

  2. The MC Receiver closes the connection by sending back an empty response (HTTP 202) to the MC Initiator.

    Upon receiving an empty response, the MC Initiator initializes and starts its polling mechanism to enable subsequent polls to be sent to the MC Receiver. Specifically, the MC Initiator polling mechanism starts a timer with expiration set to the interval configured for the time between successive polls.

  3. Upon timer expiration, the MC Initiator sends a MakeConnection message to the MC Receiver with the same MakeConnection anonymous URI information in its message.

  4. As the MC Receiver has not completed process the getQuote() operation, no response is available to send back to the MC Initiator. As a result, the MC Receiver closes the connection by sending back another empty response (HTTP 202) indicating that no responses are available at this time.

    Upon receipt of the empty message, the MC Initiator restarts the timer for the MakeConnection polling mechanism.

    Before the timer expires, the getQuote() operation completes. Since the original request contained a MakeConnection anonymous URI in its ReplyTo header, the MC Receiver stores the response and waits to receive the next MakeConnection message with a matching address.

  5. Upon timer expiration, the MC Initiator sends a MakeConnection message to the MC Receiver with the same MakeConnection anonymous URI information in its message.

  6. Upon receipt of the MakeConnection message, the MC Receiver retrieves the stored response message and sends it as a response to the received MakeConnection message.

    The MC Initiator receives the response message and terminates the MakeConnection polling mechanism.

MakeConnection transport is recommended when using asynchronous invocation from behind a firewall. For a list of programming models supported, see Table 3-2, "Transport Types for Invoking Web Services Asynchronously".

The following sections describe how to enable and configure MakeConnection on a Web service and client:

Enabling and Configuring MakeConnection on a Web Service

MakeConnection can be enabled by attaching a MakeConnection policy assertion to the Web service and then calling its methods from a client using the standard JAX-WS client APIs. A policy can be attached to a Web service in one of the following ways:

  • Adding an @Policy annotation to the JWS file. You can attach a MakeConnection policy at the class level only.

  • Adding reference to the policy to the Web service WSDL.

The following sections describe the steps required to enable MakeConnection on a Web service:

Creating the Web Service MakeConnection WS-Policy File (Optional)

A WS-Policy file is an XML file that contains policy assertions that comply with the WS-Policy specification. In this case, the WS-Policy file contains Web service MakeConnection policy assertions.

WebLogic Server includes pre-packaged WS-Policy files that contain typical MakeConnection assertions that you can use if you do not want to create your own WS-Policy file. The pre-packaged WS-Policy files that support MakeConnection are listed in the following table. In some cases, both reliable messaging and MakeConnection are enabled by the policy. For more information, see Appendix A, "Pre-packaged WS-Policy Files for Web Services Reliable Messaging and MakeConnection".

Note:

You can attach MakeConnection policies at the class level only; you cannot attach the MakeConnection policies at the method level.

Table 3-9 Pre-packaged WS-Policy Files That Support MakeConnection

Pre-packaged WS-Policy File Description

Mc1.1.xml

Enables MakeConnection support on the Web service and specifies usage as optional on the Web service client. The WS-Policy 1.5 protocol is used. See Mc1.1.xml (WS-Policy File).

Mc.xml

Enables MakeConnection support on the Web service and specifies usage as optional on the Web service client. The WS-Policy 1.2 protocol is used. See Mc.xml (WS-Policy File).

Reliability1.2_ExactlyOnce_WithMC1.1.xml

Specifies policy assertions related to quality of service. It enables MakeConnection support on the Web service and specifies usage as optional on the Web service client. See Reliability1.2_ExactlyOnce_WithMC1.1.xml (WS-Policy File).

Reliability1.2_SequenceSTR.xml

Specifies that in order to secure messages in a reliable sequence, the runtime will use the wsse:SecurityTokenReference that is referenced in the CreateSequence message. It enables MakeConnection support on the Web service and specifies usage as optional on the Web service client. See Reliability1.2_SequenceSTR.xml (WS-Policy File).

Reliability1.0_1.2.xml

Combines 1.2 and 1.0 WS-Reliable Messaging policy assertions. The policy assertions for the 1.2 version MakeConnection support on the Web service and specifies usage as optional on the Web service client. This sample relies on smart policy selection to determine the policy assertion that is applied at runtime. See Reliability1.0_1.2.xml (WS-Policy File).


You can use one of the pre-packaged MakeConnection WS-Policy files included in WebLogic Server; these files are adequate for most use cases. You cannot modify the pre-packaged files. If the values do not suit your needs, you must create a custom WS-Policy file. For example, you may wish to configure support of MakeConnection as required on the Web service client side. The MakeConnection policy assertions conform to the WS-PolicyAssertions specification at http://www.ibm.com/developerworks/library/specification/ws-polas.

To create a custom WS-Policy file that contains MakeConnection assertions, use the following guidelines:

  • The root element of a WS-Policy file is always <wsp:Policy>.

  • To configure Web service MakeConnection, you simply add a <wsmc:MCSupported> child element to define the Web service MakeConnection support.

  • The <wsmc:MCSupported> child element contains one policy attribute, Optional, that specifies whether MakeConnection must be configured on the Web service client. This attribute can be set to true or false, and is set to true by default. If set to false, then use of MakeConnection is required and both the ReplyTo and FaultTo (if specified) headers must contain MakeConnection anonymous URIs.

The following example enables MakeConnection on the Web service and specifies that MakeConnection must be enabled on the Web service client. In this example, the WS-Policy 1.5 protocol is used.

<?xml version="1.0"?>
<wsp15:Policy  xmlns:wsp15="http://www.w3.org/ns/ws-policy" 
  xmlns:wsmc="http://docs.oasis-open.org/ws-rx/wsmc/200702">
  <wsmc:MCSupported wsp15:Optional="false" />
</wsp15:Policy>

Programming the JWS File to Enable MakeConnection

This section describes how to enable MakeConnection on the Web service using a pre-packaged or custom MakeConnection WS-Policy file. For information about creating a custom policy file, see Creating the Web Service MakeConnection WS-Policy File (Optional).

Use the @Policy annotation in your JWS file to specify that the Web service has a WS-Policy file attached to it that contains MakeConnection assertions. WebLogic Server delivers a set of pre-packaged WS-Policy files, as described in Appendix A, "Pre-packaged WS-Policy Files for Web Services Reliable Messaging and MakeConnection".

Refer to the following guidelines when using the @Policy annotation for Web service reliable messaging:

  • You can attach the MakeConnection policy at the class level only; you cannot attach the MakeConnection policy at the method level.

  • Use the uri attribute to specify the build-time location of the policy file, as follows:

    • If you have created your own WS-Policy file, specify its location relative to the JWS file. For example:

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

      In this example, the McPolicy.xml file is located in the same directory as the JWS file.

    • To specify one of the pre-packaged WS-Policy files or a WS-Policy file that is packaged in a shared Java EE library, use the policy: prefix along with the name and path of the policy file. This syntax tells the jwsc Ant task at build-time not to look for an actual file on the file system, but rather, that the Web service will retrieve the WS-Policy file from WebLogic Server at the time the service is deployed.

      Note:

      Shared Java EE libraries are useful when you want to share a WS-Policy file with multiple Web services that are packaged in different Enterprise applications. As long as the WS-Policy file is located in the META-INF/policies or WEB-INF/policies directory of the shared Java EE library, you can specify the policy file in the same way as if it were packaged in the same archive at the Web service. See "Creating Shared Java EE Libraries and Optional Packages" in Developing Applications for Oracle WebLogic Server for information about creating libraries and setting up your environment so the Web service can locate the policy files.
    • To specify that the policy file is published on the Web, use the http: prefix along with the URL, as shown in the following example:

      @Policy(uri="http://someSite.com/policies/mypolicy.xml"
              attachToWsdl=true)
      
  • Set the attachToWsdl attribute of the @Policy annotation to specify whether the policy file should be attached to the WSDL file that describes the public contract of the Web service. Typically, you want to publicly publish the policy so that client applications know the reliable messaging capabilities of the Web service. For this reason, the default value of this attribute is true.

For more information about the @Policy annotation, see "weblogic.jws.Policy" in WebLogic Web Services Reference for Oracle WebLogic Server.

The following example shows a simple JWS file that enables MakeConnection; see the explanation after the example for coding guidelines that correspond to the Java code in bold.

package examples.webservices.async

import javax.jws.WebMethod;
import javax.jws.WebService;
import weblogic.jws.Policy; 

/**
 * Simple reliable Web Service.
 */

@WebService(name="HelloWorldPortType",
              serviceName="HelloWorldService")

@Policy(uri="McPolicy.xml", attachToWsdl=true) 
public class HelloWorldImpl {
  private static String onewaySavedInput = null;

/**
 * A one-way helloWorld method that saves the given string for later 
 * concatenation to the end of the message passed into helloWorldReturn.
 */
  @WebMethod()
  public void helloWorld(String input) {
    System.out.println(" Hello World " + input);
    onewaySavedInput = input;
   }

/**
 * This echo method concatenates the saved message from helloWorld 
 * onto the end of the provided message, and returns it.
 */
  @WebMethod()
  public String echo(String input2) {
    System.out.println(" Hello World " + input2 + onewaySavedInput);
    return input + onewaySavedInput;
  }
}

As shown in the previous example, the custom McPolicy.xml policy file is attached to the Web service at the class level, which means that the policy file is applied to all public operations of the Web service. You can attach a MakeConnection policy at the class level only; you cannot attach a MakeConnection policy at the method level.

The policy file is attached to the WSDL file. For information about the pre-packaged policies available and creating a custom policy, see Creating the Web Service MakeConnection WS-Policy File (Optional).

The echo() method has been marked with the @WebMethod JWS annotation, which means it is a public operation called echo. Because of the @Policy annotation, the operation using MakeConnection transport protocol.

Enabling and Configuring MakeConnection on a Web Service Client

Note:

The MakeConnection and asynchronous client transport features are mutually exclusive. If you attempt to enable both features on the same Web service client, an error is returned. For more information about asynchronous client transport, see Developing Scalable Asynchronous JAX-WS Clients (Asynchronous Client Transport).

It is recommended that you use the asynchronous handler feature, AsyncClientHandlerFeature when using the asynchronous callback handler programming model. For more information, see Developing the Asynchronous Handler Interface.

To enable MakeConnection on a Web service client, pass an instance of the weblogic.wsee.mc.api.McFeature as a parameter when creating the Web service proxy or dispatch. A simple example of how to enable MakeConnection is shown below.

Note:

This example will use synchronous transport for synchronous methods. To configure MakeConnection as the transport for synchronous methods, see Configuring MakeConnection as the Transport for Synchronous Methods.
package examples.webservices.myservice.client;

import weblogic.wsee.mc.api.McFeature;
...
    List<WebServiceFeature> features = new ArrayList<WebServiceFeature>();
...
    McFeature mcFeature = new McFeature();
    features.add(mcFeature);
...
    // ... Implement asynchronous handler interface as described in 
    //  Developing the Asynchronous Handler Interface. 
    // ....
    AsyncClientHandlerFeature handlerFeature = new AsyncClientHandlerFeature(handler);
    features.add(handlerFeature);
    _features = features.toArray(new WebServiceFeature[features.size()]);
    BackendService port = _service.getBackendServicePort(_features);
...
    // Make the invocation. Our asynchronous handler implementation (set 
    // into the AsyncClientHandlerFeature above) receives the response.
    String request = "Dance and sing";
    System.out.println("Invoking DoSomething asynchronously with request: " + request);
    anotherPort.doSomethingAsync(request);
..
  }
}

To configure specific features of MakeConnection on the Web service client, as described in the following sections.

Configuring the Expiration Time for Sending MakeConnection Messages

Table 3-10 defines that McFeature methods for configuring the maximum interval of time before an MC Initiator stops sending MakeConnection messages to an MC Receiver.

Table 3-10 Methods for Configuring the Expiration Time for Sending MakeConnection Messages

Method Description

String getsExpires()

Returns the expiration value currently configured.

void setExpires(String expires)

Set the expiration time.

The value specified must be a positive value and conform to the XML schema duration lexical format, PnYnMnDTnHnMnS, where nY specifies the number of years, nM specifies the number of months, nD specifies the number of days, T is the date/time separator, nH specifies the number of hours, nM specifies the number of minutes, and nS specifies the number of seconds. This value defaults to P1D (1 day).


Configuring the Polling Interval

Table 3-11 defines that McFeature methods for configuring the interval of time that must pass before a MakeConnection message is sent by an MC Initiator to an MC Receiver after the receipt of an empty response message. If the MC Initiator does not receive a non-empty response for a given message within the specified interval, the MC Initiator sends another MakeConnection message.

Table 3-11 Methods for Configuring the Polling Interval

Method Description

String getInterval()

Gets the polling interval.

void setInterval(String pollingInterval)

Set the polling interval.

The value specified must be a positive value and conform to the XML schema duration lexical format, PnYnMnDTnHnMnS, where nY specifies the number of years, nM specifies the number of months, nD specifies the number of days, T is the date/time separator, nH specifies the number of hours, nM specifies the number of minutes, and nS specifies the number of seconds. This value defaults to P0DT5S (5 seconds).


In the following example, the polling interval is set to 36 hours.

...
    McFeature mcFeature = new McFeature();
    mcFeature.setInterval("P0DT36H")
    MyService port = service.getMyServicePort(mcFeature);
...

Configuring the Exponential Backoff

Table 3-12 defines the McFeature methods for configuring the exponential backoff flag. This flag specifies whether the polling interval, described in Configuring the Polling Interval, will be adjusted using the exponential backoff algorithm. In this case, if the MC Initiator does not receive a non-empty response for the time interval specified by the polling interval, the exponential backoff algorithm is used for timing successive retransmissions by the MC Initiator, should the response not be received.

The exponential backoff algorithm specifies that successive polling intervals should increase exponentially, based on the polling interval. For example, if the polling interval is 2 seconds, and the exponential backoff element is set, successive polling intervals if the response is not received are 2, 4, 8, 16, 32, and so on.

This value defaults to false, the same polling interval is used in successive retries; the interval does not increase exponentially.

Table 3-12 Methods for Configuring the Exponential Backoff

Method Description

boolean isExponentialBackoff()

Returns a boolean value indicating whether exponential backoff is enabled.

void setExponentialBackoff(boolean backoff)

Set the exponential backoff flag. Valid values are true and false. This flag defaults to false.


In the following example, enables the exponential backoff flag.

...
    McFeature mcFeature = new McFeature();
    mcFeature.setMessageInterval(P0DT36H)
    mcFeature.setExponentialBackoff(true);
    MyService port = service.getMyServicePort(mcFeature);
...

Configuring MakeConnection as the Transport for Synchronous Methods

By default, synchronous methods use synchronous transport even when MakeConnection is enabled on the client. You can configure your client to use MakeConnection as the transport for synchronous methods. In this case, MakeConnection messages are sent by the MC Initiator based on the configured polling interval (described in Configuring the Polling Interval) until a non-empty response message is received.

To configure MakeConnection as the transport protocol to use for synchronous methods, use one of the following methods:

  • When instantiating a new McFeature() object, you can pass as a parameter a boolean value that specifies whether MakeConnection should be used as the transport protocol for synchronous methods. For example:

    ...
        McFeature mcFeature = new McFeature(true);
        MyService port = service.getMyServicePort(mcFeature);
    ...
    
  • Use the McFeature methods defined in Table 3-13. For example:

    ...
        McFeature mcFeature = new McFeature();
        mcFeature.setUseMCWithSyncInvoke(true);
        MyService port = service.getMyServicePort(mcFeature);
    ...
    

Table 3-13 Methods for Configuring Synchronous Method Support

Method Description

boolean isUseMCWithSyncInvoke()

Returns a boolean value indicating whether synchronous method support is enabled.

void setUseMCWithSyncInvoke(boolean useMCWithSyncInvoke)

Sets the synchronous method support flag. Valid values are true and false. This flag defaults to false.


You can set the maximum amount of time a synchronous method will block and wait for a response using the weblogic.wsee.jaxws.JAXWSProperties.REQUEST_TIMEOUT property. This property default to 0 indicating no timeout. For more information about setting message properties, see Propagating User-defined Request Context to the Response.

Using the JAX-WS Reference Implementation

The JAX-WS Reference Implementation (RI) supports the following programming models:

  • Asynchronous client polling through use of the java.util.concurrent.Future interface.

  • Asynchronous callback handlers on a per request basis. The calling client specifies the callback handler at invocation time. When the response is available, the callback handler is invoked to process the response.

Unlike with asynchronous client transport feature, the JAX-WS RI provides very limited support for WS-Addressing, including:

  • Manual support for adding client-side outbound WS-Addressing headers.

  • Manual support for publishing the client-side endpoint to receive responses.

  • No support for detecting incorrect client-side programming model (resulting in synchronous call hanging, for example).

  • No support for surviving a client-side or service-side restart.

The following example shows a simple client file, AsyncClient, that has a single method, AddNumbersTestDrive, that asynchronously invokes the AddNumbersAsync method of the AddNumbersService service. The Java code in bold is described following the code sample.

package examples.webservices.async.client;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import javax.xml.ws.BindingProvider;

import java.util.concurrent.Future;
import javax.xml.ws.AsyncHandler; 
import javax.xml.ws.Response;

public class AsyncClient  {

   private AddNumbersPortType port = null;
   protected void setUp() throws Exception {
      AddNumbersService service = new AddNumbersService();
      port = service.getAddNumbersPort(); 
      String serverURI = System.getProperty("wls-server");
      ((BindingProvider) port).getRequestContext().put(
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
             "http://" + serverURI + "/JAXWS_ASYNC/AddNumbersService");
   }

/**
* 
* Asynchronous callback handler
*/
   class AddNumbersCallbackHandler implements AsyncHandler<AddNumbersResponse> {
      private AddNumbersResponse output;
      public void handleResponse(Response<AddNumbersResponse> response) {
         try {
            output = response.get();
         } catch (ExecutionException e) {
             e.printStackTrace();
         } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }
      AddNumbersResponse getResponse() {
         return output;
      }
   }

   public void AddNumbersTestDrive() throws Exception {
      int number1 = 10;
      int number2 = 20;
      
      // Asynchronous Callback method
      AddNumbersCallbackHandler callbackHandler = 
         new AddNumbersCallbackHandler();
      Future<?> resp = port.addNumbersAsync(number1, number2,
         callbackHandler);
      // For the purposes of a test, block until the async call completes
      resp.get(5L, TimeUnit.MINUTES); 
      int result = callbackHandler.getResponse().getReturn(); 

      // Polling method
      Response<AddNumbersResponse> addNumbersResp = 
           port.AddNumbersAsync(number1, number2);
      while (!addNumbersResp.isDone()) {
            Thread.sleep(100);
      }
      AddNumbersResponse reply = addNumbersResp.get();
      System.out.println("Server responded through polling with: " + 
          reply.getResponseType());    
   }
}

The example demonstrates the steps to implement both the asynchronous polling and asynchronous callback handler programming models.

To implement an asynchronous callback handler:

  1. Create an asynchronous handler that implements the javax.xml.ws.AsyncHandler<T> interface (see http://download.oracle.com/javaee/5/api/javax/xml/ws/AsyncHandler.html). The asynchronous handler defines one method, handleResponse, that enables clients to receive callback notifications at the completion of service endpoint operations that are invoked asynchronously. The type should be set to AddNumberResponse.

    class AddNumbersCallbackHandler implements AsyncHandler<AddNumbersResponse> {
       private AddNumbersResponse output;
    
       public void handleResponse(Response<AddNumbersResponse> response) {
          try {
             output = response.get();
             } catch (ExecutionException e) {
               e.printStackTrace();
             } catch (InterruptedException e) {
               e.printStackTrace();
    
             }
          }
    
          AddNumbersResponse getResponse() {
             return output;
       }
    }
    
  2. Instantiate the asynchronous callback handler.

    AddNumbersCallbackHandler callbackHandler = 
       new AddNumbersCallbackHandler();
    
  3. Instantiate the AddNumbersService Web service and call the asynchronous version of the Web service method, addNumbersAsync, passing a handle to the asynchronous callback handler.

    AddNumbersService service = new AddNumbersService();
    port = service.getAddNumbersPort();
    ...
    
    Future<?> resp = port.addNumbersAsync(number1, number2,
       callbackHandler);
    

    java.util.concurrent.Future (see http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Future.html) represents the result of an asynchronous computation and provides methods for checking the status of the asynchronous task, getting the result, or canceling the task execution.

  4. Get the result of the asynchronous computation. In this example, a timeout value is specified to wait for the computation to complete.

    resp.get(5L, TimeUnit.MINUTES);
    
  5. Use the callback handler to access the response message.

    int result = callbackHandler.getResponse().getReturn();
    

To implement an asynchronous polling mechanism:

  1. Instantiate the AddNumbersService Web service and call the asynchronous version of the Web service method, addNumbersAsync.

    Response<AddNumbersResponse> addNumbersResp = 
         port.AddNumbersAsync(number1, number2);
    
  2. Sleep until a message is received.

    while (!addNumbersResp.isDone()) {
            Thread.sleep(100);
    
  3. Poll for a response.

    AddNumbersResponse reply = addNumbersResp.get();
    

Propagating Request Context to the Response

WebLogic Server provides a powerful facility that enables you to attach your business context—for example, a business-level message ID—to the request message and access it when the response is returned, regardless of what the request and response messages convey over the wire. For example, you may have a business-level message ID that will not otherwise be available in the response message. By propagating this information with the message, you can access it when the response message is returned.

Web service clients can store any request message context property, as long as it is Serializable. Message context properties can be stored as part of the weblogic.wsee.jaxws.JAXWSProperties.PERSISTENT_CONTEXT Map property and retrieved after the response message is returned.

The following example shows how to use the PERSISTENT_CONTEXT Map property to define and set a message context property.

Example 3-3 Setting Message Context Properties

import weblogic.wsee.jaxws.JAXWSProperties;
. . .
MyClientPort port = myService.getPort();
Map<String, Serializable> clientPersistProps =
    port.getRequestContext().get(JAXWSProperties.PERSISTENT_CONTEXT);
Serializable obj = <my_property>;
clientPersistProps.put("MyProperty", obj);

port.myOperationAsync(<args>, new AsyncHandler<MyOperationResponse>() {
    public void handleResponse(Response<MyOperationResponse> res) {
        try {
            // Get the actual response
            MyOperationResponse response = res.get().getReturn();

            // Get the property stored when making request. Note, this property did not get
            // passed over the wire with the reuqest. The Web services runtime stores it.
            Map<String, Serializable> clientPersistProps =
                res.getContext().get(JAXWSProperties.PERSISTENT_CONTEXT);
            Serializable obj = clientPersistProps.get("MyProperty");
            // Do something with MyProperty 
        } catch (Exception e) {
           // Error handling
        }
    }
});
...

Monitoring Asynchronous Web Service Invocation

You can monitor runtime information for clients that invoke Web services asynchronously, such as number of invocations, errors, faults, and so on, using the Administration Console. To monitor Web service clients, click on the Deployments node in the left pane and, in the Deployments table that appears in the right pane, locate the Enterprise application in which the Web service client is packaged. Expand the application by clicking the + node and click on the application module within which the Web service client is located. Click the Monitoring tab, then click the Web Service Clients tab.

If you use the MakeConnection transport protocol, you can monitor the MakeConnection anonymous endpoints for a Web service or client. For each anonymous endpoint, runtime monitoring information is displayed, such as the number of messages received, the number of messages pending, and so on.

You can customize the information that is shown in the table by clicking Customize this table.

To monitor MakeConnection anonymous endpoints for a Web service, click on the Deployments node in the left pane and, in the Deployments table that appears in the right pane, locate the Enterprise application in which the Web service is packaged. Expand the application by clicking the + node; the Web services in the application are listed under the Web Services category. Click on the name of the Web service and select Monitoring> Ports> Make Connection.

To monitor MakeConnection anonymous endpoints for a Web service client, click on the Deployments node in the left pane and, in the Deployments table that appears in the right pane, locate the Enterprise application in which the Web service client is packaged. Expand the application by clicking the + node and click on the application module within which the Web service client is located. Click the Monitoring tab, then click the Web Service Clients tab. Then click Monitoring> Servers> Make Connection.

Clustering Considerations for Asynchronous Web Service Messaging

When a Web service client runs in a cluster, you need to make special allowances to ensure that the response messages can be delivered properly to the asynchronous response endpoint for asynchronous calls. You defined the asynchronous response endpoint with the AsyncClientTransportFeature, as described in Enabling and Configuring the Asynchronous Client Transport Feature.

Consider the scenario shown in the following figure.

Figure 3-3 Clustering Scenario Resulting in an Error

Description of Figure 3-3 follows
Description of "Figure 3-3 Clustering Scenario Resulting in an Error"

In the scenario shown in the previous figure:

  • A two-node cluster hosts the client application; the nodes are named Server1 and Server2. The cluster has a simple load-balancing front-end proxy.

  • The client application is a Web application called ClientWebApp which is deployed homogeneously to the cluster. In other words, the Web application runs on both member servers in the cluster.

  • External clients of the ClientWebApp application make requests through the cluster front-end address.

Now consider the following sequence:

  1. An external client requests a page from ClientWebApp via the cluster front-end.

  2. The cluster front-end load balances the page request and sends it to the ClientWebApp on Server1.

  3. ClientWebApp on Server1 creates an instance of a Web service client, BackendServiceClient, to communicate with its back-end service, BackendService. The creation of BackendServiceClient causes an asynchronous response endpoint to be published to receive asynchronous responses whenever BackendServiceClient is used to make an asynchronous request.

  4. ClientWebApp on Server1 calls BackendServiceClient.doSomethingAsync() to perform an operation on the backend service. The address of the asynchronous response endpoint is included in the ReplyTo address. This address starts with the address of the cluster front end, and not the address of Server1.

  5. The cluster receives the response to the doSomething operation.

  6. The cluster load balances the message, this time to Server2.

  7. The message delivery fails because there is no asynchronous response endpoint on Server2 to receive the response.

You can use one of the following to resolve this problem:

  • Use a SOAP-aware cluster front-end proxy plug-in, such as WebLogic Server HttpClusterServlet. For more information, see "Configure Proxy Plug-ins" in Using Clusters for Oracle WebLogic Server. This option may not be feasible, for example if your company has standardized on a cluster front-end technology.

  • Ensure that all member servers in a cluster publish an asynchronous response endpoint so that the asynchronous response messages can be delivered to any member server and optionally forwarded to the correct server via in-place cluster routing.

To implement the second option, it is recommended that you define a singleton port instance and initialize it when the client container initializes (upon deployment). For an example illustrating the recommended method for initializing the asynchronous response endpoint in a cluster, see Example 2-2, "Asynchronous Web Service Client Best Practices Example".

Note:

You may choose to initialize the endpoint in different ways depending on the container type. For example, if the client is hosted in a Web service, a method on the Web service container could be annotated with @PostConstruct and that method could initialize the singleton port. In an EJB container, you could use the ejbCreate() method as the trigger point for creating the singleton port.