/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2009 Sun Microsystems, Inc. */ package org.opends.sdk; import java.io.Closeable; import java.util.Collection; import org.opends.sdk.requests.*; import org.opends.sdk.responses.BindResult; import org.opends.sdk.responses.CompareResult; import org.opends.sdk.responses.Result; import org.opends.sdk.responses.SearchResultEntry; import org.opends.sdk.schema.Schema; /** * An asynchronous connection with a Directory Server over which read * and update operations may be performed. See RFC 4511 for the LDAPv3 * protocol specification and more information about the types of * operations defined in LDAP. *

*

Operation processing

*

* All operations are performed asynchronously and return a * {@link FutureResult} or sub-type thereof which can be used for * retrieving the result using the {@link FutureResult#get} method. * Operation failures, for whatever reason, are signalled by the * {@link FutureResult#get()} method throwing an * {@link ErrorResultException}. *

* Synchronous operations are easily simulated by immediately getting * the result: * *

 * Connection connection = ...;
 * AddRequest request = ...;
 * // Will block until operation completes, and
 * // throws exception on failure.
 * connection.add(request).get();
 * 
* * Operations can be performed in parallel while taking advantage of the * simplicity of a synchronous application design: * *
 * Connection connection1 = ...;
 * Connection connection2 = ...;
 * AddRequest request = ...;
 * // Add the entry to the first server (don't block).
 * FutureResult future1 = connection1.add(request);
 * // Add the entry to the second server (in parallel).
 * FutureResult future2 = connection2.add(request);
 * // Total time = is O(1) instead of O(n).
 * future1.get();
 * future2.get();
 * 
* * More complex client applications can take advantage of a fully * asynchronous event driven design using {@link ResultHandler}s: * *
 * Connection connection = ...;
 * SearchRequest request = ...;
 * // Process results in the search result handler
 * // in a separate thread.
 * SearchResponseHandler handle = ...;
 * connection.search(request, handler);
 * 
*

*

Closing connections

*

* Applications must ensure that a connection is closed by calling * {@link #close()} even if a fatal error occurs on the connection. Once * a connection has been closed by the client application, any attempts * to continue to use the connection will result in an * {@link IllegalStateException} being thrown. Note that, if a fatal * error is encountered on the connection, then the application can * continue to use the connection. In this case all requests subsequent * to the failure will fail with an appropriate * {@link ErrorResultException} when their result is retrieved. *

*

Event notification

*

* Applications can choose to be notified when a connection is closed by * the application, receives an unsolicited notification, or experiences * a fatal error by registering a {@link ConnectionEventListener} with * the connection using the {@link #addConnectionEventListener} method. *

*

TO DO

*

*

* * @see RFC 4511 - * Lightweight Directory Access Protocol (LDAP): The Protocol */ public interface AsynchronousConnection extends Closeable { /** * Abandons the unfinished operation identified in the provided * abandon request. *

* Note: a more convenient approach to abandoning unfinished * operations is provided via the {@link FutureResult#cancel(boolean)} * method. * * @param request * The request identifying the operation to be abandoned. * @throws UnsupportedOperationException * If this connection does not support abandon operations. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. * @throws NullPointerException * If {@code request} was {@code null}. */ void abandon(AbandonRequest request) throws UnsupportedOperationException, IllegalStateException, NullPointerException; /** * Adds an entry to the Directory Server using the provided add * request. * * @param request * The add request. * @param handler * A result handler which can be used to asynchronously * process the operation result when it is received, may be * {@code null}. * @return A future representing the result of the operation. * @throws UnsupportedOperationException * If this connection does not support add operations. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. * @throws NullPointerException * If {@code request} was {@code null}. */ FutureResult add(AddRequest request, ResultHandler handler) throws UnsupportedOperationException, IllegalStateException, NullPointerException; /** * Registers the provided connection event listener so that it will be * notified when this connection is closed by the application, * receives an unsolicited notification, or experiences a fatal error. * * @param listener * The listener which wants to be notified when events occur * on this connection. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. * @throws NullPointerException * If the {@code listener} was {@code null}. */ void addConnectionEventListener(ConnectionEventListener listener) throws IllegalStateException, NullPointerException; /** * Authenticates to the Directory Server using the provided bind * request. * * @param request * The bind request. * @param handler * A result handler which can be used to asynchronously * process the operation result when it is received, may be * {@code null}. * @return A future representing the result of the operation. * @throws UnsupportedOperationException * If this connection does not support bind operations. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. * @throws NullPointerException * If {@code request} was {@code null}. */ FutureResult bind(BindRequest request, ResultHandler handler) throws UnsupportedOperationException, IllegalStateException, NullPointerException; /** * Releases any resources associated with this connection. For * physical connections to a Directory Server this will mean that an * unbind request is sent and the underlying socket is closed. *

* Other connection implementations may behave differently, and may * choose not to send an unbind request if its use is inappropriate * (for example a pooled connection will be released and returned to * its connection pool without ever issuing an unbind request). *

* This method is semantically equivalent to the following code: * *

   * UnbindRequest request = Requests.newUnbindRequest();
   * connection.close(request);
   * 
* * Calling {@code close} on a connection that is already closed has no * effect. */ void close(); /** * Releases any resources associated with this connection. For * physical connections to a Directory Server this will mean that the * provided unbind request is sent and the underlying socket is * closed. *

* Other connection implementations may behave differently, and may * choose to ignore the provided unbind request if its use is * inappropriate (for example a pooled connection will be released and * returned to its connection pool without ever issuing an unbind * request). *

* Calling {@code close} on a connection that is already closed has no * effect. * * @param request * The unbind request to use in the case where a physical * connection is closed. * @param reason * A reason describing why the connection was closed. * @throws NullPointerException * If {@code request} was {@code null}. */ void close(UnbindRequest request, String reason); /** * Compares an entry in the Directory Server using the provided * compare request. * * @param request * The compare request. * @param handler * A result handler which can be used to asynchronously * process the operation result when it is received, may be * {@code null}. * @return A future representing the result of the operation. * @throws UnsupportedOperationException * If this connection does not support compare operations. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. * @throws NullPointerException * If {@code request} was {@code null}. */ FutureResult compare(CompareRequest request, ResultHandler handler) throws UnsupportedOperationException, IllegalStateException, NullPointerException; /** * Deletes an entry from the Directory Server using the provided * delete request. * * @param request * The delete request. * @param handler * A result handler which can be used to asynchronously * process the operation result when it is received, may be * {@code null}. * @return A future representing the result of the operation. * @throws UnsupportedOperationException * If this connection does not support delete operations. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. * @throws NullPointerException * If {@code request} was {@code null}. */ FutureResult delete(DeleteRequest request, ResultHandler handler) throws UnsupportedOperationException, IllegalStateException, NullPointerException; /** * Requests that the Directory Server performs the provided extended * request. * * @param * The type of result returned by the extended request. * @param request * The extended request. * @param handler * A result handler which can be used to asynchronously * process the operation result when it is received, may be * {@code null}. * @return A future representing the result of the operation. * @throws UnsupportedOperationException * If this connection does not support extended operations. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. * @throws NullPointerException * If {@code request} was {@code null}. */ FutureResult extendedRequest( ExtendedRequest request, ResultHandler handler) throws UnsupportedOperationException, IllegalStateException, NullPointerException; /** * Indicates whether or not this connection has been explicitly closed * by calling {@code close}. This method will not return {@code true} * if a fatal error has occurred on the connection unless {@code * close} has been called. * * @return {@code true} if this connection has been explicitly closed * by calling {@code close}, or {@code false} otherwise. */ boolean isClosed(); /** * Returns true if the connection has not been closed and is still valid. * * @return {@code true} if the connection is valid, {@code false} otherwise. */ boolean isValid(); /** * Modifies an entry in the Directory Server using the provided modify * request. * * @param request * The modify request. * @param handler * A result handler which can be used to asynchronously * process the operation result when it is received, may be * {@code null}. * @return A future representing the result of the operation. * @throws UnsupportedOperationException * If this connection does not support modify operations. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. * @throws NullPointerException * If {@code request} was {@code null}. */ FutureResult modify(ModifyRequest request, ResultHandler handler) throws UnsupportedOperationException, IllegalStateException, NullPointerException; /** * Renames an entry in the Directory Server using the provided modify * DN request. * * @param request * The modify DN request. * @param handler * A result handler which can be used to asynchronously * process the operation result when it is received, may be * {@code null}. * @return A future representing the result of the operation. * @throws UnsupportedOperationException * If this connection does not support modify DN operations. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. * @throws NullPointerException * If {@code request} was {@code null}. */ FutureResult modifyDN(ModifyDNRequest request, ResultHandler handler) throws UnsupportedOperationException, IllegalStateException, NullPointerException; /** * Reads the named entry from the Directory Server. *

* If the requested entry is not returned by the Directory Server then * the request will fail with an {@link EntryNotFoundException}. More * specifically, the returned future will never return {@code null}. *

* This method is equivalent to the following code: * *

   * SearchRequest request = new SearchRequest(name,
   *     SearchScope.BASE_OBJECT, "(objectClass=*)", attributeDescriptions);
   * connection.searchSingleEntry(request, resultHandler, p);
   * 
* * @param name * The distinguished name of the entry to be read. * @param attributeDescriptions * The names of the attributes to be included with the entry, * which may be {@code null} or empty indicating that all * user attributes should be returned. * @param handler * A result handler which can be used to asynchronously * process the operation result when it is received, may be * {@code null}. * @return A future representing the result of the operation. * @throws UnsupportedOperationException * If this connection does not support search operations. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. * @throws NullPointerException * If the {@code name} was {@code null}. */ FutureResult readEntry(DN name, Collection attributeDescriptions, ResultHandler handler) throws UnsupportedOperationException, IllegalStateException, NullPointerException; /** * Reads the Root DSE from the Directory Server. *

* If the Root DSE is not returned by the Directory Server then the * request will fail with an {@link EntryNotFoundException}. More * specifically, the returned future will never return {@code null}. * * @param handler * A result handler which can be used to asynchronously * process the operation result when it is received, may be * {@code null}. * @return A future representing the result of the operation. * @throws UnsupportedOperationException * If this connection does not support search operations. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. */ FutureResult readRootDSE(ResultHandler handler) throws UnsupportedOperationException, IllegalStateException; /** * Reads the schema from the Directory Server contained in the named * subschema sub-entry. *

* If the requested schema is not returned by the Directory Server * then the request will fail with an {@link EntryNotFoundException}. * More specifically, the returned future will never return {@code * null}. *

* Implementations may choose to perform optimizations such as * caching. * * @param name * The distinguished name of the subschema sub-entry. * @param handler * A result handler which can be used to asynchronously * process the operation result when it is received, may be * {@code null}. * @return A future representing the result of the operation. * @throws UnsupportedOperationException * If this connection does not support search operations. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. */ FutureResult readSchema(DN name, ResultHandler handler) throws UnsupportedOperationException, IllegalStateException; /** * Reads the schema from the Directory Server which applies to the * named entry. *

* If the requested entry or its associated schema are not returned by * the Directory Server then the request will fail with an * {@link EntryNotFoundException}. More specifically, the returned * future will never return {@code null}. *

* A typical implementation will first read the {@code * subschemaSubentry} attribute of the entry in order to locate the * schema. However, implementations may choose to perform other * optimizations, such as caching. * * @param name * The distinguished name of the entry whose schema is to be * located. * @param handler * A result handler which can be used to asynchronously * process the operation result when it is received, may be * {@code null}. Optional additional handler parameter. * @return A future representing the result of the operation. * @throws UnsupportedOperationException * If this connection does not support search operations. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. */ FutureResult readSchemaForEntry(DN name, ResultHandler handler) throws UnsupportedOperationException, IllegalStateException; /** * Removes the provided connection event listener from this connection * so that it will no longer be notified when this connection is * closed by the application, receives an unsolicited notification, or * experiences a fatal error. * * @param listener * The listener which no longer wants to be notified when * events occur on this connection. * @throws NullPointerException * If the {@code listener} was {@code null}. */ void removeConnectionEventListener(ConnectionEventListener listener) throws NullPointerException; /** * Searches the Directory Server using the provided search request. * * @param request * The search request. * @param resultHandler * A result handler which can be used to asynchronously * process the operation result when it is received, may be * {@code null}. * @param searchResulthandler * A search result handler which can be used to * asynchronously process the search result entries and * references as they are received, may be {@code null}. * @return A future representing the result of the operation. * @throws UnsupportedOperationException * If this connection does not support search operations. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. * @throws NullPointerException * If {@code request} was {@code null}. */ FutureResult search(SearchRequest request, ResultHandler resultHandler, SearchResultHandler searchResulthandler) throws UnsupportedOperationException, IllegalStateException, NullPointerException; /** * Searches the Directory Server for a single entry using the provided * search request. *

* If the requested entry is not returned by the Directory Server then * the request will fail with an {@link EntryNotFoundException}. More * specifically, the returned future will never return {@code null}. * If multiple matching entries are returned by the Directory Server * then the request will fail with an * {@link MultipleEntriesFoundException}. * * @param request * The search request. * @param handler * A result handler which can be used to asynchronously * process the operation result when it is received, may be * {@code null}. * @return A future representing the result of the operation. * @throws UnsupportedOperationException * If this connection does not support search operations. * @throws IllegalStateException * If this connection has already been closed, i.e. if * {@code isClosed() == true}. * @throws NullPointerException * If the {@code request} was {@code null}. */ FutureResult searchSingleEntry( SearchRequest request, ResultHandler handler) throws UnsupportedOperationException, IllegalStateException, NullPointerException; }