Programming Advanced Features of WebLogic Web Services Using JAX-RPC

     Previous  Next    Open TOC in new window    View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

Invoking a Web Service Using Asynchronous Request-Response

The following sections describe how to invoke a Web Service using asynchronous request-response:

 


Overview of the Asynchronous Request-Response Feature

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, or in other words, use the asynchronous request-response feature of WebLogic Web Services.

You invoke a Web Service asynchronously only from a client running in a WebLogic Web Service, never from a stand-alone client application. The invoked Web Service does not change in any way, thus you can invoke any deployed Web Service (both WebLogic and non-WebLogic) asynchronously as long as the application server that hosts the Web Service supports the WS-Addressing specification.

When implementing asynchronous request-response in your client, rather than invoking the operation directly, you invoke an asynchronous flavor of the same operation. (This asynchronous flavor of the operation is automatically generated by the jwsc Ant task.) For example, rather than invoking an operation called getQuote directly, you would invoke getQuoteAsync instead. The asynchronous flavor of the operation always returns void, even if the original operation returns a value. You then include methods in your client that handle the asynchronous response or failures when it returns later on. You put any business logic that processes the return value of the Web Service operation invoke or a potential failure in these methods. You use both naming conventions and JWS annotations to specify these methods to the JWS compiler. For example, if the asynchronous operation is called getQuoteAsync, then these methods might be called onGetQuoteAsyncResponse and onGetQuoteAsyncFailure.

Note: For information about using asynchronous request-response with other asynchronous features, such as Web Service reliable messaging or buffering, see Using the Asynchronous Features Together. This section describes how to use the asynchronous request-response feature on its own.

The asynchronous request-response feature works only with HTTP; you cannot use it with the HTTPS or JMS transport.

 


Using Asynchronous Request-Response: Main Steps

The following procedure describes how to create a client Web Service that asynchronously invokes an operation in a different Web Service. The procedure shows how to create the JWS file that implements the client Web Service from scratch; if you want to update an existing JWS file, use this procedure as a guide.

For clarity, it is assumed in the procedure that:

It is further 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 generated service. For more information, see the following sections in Getting Started With WebLogic Web Services Using JAX-RPC:

When you invoke the StockQuoteClientService Web Service, which in turn invokes the StockQuoteService Web Service, the second invoke will be asynchronous rather than synchronous.

 


Configuring the Host WebLogic Server Instance for the Asynchronous Web Service

Configuring the WebLogic Server instance on which the asynchronous Web Service is deployed involves configuring JMS resources, such as JMS servers and modules, that are used internally by the Web Services runtime.

You can configure these resources manually or you can use the Configuration Wizard to extend the WebLogic Server domain using a Web Services-specific extension template. Using the Configuration Wizard greatly simplifies the required configuration steps; for details, see “Configuring Your Domain For Web Services Features” in Getting Started With WebLogic Web Services Using JAX-RPC.

Note: Alternatively, you can use WLST to configure the resources. For information about using WLST to extend the domain, see “Configuring Existing Domains” in WebLogic Scripting Tool.

If you prefer to configure the resources manually, perform the following steps.

Table 2-2 Steps to Configure Host WebLogic Server Instance Manually for the Asynchronous Web Service 
#
Step
Description
1
Invoke the Administration Console for the domain that contains the host WebLogic Server instance.
To invoke the Administration Console in your browser, enter the following URL:
http://host:port/console
where
  • host refers to the computer on which the Administration Server is running.
  • port refers to the port number where the Administration Server is listening for connection requests. The default port number for the Administration server is 7001.
See “Invoking the Administration Console” in Getting Started With WebLogic Web Services Using JAX-RPC.
2
Create a JMS Server.
Create a JMS Server. If a JMS server already exists, you can use it if you do not want to create a new one.
See “Create JMS servers” in the Administration Console Online Help.
3
Create JMS module and define queue.
Create a JMS module, and then define a JMS queue in the module. If a JMS module already exists, you can use it if you do not want to create a new one. Target the JMS queue to the JMS server you created in the preceding step. Be sure you specify that this JMS queue is local, typically by setting the local JNDI name. See “Create JMS system modules” and “Create queues in a system module” in the Administration Console Online Help.
If you want the asynchronous Web Service to use the default Web Services queue, set the JNDI name of the JMS queue to weblogic.wsee.DefaultQueue.
Clustering Considerations:
If you are using the Web Service asynchronous feature in a cluster, you must:
  • Create a local JMS queue, rather than a distributed queue, when creating the JMS queue.
  • Explicitly target this JMS queue to each server in the cluster.
