Complete Contents
Preface
Chapter 1 Understanding LDAP
Chapter 2 Using the Netscape Directory SDK for Java
Chapter 3 Quick Start
Chapter 4 Writing an LDAP Client
Chapter 5 Using the LDAP Java Classes
Chapter 6 Searching the Directory
Chapter 7 Using Filter Configuration Files
Chapter 8 Adding, Updating, and Deleting Entries
Chapter 9 Comparing Values in Entries
Chapter 10 Working with LDAP URLs
Chapter 11 Getting Server Information
Chapter 12 Connecting Over SSL
Chapter 13 Working with LDAP Controls
Chapter 14 Using SASL Authentication
Chapter 15 Using Netscape's JNDI Service Provider
Chapter 16 Working with Extended Operations
Chapter 17 Using the Asynchronous Interface
Glossary
Directory SDK for Java 4.0 Programmer's Guide: Using the Asynchronous Interface
Previous Next Contents Index


Chapter 17 Using the Asynchronous Interface

This chapter shows you how to use the Asynchronous Interface to LDAP in Java applications.

This chapter contains the following sections:


Synchronous vs. Asynchronous Connections
Most operations using the Directory SDK for Java are performed synchronously. A connection is established, a request is sent, the results are returned, and the application resumes. Though the SDK can deliver one search result at a time, other operations block until completion when accessing an LDAP server.

Sometimes it is useful to initiate a new request while another one executes. An additional interface is provided to access the SDK's built-in support for these asynchronous requests. By returning control to an application before obtaining a response, the Asynchronous Interface allows you to perform complex operations requiring access to low-level LDAP mechanisms.

Beginning with version 4.0 of the Directory SDK for Java, LDAPConnection methods support both asynchronous and synchronous requests. Synchronous methods wait for response messages from a server and then process them for you. Asynchronous methods require you to check for the messages and perform the processing in your code. This allows you to make additional LDAP requests while waiting for results to return.


Common Uses for the Asynchronous Interface
Since it involves managing more complex code in an application, it is best to use the asynchronous methods only when required. The most common use is for merging the results of searches that involve multiple servers or that are executed simultaneously on different subtrees. This is sometimes referred to as "multiplexing."

A search that multiplexes servers can make a request to an array of hosts. A search that multiplexes query statements can make different requests to different subtrees of a server. If you combine these search methods you can perform complex searches across a number of servers without having to wait for individual responses.

The following example illustrates a practical use of multiplexed searches and the asynchronous interface.

Suppose we want to implement event notification as a generic service using LDAP persistent search. Synchronous methods require a new thread for every request to the service. This solution is not scalable and can exhaust system resources very quickly.

If we rewrite the search using the asynchronous interface, performance will improve dramatically. Since asynchronous searches do not block until completion, we can multiplex the persistent search results into one queue and then process them on a single thread.


New Classes in the Asynchronous Interface
The Directory SDK for Java handles asynchronous communication through the LDAPAsynchronousConnection interface and its dependent classes. These files collectively form the asynchronous extensions to the LDAP API.

LDAPAsynchronousConnection defines methods for authenticating to a server, as well as for searching, modifying, comparing and deleting entries in the directory.

When you call a method of LDAPAsynchronousConnection, it returns a listener object. This object acts as a message queue and accepts search results and server-generated responses to LDAP requests. It is the responsibility of the LDAP client to read and process these messages.

LDAPAsynchronousConnection incorporates the following classes which handle asynchronous client-server interactions:

The rest of this chapter shows you how to use the asynchronous interface to perform multiplexed searches.


Performing Asynchronous Searches
One of the most common uses of the asynchronous interface is for performing multiplexed searches using more than one server or query. The rest of this section will show you how to do this.

Searching Multiple Servers
To perform a search on more than one server:

  1. Connect to all the servers.
  2. Create a response listener for one search.
  3. Share the response listener all the other searches.
  4. Obtain and process the results.
  5. Disconnect from the servers.
The following code demonstrates how to do this in an application:

