Writing Asynchronous Clients With &DirectorySDKForJava;
This chapter shows how to use the asynchronous interface to LDAP in
Java applications.
This chapter covers the following topics:
Synchronous and Asynchronous Connections With Directory SDK for Java
Common Uses for the Asynchronous Interface With Directory SDK for Java
Classes in the Asynchronous Interface for Directory SDK for Java
Performing Asynchronous Searches With Directory SDK for Java
Further Reading About the Asynchronous Interface for Directory SDK for Java
Synchronous and Asynchronous Connections
With Directory SDK for Java
asynchronous interface
explained
synchronous interface
explained
Most operations with &DirectorySDKForJava; are performed synchronously.
A connection is established, a request is sent, the results are returned.
Then the application resumes. Though the &DirectorySDKForJava; can deliver
one search result at a time, other operations block until completion when
accessing an LDAP server.
Sometimes, initiating a new request while another request executes can
be useful. An additional interface is provided to access the built-in support
in &DirectorySDKForJava; 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.
LDAPConnection methods support both asynchronous
requests and synchronous requests. Synchronous methods wait for response messages
from a server and then process the responses for you. Asynchronous methods
require that you check for the messages. You then perform the processing in
your code. This mechanism allows you to make additional LDAP requests while
waiting for results to return.
Common Uses for the Asynchronous Interface
With Directory SDK for Java
asynchronous interface
common uses
Since using the asynchronous interface involves managing more complex
code in an application, 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 method
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 event notification must be implemented as a generic service
with 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.
After the search is rewritten using the asynchronous interface, performance
improves dramatically. Since asynchronous searches do not block until completion,
the persistent search results can be multiplexed into one queue and then processed
on a single thread.
Classes in the Asynchronous Interface for Directory
SDK for Java
asynchronous interface
classes
&DirectorySDKForJava; 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,
the method returns a listener object. This object acts as a message queue.
The object accepts search results and server-generated responses to LDAP requests.
The LDAP client has the responsibility to read and process these messages.
LDAPAsynchronousConnection incorporates the following
classes for handling asynchronous client-server interactions:
LDAPMessage, which is the base class
for LDAP request and response messages.
LDAPResponse, which extends LDAPMessage
, represents a message received from an LDAP server in response
to a request.
LDAPExtendedResponse, which extends
LDAPResponse. This response is the response that an LDAP server
returns when handling an extended operation request.
LDAPResponseListener queues LDAPResponse
messages.
LDAPSearchResult, which extends
LDAPMessage. The response contains a single LDAP entry. The response
is one of the responses an LDAP server can return when handling a search request.
LDAPSearchResultReference, which extends
LDAPMessage. The response contains a referral. The response is
one of the responses that an LDAP server can return when handling a search
request.
LDAPSearchListener queues search results
and references.
Performing Asynchronous Searches With Directory
SDK for Java
One of the most common uses of the asynchronous interface is for performing
multiplexed searches using more than one server or suffix.
To Search Across Multiple Servers
asynchronous interface
search multiple servers
To search on more than one server, perform the following steps.
Connect to all the servers.
Create a response listener for one search.
Share the response listener with all the other searches.
Obtain and process the results.
Disconnect from the servers.
Searching Across Multiple Servers
This example demonstrates how to search on two servers at the same time.
import netscape.ldap.*;
import java.util.*;
public class MultiplexServers {
public static void main(String[] args) {
try {
LDAPConnection[] ld = new LDAPConnection[2];
String[] hosts = {"server1", "server2"};
int[] ports = {389, 389};
String[] bases = {"dc=example,dc=com", "dc=example,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 LDAPConnection();
ld[i].connect(hosts[i], ports[i]);
}
/* Get a response listener for one search */
LDAPSearchListener l = ld[0].search(bases[0], ld[0].SCOPE_SUB,
MY_FILTER, null, false, (LDAPSearchListener)null);
/* Share the listener */
for (int 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) {
; // Ignore referrals
} else if (msg instanceof LDAPSearchResult) {
LDAPEntry entry = ((LDAPSearchResult)msg).getEntry();
System.out.println("Found entry: " + entry.getDN());
} else if (msg instanceof LDAPResponse) {
int result = ((LDAPResponse)msg).getResultCode();
if (result != 0) {
System.out.println("Result code: " + result);
System.out.println("Error message: " +
((LDAPResponse)msg).getErrorMessage());
}
}
}
for (int i = 0; i < ld.length; i++) {
ld[i].disconnect();
}
} catch (LDAPException e) {
System.err.println(e.toString());
}
}
}
To Search Across Multiple Suffixes
on a Single Server
asynchronous interface
search multiple suffixes
To search on more than one suffix, perform the following steps.
Connect to the server.
Create a response listener for one search.
Share (multiplex) the response listener with the other searches.
Obtain and process the results.
Disconnect from the server.
Searching Across Multiple Suffixes
This example demonstrates how to search across two suffixes at the same
time.
import netscape.ldap.*;
import java.util.*;
public class MultiplexSuffixes {
public static void main(String[] args) {
try {
UserArgs userArgs =
new UserArgs("MultipleSuffixes", args, false);
LDAPConnection ld = new LDAPConnection();
ld.connect(userArgs.getHost(), userArgs.getPort());
String[] bases = {"dc=example,dc=com",
"ou=groups,dc=example,dc=com"};
String MY_FILTER = "(objectclass=*)";
/* Get a response listener for one search */
LDAPSearchListener l = ld.search(bases[0], ld.SCOPE_ONE,
MY_FILTER, null, false, (LDAPSearchListener)null);
/* Share the listener */
for (int i = 1; i < bases.length; i++) {
ld.search(bases[i], ld.SCOPE_ONE,
MY_FILTER, null, false, l);
}
/* Loop on results until finished */
LDAPMessage msg;
while ((msg = l.getResponse()) != null) {
if (msg instanceof LDAPSearchResultReference) {
; // Ignore referrals
} else if (msg instanceof LDAPSearchResult) {
LDAPEntry entry = ((LDAPSearchResult)msg).getEntry();
System.out.println("Found entry: " + entry.getDN());
} else if (msg instanceof LDAPResponse) {
int result = ((LDAPResponse)msg).getResultCode();
if (result != 0) {
System.out.println("Result code: " + result);
System.out.println("Error message: " +
((LDAPResponse)msg).getErrorMessage());
}
}
}
ld.disconnect();
} catch (LDAPException e) {
System.err.println(e.toString());
}
}
}
Further Reading About the Asynchronous Interface
for Directory SDK for Java
The asynchronous interface is defined in an Internet Draft, The
Java LDAP Application Programming Interface.