4
Create a Work Manager.
Define a Work Manager named weblogic.wsee.mdb.DispatchPolicy, which is used by the asynchronous request-response feature, by default.
See “Create global Work Managers” in the Administration Console Online Help.
5
Tune your domain environment, as required. (Optional)
Review “Tuning Heavily Loaded Systems to Improve Web Service Performance” in WebLogic Server Performance and Tuning.

 


Writing the Asynchronous JWS File

The following example shows a simple JWS file that implements a Web Service called StockQuoteClient that has a single method, asyncOperation, that in turn asynchronously invokes the getQuote method of the StockQuote service. The Java code in bold is described Coding Guidelines for Invoking a Web Service Asynchronously. See Example of a Synchronous Invoke to see how the asynchronous invoke differs from a synchronous invoke of the same operation.

package examples.webservices.async_req_res;
import weblogic.jws.WLHttpTransport;
import weblogic.jws.ServiceClient;
import weblogic.jws.AsyncResponse;
import weblogic.jws.AsyncFailure;
import weblogic.wsee.async.AsyncPreCallContext;
import weblogic.wsee.async.AsyncCallContextFactory;
import weblogic.wsee.async.AsyncPostCallContext;
import javax.jws.WebService;
import javax.jws.WebMethod;
import examples.webservices.async_req_res.StockQuotePortType;
import java.rmi.RemoteException;
@WebService(name="StockQuoteClientPortType",
serviceName="StockQuoteClientService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="asyncClient",
serviceUri="StockQuoteClient",
portName="StockQuoteClientServicePort")
/**
* Client Web Service that invokes the StockQuote Service asynchronously.
*/
public class StockQuoteClientImpl {
  @ServiceClient(wsdlLocation="http://localhost:7001/async/StockQuote?WSDL",
serviceName="StockQuoteService", portName="StockQuote")
  private StockQuotePortType port;
  @WebMethod
public void asyncOperation (String symbol, String userName)
throws RemoteException {
    AsyncPreCallContext apc = AsyncCallContextFactory.getAsyncPreCallContext();
apc.setProperty("userName", userName);
    try {
port.getQuoteAsync(apc, symbol );
System.out.println("in getQuote method of StockQuoteClient WS");
     } catch (RemoteException re) {
        System.out.println("RemoteException thrown");
throw new RuntimeException(re);
}
  }
  @AsyncResponse(target="port", operation="getQuote")
public void onGetQuoteAsyncResponse(AsyncPostCallContext apc, int quote) {
// Get the userName property we set on AsyncPreCallContext
String userName = (String)apc.getProperty("userName");
System.out.println("-------------------");
System.out.println(username + " Got quote " + quote );
System.out.println("-------------------");
}
  @AsyncFailure(target="port", operation="getQuote")
public void onGetQuoteAsyncFailure(AsyncPostCallContext apc, Throwable e) {
System.out.println("-------------------");
e.printStackTrace();
System.out.println("-------------------");
}
}

Coding Guidelines for Invoking a Web Service Asynchronously

The following guidelines for invoking an operation asynchronously correspond to the Java code shown in bold in the example described in Writing the Asynchronous JWS File. These guidelines are in addition to the standard ones for creating JWS files. See Example of a Synchronous Invoke to see how the asynchronous invoke differs from a synchronous invoke of the same operation.

To invoke an operation asynchronously in your JWS file:

Note: You are not required to use the @AsyncResponse and @AsyncFailure annotations, although it is a good practice because it clears up any ambiguity and makes your JWS file clean and understandable. However, in the rare use case where you want one of the onXXX methods to handle the asynchronous response or failure from two (or more) stubs that are invoking operations from two different Web Services that have the same name, then you should explicitly NOT use these annotations. Be sure that the name of the onXXX methods follow the correct naming conventions exactly, as described above.

Using Asynchronous Pre- and Post-call Contexts

The AsyncPreCallContext and AsyncPostCallContext APIs describe asynchronous contexts that you can use in your Web Service for a variety of reasons. For example:

To use asynchronous pre- and post-call contexts:

  1. Import the asynchronous pre- and post-call context WebLogic APIs:
  2. import weblogic.wsee.async.AsyncCallContextFactory;
    import weblogic.wsee.async.AsyncPreCallContext;
    import weblogic.wsee.async.AsyncPostCallContext;
  3. In the method of the JWS file that is going to invoke the asynchronous operation, get a pre-call asynchronous context using the context factory. For example:
  4. AsyncPreCallContext apc =
    AsyncCallContextFactory.getAsyncPreCallContext();
  5. Use the pre-call context methods to operate on the asynchronous context before the asynchronous method is called. The following example uses the setProperty method of the pre-call context to create a property that stores the username:
  6. apc.setProperty("userName", userName);
  7. Use the post-call context methods to operate on the asynchronous context after the asynchronous method is called. The following example uses the getProperty method of the post-call context to get the property that was set by pre-call context before invoking the asynchronous method:
  8. String userName = (String)apc.getProperty("userName");

