зеркало из https://github.com/mozilla/pjs.git
618 строки
34 KiB
Plaintext
618 строки
34 KiB
Plaintext
<!--
|
|
|
|
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
|
Portions copyright 1999 Netscape Communications Corporation. All
|
|
Rights Reserved.
|
|
|
|
The contents of this document are subject to the terms of the
|
|
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
|
version (the "License"). You may not use this document except in
|
|
compliance with the License.
|
|
|
|
See the License for the specific language governing
|
|
permissions and limitations under the License. You can obtain
|
|
a copy of the License at
|
|
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
|
|
|
-->
|
|
<chapter id="common-classes"><title>Using the LDAP Java Classes</title>
|
|
<highlights>
|
|
<para>This chapter covers general LDAP Java classes that are commonly used
|
|
when writing LDAP clients.</para>
|
|
<itemizedlist>
|
|
<para>This chapter covers the following topics:</para>
|
|
<listitem><para><olink targetptr="jdk-info">Getting Information About Directory
|
|
SDK for Java</olink></para></listitem>
|
|
<listitem><para><olink targetptr="handling-exceptions">Handling Exceptions
|
|
With Directory SDK for Java</olink></para></listitem>
|
|
<listitem><para><olink targetptr="handling-referrals">Handling Referrals With
|
|
Directory SDK for Java</olink></para></listitem>
|
|
<listitem><para><olink targetptr="in-memory-cache">Using In-Memory Cache With
|
|
Directory SDK for Java</olink></para></listitem>
|
|
<listitem><para><olink targetptr="cloning-connection">Cloning a Connection
|
|
With Directory SDK for Java</olink></para></listitem>
|
|
<listitem><para><olink targetptr="handling-dns">Manipulating Distinguished
|
|
Names With Directory SDK for Java</olink></para></listitem>
|
|
</itemizedlist>
|
|
</highlights>
|
|
<sect1 id="jdk-info"><title>Getting Information About &DirectorySDKForJava;</title>
|
|
<indexterm>
|
|
<primary>&DirectorySDKForJava;</primary>
|
|
<secondary>getting information about</secondary>
|
|
</indexterm>
|
|
<para>You can get information about the version of &DirectorySDKForJava; that
|
|
you are using. Version information tells you the version of the LDAP Java
|
|
classes. Version information can also tell you the highest version of the
|
|
LDAP protocol that &DirectorySDKForJava; supports.</para>
|
|
<para>To get this information, use the <literal>getProperty</literal> method
|
|
of the <classname>LDAPConnection</classname> object.</para>
|
|
<programlisting>LDAPConnection ld = new LDAPConnection();
|
|
try {
|
|
System.out.println("LDAP Java Classes Version: " +
|
|
(Float) ld.getProperty(LDAPConnection.LDAP_PROPERTY_SDK));
|
|
System.out.println("Highest version of LDAP supported: " +
|
|
(Float) ld.getProperty(LDAPConnection.LDAP_PROPERTY_PROTOCOL));
|
|
System.out.println("Authentication methods supported: " +
|
|
(String) ld.getProperty(LDAPConnection.LDAP_PROPERTY_SECURITY));
|
|
} catch (LDAPException e) {
|
|
System.out.println("Could not get SDK properties.");
|
|
System.out.println("Error: " + e.toString());
|
|
}</programlisting>
|
|
<para>Although a <literal>setProperty</literal> method is provided, currently
|
|
no properties exist that you can set. If you invoke the <literal>setProperty</literal> method,
|
|
the method returns an <classname>LDAPException</classname>.</para></sect1>
|
|
<sect1 id="handling-exceptions"><title>Handling Exceptions With &DirectorySDKForJava;</title>
|
|
<indexterm>
|
|
<primary>exceptions</primary>
|
|
<secondary>handling</secondary>
|
|
</indexterm>
|
|
<para>In LDAP, the success or failure of an operation is specified by an LDAP
|
|
result code sent back to the client. For example, the result code <returnvalue>0</returnvalue> indicates
|
|
that the operation was successful. A non zero result code usually indicates
|
|
that an error occurred.</para>
|
|
<sect2 id="getting-info"><title>Getting Information About the Error</title>
|
|
<indexterm>
|
|
<primary>exceptions</primary>
|
|
<secondary>getting information about</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>LDAP result code</primary>
|
|
</indexterm>
|
|
<para>In the LDAP Java classes, when an error occurs, an <classname>LDAPException
|
|
</classname> is returned. Referrals cause an <classname>LDAPReferralException</classname> to
|
|
be returned as described in <olink targetptr="handling-referrals">Handling
|
|
Referrals With Directory SDK for Java</olink>.</para>
|
|
<itemizedlist>
|
|
<para>An <classname>LDAPException</classname> contains the following information:
|
|
</para>
|
|
<listitem><para>The LDAP result code for the error that occurred</para>
|
|
</listitem>
|
|
<listitem><para>A message that contains any additional information about the
|
|
error from the server</para></listitem>
|
|
</itemizedlist>
|
|
<para>An error can occur when an entry specified by a DN cannot be found.
|
|
The <classname>LDAPException</classname> then also contains the DN of the <firstterm>
|
|
closest matching entry</firstterm> that can be found.</para>
|
|
<itemizedlist>
|
|
<para>To get information from the <classname>LDAPException</classname>, use
|
|
one of the following methods:</para>
|
|
<listitem><para>To get the string representation of the exception, use the <literal>
|
|
toString</literal> method.</para></listitem>
|
|
<listitem><para>To get the LDAP result code, use the <literal>getLDAPResultCode</literal> method.
|
|
</para></listitem>
|
|
<listitem><para>To get any additional information sent by the server, use
|
|
the <literal>getLDAPErrorMessage</literal> method.</para></listitem>
|
|
<listitem><para>To get the closest matching DN in cases where your client
|
|
specified a DN to a nonexistent entry, use the <literal>getMatchedDN</literal> method.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
<para>To get the error message describing the LDAP result code, use the <literal>
|
|
errorCodeToString</literal> method, as described in <olink
|
|
targetptr="error-message">Getting the Error Message</olink>.</para>
|
|
<para>The following section of code gets and prints information about an <classname>
|
|
LDAPException</classname>.</para>
|
|
<programlisting>try {
|
|
/* Attempt to perform an LDAP operation here. */
|
|
} catch (LDAPException e) {
|
|
/* Get and print the result code and any other info. */
|
|
int resultCode = e.getLDAPResultCode();
|
|
String serverInfo = e.getLDAPErrorMessage();
|
|
System.out.println("LDAP Result Code: " + resultCode);
|
|
if (serverInfo != null) {
|
|
System.out.println("Additional Info: " + serverInfo);
|
|
}
|
|
/*
|
|
* If the exception was returned because an entry was
|
|
* not found, print the DN of the closest entry found.
|
|
*/
|
|
switch (resultCode) {
|
|
case LDAPException.NO_SUCH_OBJECT:
|
|
case LDAPException.ALIAS_PROBLEM:
|
|
case LDAPException.INVALID_DN_SYNTAX:
|
|
case LDAPException.ALIAS_DEREFERENCING_PROBLEM:
|
|
String matchedDN = e.getMatchedDN();
|
|
if (matchedDN != null) {
|
|
System.out.println("Closest Entry: " + matchedDN);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}</programlisting>
|
|
</sect2>
|
|
<sect2 id="error-message"><title>Getting the Error Message</title>
|
|
<indexterm>
|
|
<primary>LDAP result code</primary>
|
|
<secondary>string description for</secondary>
|
|
</indexterm>
|
|
<para>To get the error message for an LDAP result code, use the <literal>errorCodeToString
|
|
</literal> method.</para>
|
|
<programlisting>try {
|
|
/* Attempt to perform an LDAP operation here. */
|
|
} catch (LDAPException e) {
|
|
/* Get and print the error message. */
|
|
int resultCode = e.getLDAPResultCode();
|
|
System.out.println("Error: " + e.errorCodeToString(resultCode));
|
|
}</programlisting>
|
|
<para>Error messages corresponding to each LDAP result code are located either
|
|
inside the <filename>ldapjdk.jar</filename> file or under another directory
|
|
in your <envar>CLASSPATH</envar>, in a properties file named <filename>netscape/ldap/errors/ErrorCodes.props
|
|
</filename> or <filename>netscape/ldap/errors/ErrorCodes_<replaceable>locale</replaceable>.props
|
|
</filename>. <replaceable>locale</replaceable> can be a two-letter version
|
|
of the locale, such as <literal>de</literal>, <literal>fr</literal>, or <literal>
|
|
ja</literal>, or it can be a full version of the locale, such as <literal>en_US</literal>.
|
|
</para>
|
|
<para>When you invoke the <literal>errorCodeToString</literal> method of an <classname>
|
|
LDAPException</classname>, the method retrieves the error message string for
|
|
the specified locale. If no locale is specified, the method retrieves the
|
|
default locale from the properties file. The <literal>errorCodeToString</literal> method
|
|
looks for locale-specific properties files in the following order, retrieving
|
|
the first property that is found:</para>
|
|
<programlisting>netscape/ldap/error/ErrorCodes_<replaceable>language</replaceable>_<replaceable>
|
|
country</replaceable>.props
|
|
netscape/ldap/error/ErrorCodes_<replaceable>language</replaceable>.props
|
|
netscape/ldap/error/ErrorCodes.props</programlisting>
|
|
</sect2>
|
|
</sect1>
|
|
<sect1 id="handling-referrals"><title>Handling Referrals With &DirectorySDKForJava;</title>
|
|
<indexterm>
|
|
<primary>referrals</primary>
|
|
</indexterm>
|
|
<para>An LDAP server can receive a request for a DN that is not under its
|
|
directory tree. The server can then refer clients to another LDAP server that
|
|
might contain that DN. The response is known as a <firstterm>referral</firstterm>.
|
|
This section explains how to set up your LDAP client to handle referrals automatically.
|
|
</para>
|
|
<sect2 id="understanding-referrals"><title>Understanding Referrals</title>
|
|
<itemizedlist>
|
|
<para>Suppose an LDAP server has a directory that starts under <literal>dc=example,dc=com
|
|
</literal>. Your client might send the server a request to modify the entry
|
|
with the DN <literal>uid=bjensen,ou=People,o=example.com</literal>. The entry
|
|
is not under <literal>dc=example,dc=com</literal>. One of the following can
|
|
occur.</para>
|
|
<listitem><para>If the server is not configured to send a referral, an <classname>
|
|
LDAPException</classname> is returned with the LDAP result code <constant>LDAPException.NO_SUCH_OBJECT
|
|
</constant>.</para></listitem>
|
|
<listitem><para>If the server is configured to refer you to another LDAP server,
|
|
the server sends a referral back to your client.</para>
|
|
<itemizedlist>
|
|
<para>Depending on how your LDAP client is configured, one of the following
|
|
can occur:</para>
|
|
<listitem><para>If your client handles referrals automatically, your client
|
|
connects to the LDAP server specified in the referral and requests to modify
|
|
the entry. The client binds anonymously to that server. To bind as a specific
|
|
user, refer to <olink targetptr="enabling-referrals">Enabling or Disabling
|
|
Referral Handling</olink>.</para></listitem>
|
|
<listitem><para>If your client does not handle referrals automatically, an <classname>
|
|
LDAPReferralException</classname> is returned. You can get the LDAP URL specified
|
|
in the referral by catching the exception, and then invoking the <literal>getURLs
|
|
</literal> method.</para></listitem>
|
|
</itemizedlist>
|
|
<para>By default, clients built with &DirectorySDKForJava; are configured
|
|
to follow referrals automatically.</para></listitem>
|
|
</itemizedlist>
|
|
<para>Another concept that is similar to a referral is a search reference.
|
|
A <firstterm>search reference</firstterm> is an entry with the object class <literal>
|
|
referral</literal>. The <literal>ref</literal> attribute of this object contains
|
|
an LDAP URL that points to another LDAP server.</para>
|
|
<para>When your client searches a subtree of the directory that contains search
|
|
references, the server returns a mix of matching entries and search references.
|
|
As you iterate through the enumeration of search results, you can encounter
|
|
a search reference although your client does not handle referrals automatically.
|
|
An <classname>LDAPReferralException</classname> is then returned.</para></sect2>
|
|
<sect2 id="enabling-referrals"><title>Enabling or Disabling Referral Handling</title>
|
|
<indexterm>
|
|
<primary>referrals</primary>
|
|
<secondary>handling automatically</secondary>
|
|
</indexterm>
|
|
<para>By default, clients built with &DirectorySDKForJava; automatically
|
|
follow referrals to other servers.</para>
|
|
<itemizedlist>
|
|
<para>To change the way your client handles referrals, use one of two methods.
|
|
Use the <literal>setOption</literal> method of the <classname>LDAPConnection</classname> object
|
|
to change the behavior for all LDAP operations. Alternatively, use the <literal>setReferrals
|
|
</literal> method of the <classname>LDAPConstraints</classname> object to
|
|
change the behavior for a specific search request.</para>
|
|
<listitem><para>To prevent the client from automatically following referrals,
|
|
pass <literal>LDAPv3.REFERRALS</literal> and <literal>false</literal> as arguments
|
|
to the <literal>setOption</literal> method. Alternatively, pass <literal>false</literal> as
|
|
the argument to the <literal>setReferrals</literal> method.</para></listitem>
|
|
<listitem><para>To enable the client to follow referrals automatically again,
|
|
pass <literal>LDAPv3.REFERRALS</literal> and <literal>true</literal> as arguments
|
|
to the <literal>setOption</literal> method. Alternatively, pass <literal>true</literal> as
|
|
the argument to the <literal>setReferrals</literal> method.</para></listitem>
|
|
</itemizedlist>
|
|
</sect2>
|
|
<sect2 id="limiting-referral-hops"><title>Limiting Referral Hops</title>
|
|
<indexterm>
|
|
<primary>referrals</primary>
|
|
<secondary>specifying maximum hops</secondary>
|
|
</indexterm>
|
|
<para>You can specify the maximum number of referral hops that should be followed
|
|
in a sequence of referrals. You can set the preference for the connection.
|
|
You can also set the maximum as a constraint for specific search operations.
|
|
The maximum is called the <firstterm>referral hop limit</firstterm>.</para>
|
|
<para>For example, suppose you set a limit of two referral hops. If LDAP server
|
|
A refers to server B, B to C, and C to D, your client is being referred three
|
|
times in a row. Your client does not follow the referral to LDAP server D
|
|
because this referral exceeds the referral hop limit.</para>
|
|
<para>If the referral hop limit is exceeded, an <classname>LDAPReferralException</classname> is
|
|
returned.</para>
|
|
<para>To set the referral hop limit, use either of two methods. Use the <literal>
|
|
LDAPv3.REFERRALS_HOP_LIMIT</literal> preference with the <literal>setOption</literal> method
|
|
of the <classname>LDAPConnection</classname> object to change the behavior
|
|
for all LDAP operations. Alternatively, use the <literal>setHopLimit</literal> method
|
|
of the <classname>LDAPConstraints</classname> object to change the behavior
|
|
for a specific search request.</para>
|
|
<para>By default, the maximum number of referral hops is 10.</para></sect2>
|
|
<sect2 id="referral-bind"><title>Binding When Following Referrals</title>
|
|
<indexterm>
|
|
<primary>authentication</primary>
|
|
<secondary>authenticating during referrals</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>referrals</primary>
|
|
<secondary>authenticating</secondary>
|
|
</indexterm>
|
|
<para>If the connection is set up so that referrals are always followed, the
|
|
LDAP server that you connect to can refer you to another server. By default,
|
|
the client binds anonymously such that no user names or passwords are specified
|
|
when following referrals.</para>
|
|
<para>To authenticate to the LDAP server that you are referred to, specify
|
|
how to get the DN and password for authentication. You need to define a class
|
|
that implements the <classname>LDAPRebind</classname> interface. Then, specify
|
|
an object of this new class with either of two methods. Use the <literal>LDAPv3.REFERRALS_REBIND_PROC
|
|
</literal> preference with the <literal>setOption</literal> method of the <classname>
|
|
LDAPConnection</classname> object to set the preference for all LDAP operations.
|
|
Alternatively, use the <literal>setRebindProc</literal> method of the <classname>
|
|
LDAPConstraints</classname> object to change the behavior for a specific search
|
|
request.</para>
|
|
<para>The <classname>LDAPRebind</classname> interface specifies a <literal>getRebindAuthentication
|
|
</literal> method that returns an <classname>LDAPRebindAuth</classname> object.
|
|
The <literal>getRebindAuthentication</literal> method and the <classname>LDAPRebindAuth
|
|
</classname> object that the method returns are used to get the DN and password
|
|
for authentication.</para>
|
|
<orderedlist>
|
|
<para>The following steps explain how this works.</para>
|
|
<listitem><para>The LDAP server sends a referral back to the client. The referral
|
|
contains an LDAP URL that points to another LDAP server.</para></listitem>
|
|
<listitem><para>The client creates a new <classname>LDAPConnection</classname> object.
|
|
</para></listitem>
|
|
<listitem><para>The client connects to the host and port specified in the
|
|
LDAP URL.</para></listitem>
|
|
<listitem><para>You can use the <literal>getRebindProc</literal> method to
|
|
find your object, the object that implements the <classname>LDAPRebind</classname> interface.
|
|
The client then invokes the <literal>getRebindAuthentication</literal> method,
|
|
passing in the host and port specified in the LDAP URL.</para></listitem>
|
|
<listitem><para>The <literal>getRebindAuthentication</literal> method in your
|
|
object returns an <classname>LDAPRebindAuth</classname> object.</para>
|
|
</listitem>
|
|
<listitem><para>The client invokes the <literal>getDN</literal> and <literal>getPassword
|
|
</literal> methods of the returned <classname>LDAPRebindAuth</classname> object
|
|
to get the DN and password to use for authentication.</para></listitem>
|
|
<listitem><para>The client invokes the authenticate method of the <classname>LDAPConnection
|
|
</classname> object and passes the DN and password to authenticate to the
|
|
server.</para></listitem>
|
|
</orderedlist>
|
|
<itemizedlist>
|
|
<para>Basically, you need to define the following:</para>
|
|
<listitem><para>A class that implements the <classname>LDAPRebind</classname> interface
|
|
</para></listitem>
|
|
<listitem><para>A <literal>getRebindAuthentication</literal> that takes a
|
|
host name and port number. </para></listitem>
|
|
<listitem><para>This method creates an <classname>LDAPRebindAuth</classname> object
|
|
that specifies the DN and password to use for authentication.</para></listitem>
|
|
</itemizedlist>
|
|
</sect2>
|
|
</sect1>
|
|
<sect1 id="in-memory-cache"><title>Using In-Memory Cache With &DirectorySDKForJava;</title>
|
|
<indexterm>
|
|
<primary>cache</primary>
|
|
</indexterm><indexterm>
|
|
<primary>in-memory cache</primary>
|
|
</indexterm><indexterm>
|
|
<primary>connection</primary>
|
|
<secondary>caching results</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>LDAP session</primary>
|
|
<secondary>caching results</secondary>
|
|
</indexterm><indexterm>
|
|
<primary>search results</primary>
|
|
<secondary>caching</secondary>
|
|
</indexterm>
|
|
<para>&DirectorySDKForJava; includes an <classname>LDAPCache</classname> class
|
|
that allows you to create an in-memory cache of search results for your client.
|
|
When you send a search request, you receive results. The search request and
|
|
its results are then cached. The next time your client issues the same search
|
|
request, the results are read from the cache.</para>
|
|
<sect2 id="understanding-cache"><title>How the Cache Operates</title>
|
|
<itemizedlist>
|
|
<para>Each item in the cache represents a search request and its results.
|
|
When you create the cache, you can specify the maximum size of the cache.
|
|
You can also specify the maximum amount of time that an item can be cached.</para>
|
|
<listitem><para>When an item's age exceeds that time limit, the item is removed
|
|
from the cache. The cache is checked once a minute for expired items.</para>
|
|
</listitem>
|
|
<listitem><para>If adding a new item causes the cache to exceed its maximum
|
|
size, items are removed from the cache. Removal makes space for the new item.
|
|
Items are removed on a first in, first out basis.</para></listitem>
|
|
</itemizedlist>
|
|
<itemizedlist>
|
|
<para>Each item is uniquely identified by the search criteria, which includes
|
|
the following:</para>
|
|
<listitem><para>Host name and port number of the LDAP server</para></listitem>
|
|
<listitem><para>Base DN of the search</para></listitem>
|
|
<listitem><para>Search filter</para></listitem>
|
|
<listitem><para>Scope of the search</para></listitem>
|
|
<listitem><para>Attributes to be returned in the search results</para>
|
|
</listitem>
|
|
<listitem><para>DN used to authenticate the client when binding to the server</para>
|
|
</listitem>
|
|
<listitem><para>LDAP v3 controls specified in the search request</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<para>After a search request is cached, if your client performs the same search
|
|
again, the results are read from the cache instead of from the server.</para>
|
|
<para>Note that if any part of a search request differs from a cached search
|
|
request, the results are read from the server. For example, a different DN
|
|
might be used when authenticating to the server. Alternatively, the search
|
|
request might specify that a different set of attributes should be returned.
|
|
In either case, the results are not read from the cache. Instead, the search
|
|
request is sent to the server.</para>
|
|
<para>Finally, when creating the cache, you can specify a list of the base
|
|
DNs in search requests that you want to cache. For example, if you specify <literal>
|
|
ou=People,dc=example,dc=com</literal> as a base DN to cache, your client caches
|
|
search requests where the base DN is <literal>ou=People,dc=example,dc=com</literal>.
|
|
</para></sect2>
|
|
<sect2 id="cache-setup"><title>Setting Up an In-Memory Cache</title>
|
|
<indexterm>
|
|
<primary>cache</primary>
|
|
<secondary>setting up</secondary>
|
|
</indexterm>
|
|
<orderedlist>
|
|
<para>To set up a cache for your connection, do the following:</para>
|
|
<listitem><para>Construct a new <classname>LDAPCache</classname> object that
|
|
represents the cache.</para></listitem>
|
|
<listitem><para>Invoke the <literal>setCache</literal> method of an <classname>LDAPConnection
|
|
</classname> object to associate the cache with the connection.</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
<para>For example, the following section of code creates a cache with the
|
|
maximum size of 1 Mbyte. Items in the cache expire and are automatically removed
|
|
after one hour.</para>
|
|
<programlisting>try {
|
|
LDAPConnection ld = new LDAPConnection();
|
|
|
|
/* Create a cache for the connection */
|
|
int MAX_TIME_CACHED = 3600; // 3600 seconds == 1 hour
|
|
int MAX_SIZE = 1000000; // 1000000 bytes == 1 MB
|
|
LDAPCache myCache = new LDAPCache(MAX_TIME_CACHED, MAX_SIZE);
|
|
ld.setCache(myCache);
|
|
|
|
/* Connect to server */
|
|
ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
|
|
|
|
/*
|
|
* Perform operations...
|
|
*/
|
|
} catch (LDAPException e) {
|
|
System.out.println("Error: " + e.toString());
|
|
}</programlisting>
|
|
</sect2>
|
|
<sect2 id="caching-basedn"><title>Caching Requests by Base DN</title>
|
|
<para>If you do not want all search requests cached, specify an array of base
|
|
DNs for search requests to cache in the <classname>LDAPCache</classname> constructor.
|
|
</para>
|
|
<para>For example, the following section of code constructs a cache that only
|
|
tracks search requests that specify the base DNs <literal>ou=People,dc=example,dc=com
|
|
</literal> and <literal>ou=Groups,dc=example,dc=com</literal>.</para>
|
|
<programlisting>/* Create a cache for the connection */
|
|
int MAX_TIME_CACHED = 3600;
|
|
int MAX_SIZE = 1000000;
|
|
String [] BASE_DN_CACHED = {"ou=People,dc=example,dc=com",
|
|
"ou=Groups,dc=example,dc=com"};
|
|
LDAPCache myCache = new LDAPCache(MAX_TIME_CACHED, MAX_SIZE,
|
|
BASE_DN_CACHED);</programlisting>
|
|
</sect2>
|
|
<sect2 id="sharing-cache"><title>Sharing a Cache Among Connections</title>
|
|
<indexterm>
|
|
<primary>cache</primary>
|
|
<secondary>sharing between connections</secondary>
|
|
</indexterm>
|
|
<para>You can also share the same in-memory cache among different connections.</para>
|
|
<itemizedlist>
|
|
<listitem><para>Invoke the <literal>getCache</literal> method of an <classname>LDAPConnection
|
|
</classname> object to get the <classname>LDAPCache</classname> object that
|
|
is used.</para></listitem>
|
|
<listitem><para>Invoke the <literal>setCache</literal> method of a different <classname>
|
|
LDAPConnection</classname> object to associate the retrieved <classname>LDAPCache
|
|
</classname> object with the connection.</para></listitem>
|
|
</itemizedlist>
|
|
<para>When you clone an <classname>LDAPConnection</classname> object, the
|
|
new object automatically shares the same <classname>LDAPCache</classname> object
|
|
with the original object.</para></sect2>
|
|
<sect2 id="flushing-cache"><title>Flushing the Cache</title>
|
|
<indexterm>
|
|
<primary>cache</primary>
|
|
<secondary>flushing</secondary>
|
|
</indexterm>
|
|
<para>To flush items from the cache, invoke the <literal>flushEntries</literal> method
|
|
of the <classname>LDAPCache</classname> object. You can flush either selected
|
|
items or all items from the cache.</para>
|
|
<itemizedlist>
|
|
<listitem><para>To flush selected items from the cache, specify the base DN
|
|
of the search requests that you want to flush. Specify a DN and search scope
|
|
as arguments to the <literal>flushEntries</literal> method. If the base DN
|
|
of a cached search request falls within the scope you specified, the search
|
|
request is flushed from the cache.</para></listitem>
|
|
</itemizedlist>
|
|
<para>For example, the following section of code flushes selected search requests
|
|
from the cache. If the base DN of a search request falls under the <literal>ou=People,dc=example,dc=com
|
|
</literal> subtree, the item is removed from the cache.</para>
|
|
<programlisting>LDAPCache myCache;
|
|
|
|
/* Perform search requests... */
|
|
|
|
/*
|
|
* Flush search requests with base DNs under
|
|
* ou=People,dc=example,dc=com.
|
|
*/
|
|
myCache.flushEntries("ou=People,dc=example,dc=com",
|
|
LDAPConnection.SCOPE_SUB);</programlisting>
|
|
<itemizedlist>
|
|
<listitem><para>To flush all items from the cache, pass <literal>null</literal> as
|
|
the first argument of the <literal>flushEntries</literal> method:</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<programlisting>myCache.flushEntries(null, 0);</programlisting>
|
|
</sect2>
|
|
<sect2 id="cache-stats"><title>Getting Cache Statistics</title>
|
|
<indexterm>
|
|
<primary>cache</primary>
|
|
<secondary>getting statistics</secondary>
|
|
</indexterm>
|
|
<itemizedlist>
|
|
<para>You can invoke the following methods of the <classname>LDAPCache</classname> object
|
|
to get statistics on the cache.</para>
|
|
<listitem><para>To get the total amount of available space in bytes that are
|
|
left in the cache, invoke the <literal>getAvailableSize</literal> method.</para>
|
|
</listitem>
|
|
<listitem><para>To get the array of base DNs of the search requests to be
|
|
cached, invoke the <literal>getBaseDNs</literal> method.</para></listitem>
|
|
<listitem><para>To get the total number of items that have been flushed from
|
|
the cache, not including items flushed when invoking the <literal>flushEntries</literal> method,
|
|
invoke the <literal>getNumFlushes</literal> method.</para></listitem>
|
|
<listitem><para>To get the maximum size of the cache in bytes, invoke the <literal>
|
|
getSize</literal> method.</para></listitem>
|
|
<listitem><para>To get the maximum amount of time that an item can be cached
|
|
in seconds, get the <literal>getTimeToLive</literal> method.</para></listitem>
|
|
</itemizedlist>
|
|
<itemizedlist>
|
|
<para>You can also get a running count of the number of requests that access
|
|
the cache.</para>
|
|
<listitem><para>To get the total number of requests for retrieving items from
|
|
the cache, invoke the <literal>getTotalOperation</literal> method.</para>
|
|
</listitem>
|
|
<listitem><para>To get the total number of requests that retrieved an item
|
|
from the cache, invoke the <literal>getNumHits</literal> method.</para>
|
|
</listitem>
|
|
<listitem><para>To get the total number of requests that failed to find and
|
|
retrieve an item from the cache, invoke the <literal>getNumMisses</literal> method.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
<para>For example, the following section of code gets and prints cache statistics.
|
|
</para>
|
|
<programlisting>LDAPConnection ld;
|
|
|
|
if ((ld != null) && ld.isConnected()) {
|
|
LDAPCache connCache = ld.getCache();
|
|
if (connCache != null) {
|
|
System.out.println("Cache size:\t\t" +
|
|
connCache.getSize()/1000 + " kbytes");
|
|
System.out.println("Available:\t\t" +
|
|
connCache.getAvailableSize()/1000 + " kbytes");
|
|
System.out.println( "Maximum age:\t\t" +
|
|
connCache.getTimeToLive()/1000 + " seconds");
|
|
System.out.println("Total hits:\t\t" +
|
|
connCache.getNumHits() + " hits" );
|
|
System.out.println("Total misses:\t\t" +
|
|
connCache.getNumMisses() + " misses" );
|
|
System.out.println("Total requests:\t\t" +
|
|
connCache.getTotalOperations() + " requests");
|
|
} else {
|
|
System.out.println(
|
|
"No cache associated with the connection.");
|
|
}
|
|
}</programlisting>
|
|
</sect2>
|
|
</sect1>
|
|
<sect1 id="cloning-connection"><title>Cloning a Connection With &DirectorySDKForJava;</title>
|
|
<indexterm>
|
|
<primary>connection</primary>
|
|
<secondary>cloning</secondary>
|
|
</indexterm>
|
|
<para>You can create several <classname>LDAPConnection</classname> objects
|
|
that share a single physical network connection to the LDAP server by invoking
|
|
the <literal>LDAPConnection.clone</literal> method.</para>
|
|
<itemizedlist>
|
|
<para>Clones have the following properties:</para>
|
|
<listitem><para>If you clone an object before a connection is made to the
|
|
server, the cloned object does not share the same connection as the original
|
|
object.</para></listitem>
|
|
<listitem><para>Each clone can disconnect from the server without affecting
|
|
the connection for the other clones. The network connection remains in an
|
|
open state until all clones have either disconnected or gone out of scope.</para>
|
|
</listitem>
|
|
<listitem><para>If the clone disconnects or reconnects, the clone is completely
|
|
dissociated from the source object and other clones.</para></listitem>
|
|
<listitem><para>A cloned <classname>LDAPConnection</classname> object has
|
|
a separate set of session preferences and constraints. In other words, the
|
|
clone is associated with its own <classname>LDAPSearchConstraints</classname> object.
|
|
Changes to an option or to a search constraint only affect requests issued
|
|
using that object.</para><para>For example, suppose an <classname>LDAPConnection</classname> object
|
|
allows a maximum of 100 results to be returned from a search. If you clone
|
|
an <classname>LDAPConnection</classname> object, you can change the maximum
|
|
number of results in the clone from 100 to 200. Yet, the initial object still
|
|
allows only 100 results to be returned.</para></listitem>
|
|
<listitem><para>All clones are authenticated to the server as the same user.
|
|
If you authenticate again to the server as a different user, the current clone
|
|
is disconnected. The clone connects separately to the server. The <classname>LDAPConnection
|
|
</classname> object is no longer a clone of another <classname>LDAPConnection</classname> object.
|
|
</para></listitem>
|
|
</itemizedlist>
|
|
</sect1>
|
|
<sect1 id="handling-dns"><title>Manipulating Distinguished Names With &DirectorySDKForJava;</title>
|
|
<indexterm>
|
|
<primary>distinguished names</primary>
|
|
<secondary>manipulating</secondary>
|
|
</indexterm>
|
|
<para>A distinguished name (DN) uniquely identifies an entry in the directory
|
|
tree. You can get the DN for an entry as explained in <olink
|
|
type="auto-generated" targetptr="searching-results-dns">Getting Distinguished
|
|
Names</olink>. Alternatively, you can specify a DN to read an entry from the
|
|
directory as explained in <olink type="auto-generated" targetptr="searching-read">
|
|
Reading an Entry With Directory SDK for Java</olink>. &DirectorySDKForJava; includes
|
|
a utility class, <classname>LDAPDN</classname>, that provides
|
|
methods for manipulating DNs.</para>
|
|
<para>If you want to access individual components of a distinguished name
|
|
or a relative distinguished name, invoke the <literal>LDAPDN.explodeDN</literal> method
|
|
or the <literal>LDAPDN.explodeRDN</literal> method.</para>
|
|
<para>Both methods return an array of <classname>String</classname> objects
|
|
that represent the individual components of the distinguished name.</para>
|
|
<para>You can specify whether or not you want the names of the components
|
|
included in the array by using the <parameter>notypes</parameter> parameter.</para>
|
|
<itemizedlist>
|
|
<listitem><para>Set <parameter>notypes</parameter> to <literal>false</literal> if
|
|
you want to include component attribute types in the array.</para>
|
|
<programlisting>LDAPDN.explodeDN("uid=bjensen,ou=People,dc=example,dc=com", false);
|
|
</programlisting>
|
|
<para>The method returns the array <literal>{"uid=bjensen", "ou=People", "dc=example",
|
|
"dc=com"}</literal>.</para></listitem>
|
|
<listitem><para>Set <parameter>notypes</parameter> to <literal>true</literal> if
|
|
you do not want component attribute types returned in the array.</para>
|
|
<programlisting>LDAPDN.explodeDN("uid=bjensen,ou=People,dc=example,dc=com", true);
|
|
</programlisting>
|
|
<para>The method returns the array <literal>{"bjensen", "People", "example",
|
|
"com"}</literal>.</para></listitem>
|
|
</itemizedlist>
|
|
</sect1>
|
|
</chapter>
|