import netscape.ldap.*;
import java.util.*;
/* This example multiplexes the input from three different servers */
public class MultiplexServers {
   public static void main( String[] args )
   {
      try {
         LDAPAsynch[] ld = new LDAPAsynch[3];
         String[] hosts = { "foo1", "foo2", "foo3" };
         int[] ports = { 389, 389, 2018 }
         String[] bases =
            { "o=Airius.com", "o=Acme.com", "dc=Acme,dc=com" };
         /* search for all entries with surname of Jensen */
         String MY_FILTER = "sn=Jensen";
         for( int i = 0; i < ld.length; i++ ) {
            ld[i] = new LDAPAsynch();
            /* Connect to server */
            ld[i].connect( hosts[i], ports[i] );
         }
         /* Get a response listener for one search */
         LDAPSearchListener l =
            ld[0].search( bases[0],
                         ld.SCOPE_SUB,
                         MY_FILTER,
                         null,
                         false,
                         (LDAPSearchListener)null );
         /* Share the listener */
         for( i = 1; i < ld.length; i++ ) {
            ld[i].search( bases[i],
                         ld[i].SCOPE_SUB,
                         MY_FILTER,
                         null,
                         false,
                         l );
         }
         /* Loop on results until finished */
         LDAPMessage msg;
         while( (msg = l.getResponse()) != null ) {
            if ( msg instanceof LDAPSearchResultReference ) {
               String[] urls =
                  ((LDAPSearchResultReference)msg).getUrls();
               // Do something with the referrals...
            } else if ( msg instanceof LDAPSearchResult ) {
               LDAPEntry entry =
                  ((LDAPSearchResult)msg).getEntry();
               // The rest of the processing is the same as for
               // a synchronous search
               System.out.println( entry.getDN() );
            } else {
               // A search response
               LDAPResponse res = (LDAPResponse)msg;
               int status = res.getResultCode();
               if ( status == LDAPException.SUCCESS ) {
                  // Nothing to do
               } else {
                  String err =
                     LDAPException.errorCodeToString(status);
                  throw new LDAPException(
                                          err,
                                          status,
                                          res.getErrorMessage(),
                                          res.getMatchedDN() );
               }
            }
         }
      } catch ( LDAPException e ) {
         System.err.println( e.toString() );
      }
      /* Done, so disconnect */
      if ( ld.isConnected() ) {
         ld.disconnect();
      }
   }
}
Multiple Search Statements
To perform multiple searches in different subtrees of a single server:

  1. Connect to the server.
  2. Create a response listener for one search.
  3. Share (multiplex) the response listener with the other searches.
  4. Obtain and process the results.
  5. Disconnect from the server.
The following code demonstrates how to do this in an application:

import netscape.ldap.*;
import java.util.*;
/* This example multiplexes the input from three searches in
different subtrees of the same server */
public class MultiplexTrees {
   public static void main( String[] args )
   {
      try {
         LDAPAsynch ld = new LDAPAsynch();
         /* Connect to server */
         String MY_HOST = "localhost";
         int MY_PORT = 389;
         ld.connect( MY_HOST, MY_PORT );
         String MY_FILTER = "sn=Jensen";
         String[] bases =
            { "o=Airius.com", "o=Acme.com", "dc=Acme,dc=com" };
         /* Get a response listener for one search */
         LDAPSearchListener l =
            ld.search( bases[0],
                      ld.SCOPE_SUB,
                      MY_FILTER,
                      null,
                      false,
                      (LDAPSearchListener)null );
         /* Share the listener */
         for( i = 1; i < bases.length; i++ ) {
            ld.search( bases[i],
                      ld.SCOPE_SUB,
                      MY_FILTER,
                      null,
                      false,
                      l );
         }
         /* Loop on results until finished */
         LDAPMessage msg;
         while( (msg = l.getResponse()) != null ) {
            /* The rest is the same as in the previous example */
            /* ... */

Where to Go for More Information
The javadocs for the Directory SDK for Java describe all the classes, methods and exceptions of the LDAPAsynchronousConnection interface. For more information on using the javadocs, see "Where to Find Reference Information".

The Internet-Draft titled "The Java LDAP Application Program Interface Asynchronous Extension" is available at the following URL:

http://www.ietf.org/internet-drafts/draft-ietf-ldapext-ldap-java-api-asynch-ext-00.txt.

Note. Internet-Drafts expire every six months. If the URL above does not work, try incrementing the number by one. For example, draft-06.txt would become draft-07.txt.

 

© Copyright 1999 Netscape Communications Corporation. All rights reserved.