12 Developing Asynchronous Clients

This chapter describes how to develop asynchronous WebLogic web service clients using Java API for XML Web Services (JAX-WS).

This chapter includes the following sections:

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 12-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 12-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, Make Connection transport, and synchronous transport. For a comparison of each transport type, see Table 12-2.

Asynchronous client transport and Make Connection 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 12-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 12-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:

Make Connection Transport

Enables asynchronous web service invocation from behind a firewall using Web Services Make Connection 1.1 or 1.0.

Make Connection is a client polling mechanism that provides an alternative to asynchronous client transport. As with asynchronous client transport, Make Connection 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 Make Connection 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.

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

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

Make Connection 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 Make Connection 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 Developing JAX-WS Web Services.

Table 12-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.

6

Deploy the web service client.

See Deploying and Undeploying WebLogic Web Services.

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 WebLogic Server 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 12-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 Make Connection 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 Make Connection messages for the Make Connection anonymous URI to which they are destined. Messages are persisted until either they are returned as a response to an incoming Make Connection 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 Server 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 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.

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 12-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 12-1 Asynchronous Client Transport Feature

Description of Figure 12-1 follows
Description of "Figure 12-1 Asynchronous Client Transport Feature"

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 Make Connection 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 Make Connection, see Using Asynchronous Web Service Clients From Behind a Firewall (Make Connection).

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 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.

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

http://contextAddress:port/context/targetPort-AsyncResponse

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 Administering 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.

  • targetPort-AsyncResponse—Port name of the service accessed by the client appended by -AsyncResponse.

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

For more information about the AsyncClientTransportFeature() constructor formats, see the Java API Reference for Oracle WebLogic Server.

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 12-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 12-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 12-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 12-5.

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

  • Context path of the asynchronous response endpoint. See Table 12-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 12-5.

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

  • Context path of the asynchronous response endpoint. See Table 12-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 12-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 11-1.

Example 12-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 12-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 (Make Connection)

Web Services Make Connection 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-MakeConnection version 1.1, as described in the Make Connection specification at: http://docs.oasis-open.org/ws-rx/wsmc/200702, and is backwards compatible with version 1.0.

Specifically, Make Connection:

  • 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 Make Connection specification, shows a typical Make Connection message flow.

Figure 12-2 Make Connection Message Flow

Description of Figure 12-2 follows
Description of "Figure 12-2 Make Connection Message Flow"

As shown in the previous figure, the Make Connection 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 Make Connection anonymous URI that specifies the UUID for the MC Initiator.

    The MC Receiver receives the getQuote() message. The presence of the Make Connection 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 Make Connection 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 Make Connection message to the MC Receiver with the same Make Connection 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 Make Connection polling mechanism.

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

  5. Upon timer expiration, the MC Initiator sends a Make Connection message to the MC Receiver with the same Make Connection anonymous URI information in its message.
  6. Upon receipt of the Make Connection message, the MC Receiver retrieves the stored response message and sends it as a response to the received Make Connection message.

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

Make Connection transport is recommended when using asynchronous invocation from behind a firewall. For a list of programming models supported, see Table 12-2.

The following sections describe how to enable and configure Make Connection on a web service and client:

Enabling and Configuring Make Connection on a Web Service

Make Connection can be enabled by attaching a Make Connection 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 Make Connection 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 Make Connection on a web service:

Creating the Web Service Make Connection 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 Make Connection policy assertions.

WebLogic Server includes pre-packaged WS-Policy files that contain typical Make Connection 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 Make Connection are listed in the following table. In some cases, both reliable messaging and Make Connection are enabled by the policy. For more information, see Pre-packaged WS-Policy Files for Web Services Reliable Messaging and Make Connection.

Note:

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

Table 12-9 Pre-packaged WS-Policy Files That Support Make Connection

Pre-packaged WS-Policy File Description

Mc1.1.xml

Enables Make Connection 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 Make Connection 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 Make Connection 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 Make Connection 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 Make Connection 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 Make Connection 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 Make Connection as required on the web service client side. The Make Connection policy assertions conform to the WS-PolicyAssertions specification.

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

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

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

  • The <wsmc:MCSupported> child element contains one policy attribute, Optional, that specifies whether Make Connection 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 Make Connection is required and both the ReplyTo and FaultTo (if specified) headers must contain Make Connection anonymous URIs.

The following example enables Make Connection on the web service and specifies that Make Connection 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 Make Connection

This section describes how to enable Make Connection on the web service using a pre-packaged or custom Make Connection WS-Policy file. For information about creating a custom policy file, see Creating the Web Service Make Connection 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 Make Connection assertions. WebLogic Server delivers a set of pre-packaged WS-Policy files, as described in Pre-packaged WS-Policy Files for Web Services Reliable Messaging and Make Connection.

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

  • You can attach the Make Connection policy at the class level only; you cannot attach the Make Connection 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 Make Connection; 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 Make Connection policy at the class level only; you cannot attach a Make Connection 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 Make Connection 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 Make Connection transport protocol.

Enabling and Configuring Make Connection on a Web Service Client

Note:

The Make Connection 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 Make Connection 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 Make Connection is shown below.

Note:

This example will use synchronous transport for synchronous methods. To configure Make Connection as the transport for synchronous methods, see Configuring Make Connection 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 Make Connection on the web service client, as described in the following sections.

Configuring the Expiration Time for Sending Make Connection Messages

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

Table 12-10 Methods for Configuring the Expiration Time for Sending Make Connection 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 12-11 defines that McFeature methods for configuring the interval of time that must pass before a Make Connection 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 Make Connection message.

Table 12-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 12-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 12-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 Make Connection as the Transport for Synchronous Methods

By default, synchronous methods use synchronous transport even when Make Connection is enabled on the client. You can configure your client to use Make Connection as the transport for synchronous methods. In this case, Make Connection 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 Make Connection 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 Make Connection 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 12-13. For example:

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

Table 12-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://docs.oracle.com/javaee/7/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 https://docs.oracle.com/javase/8/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 12-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 WebLogic Server 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 Make Connection transport protocol, you can monitor the Make Connection 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 Make Connection 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 Make Connection 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 12-3 Clustering Scenario Resulting in an Error

Description of Figure 12-3 follows
Description of "Figure 12-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 Administering 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 11-1.

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.