Example of a Synchronous Invoke

The following example shows a JWS file that invokes the getQuote operation of the StockQuote Web Service synchronously. The example is shown only so you can compare it with the corresponding asynchronous invoke shown in Writing the Asynchronous JWS File.

package examples.webservices.async_req_res;
import weblogic.jws.WLHttpTransport;
import weblogic.jws.ServiceClient;
import javax.jws.WebService;
import javax.jws.WebMethod;
import java.rmi.RemoteException;
@WebService(name="SyncClientPortType",
serviceName="SyncClientService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="syncClient",
serviceUri="SyncClient",
portName="SyncClientPort")
/**
* Normal service-to-service client that invokes StockQuote service
* synchronously.
*/
public class SyncClientImpl {
  @ServiceClient(wsdlLocation="http://localhost:7001/async/StockQuote?WSDL",
serviceName="StockQuoteService", portName="StockQuote")
private StockQuotePortType port;
  @WebMethod
public void nonAsyncOperation(String symbol) throws RemoteException {
    int quote = port.getQuote(symbol);
    System.out.println("-------------------");
System.out.println("Got quote " + quote );
System.out.println("-------------------");
  }
}

 


Updating the build.xml File When Using Asynchronous Request-Response

To update a build.xml file to generate the JWS file that invokes a Web Service operation asynchronously, add taskdefs and a build-clientService target that looks something like the following; see the description after the example for details:

<taskdef name="jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask" />
<target name="build-clientService">
    <jwsc
enableAsyncService="true"
srcdir="src"
destdir="${clientService-ear-dir}" >
        <jws file="examples/webservices/async_req_res/StockQuoteClientImpl.java" >
          <clientgen
wsdl="http://${wls.hostname}:${wls.port}/async/StockQuote?WSDL"
packageName="examples.webservices.async_req_res"/>
        </jws>
    </jwsc>
</target>

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

Update the jwsc Ant task that compiles the client Web Service to include a <clientgen> child element of the <jws> element so as to generate and compile the JAX-RPC stubs for the deployed StockQuote Web Service. The jwsc Ant task automatically packages them in the generated WAR file so that the client Web Service can immediately access the stubs. By default, the jwsc Ant task in this case generates both synchronous and asynchronous flavors of the Web Service operations in the JAX-RPC stubs. You do this because the StockQuoteClientImpl JWS file imports and uses one of the generated classes.

 


Disabling The Internal Asynchronous Service

By default, every WebLogic Server instance deploys an internal asynchronous Web Service that handles the asynchronous request-response feature. To specify that you do not want to deploy this internal service, start the WebLogic Server instance using the -Dweblogic.wsee.skip.async.response=true Java system property.

One reason for disabling the asynchronous service is if you use a WebLogic Server instance as a Web proxy to a WebLogic cluster. In this case, asynchronous messages will never get to the cluster, as required, because the asynchronous service on the proxy server consumes them instead. For this reason, you must disable the asynchronous service on the proxy server using the system property.

For details on specifying Java system properties to configure WebLogic Server, see “Specifying Java Options for a WebLogic Server Instance” in Managing Server Startup and Shutdown.

 


Using Asynchronous Request Response With a Proxy Server

Client applications that use the asynchronous request-response feature might not invoke the operation directly, but rather, use a proxy server. Reasons for using a proxy include the presence of a firewall or the deployment of the invoked Web Service to a cluster.

In this case, the WebLogic Server instance that hosts the invoked Web Service must be configured with the address and port of the proxy server. If your Web Service is deployed to a cluster, you must configure every server in the cluster.

This procedure describes how to create a network channel, the primary configurable WebLogic Server resource for managing network connection. Network channels enable you to provide a consistent way to access the front-end address of a cluster. For more information about network channels, see “Understanding Network Channels” in Configuring Server Environments.

For each server instance:

  1. Create a network channel for the protocol you use to invoke the Web Service. You must name the network channel weblogic-wsee-proxy-channel-XXX, where XXX refers to the protocol. For example, to create a network channel for HTTPS, call it weblogic-wsee-proxy-channel-https.
  2. See “Configure custom network channels” in the Administration Console Online Help for general information about creating a network channel.

  3. Configure the network channel, updating the External Listen Address and External Listen Port fields with the address and port of the proxy server, respectively.

  Back to Top       Previous  Next