/*
* 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-2010 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.*;
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.
*
* @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.
*
* Since abandon requests do not have a response, invoking the method
* {@code get()} on the returned future will not block, nor return anything
* (it is {@code Void}), but may throw an exception if a problem occurred
* while sending the 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.
* @return An future whose result is {@code Void}.
* @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}.
*/
FutureResult abandon(AbandonRequest request)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
/**
* Adds an entry to the Directory Server using the provided add request. Any
* intermediate responses will be ignored.
*
* @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 super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
/**
* Adds an entry to the Directory Server using the provided add request.
*
* @param request
* The add 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 intermediateResponseHandler
* An intermediate response handler which can be used to process any
* intermediate responses 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 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 super Result> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
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. Any
* intermediate responses will be ignored.
*
* @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 super BindResult> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
/**
* Authenticates to the Directory Server using the provided bind request.
*
* @param request
* The bind 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 intermediateResponseHandler
* An intermediate response handler which can be used to process any
* intermediate responses 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 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 super BindResult> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
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) throws NullPointerException;
/**
* Compares an entry in the Directory Server using the provided compare
* request. Any intermediate responses will be ignored.
*
* @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 super CompareResult> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
/**
* Compares an entry in the Directory Server using the provided compare
* request.
*
* @param request
* The compare 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 intermediateResponseHandler
* An intermediate response handler which can be used to process any
* intermediate responses 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 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 super CompareResult> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
/**
* Deletes an entry from the Directory Server using the provided delete
* request. Any intermediate responses will be ignored.
*
* @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 super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
/**
* Deletes an entry from the Directory Server using the provided delete
* request.
*
* @param request
* The delete 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 intermediateResponseHandler
* An intermediate response handler which can be used to process any
* intermediate responses 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 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 super Result> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
/**
* Requests that the Directory Server performs the provided extended request.
* Any intermediate responses will be ignored.
*
* @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 super R> 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 resultHandler
* A result handler which can be used to asynchronously process the
* operation result when it is received, may be {@code null}.
* @param intermediateResponseHandler
* An intermediate response handler which can be used to process any
* intermediate responses 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 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 super R> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
/**
* Returns a synchronous connection sharing the same underlying network
* connection as this asynchronous connection.
*
* @return A synchronous connection sharing the same underlying network
* connection as this asynchronous connection.
*/
Connection getSynchronousConnection();
/**
* 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 {@code true} if this connection has not been closed and no fatal
* errors have been detected. This method is guaranteed to return
* {@code false} only when it is called after the method {@code close} has
* been called.
*
* @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. Any intermediate responses will be ignored.
*
* @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 super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
/**
* Modifies an entry in the Directory Server using the provided modify
* request.
*
* @param request
* The modify 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 intermediateResponseHandler
* An intermediate response handler which can be used to process any
* intermediate responses 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 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 super Result> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
/**
* Renames an entry in the Directory Server using the provided modify DN
* request. Any intermediate responses will be ignored.
*
* @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 super Result> 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 resultHandler
* A result handler which can be used to asynchronously process the
* operation result when it is received, may be {@code null}.
* @param intermediateResponseHandler
* An intermediate response handler which can be used to process any
* intermediate responses 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 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 super Result> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
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 super SearchResultEntry> 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 super RootDSE> 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 super Schema> 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 super Schema> 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. Any
* intermediate responses will be ignored.
*
* @param request
* The search request.
* @param handler
* 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,
SearchResultHandler handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
/**
* Searches the Directory Server using the provided search request.
*
* @param request
* The search request.
* @param resultHandler
* 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}.
* @param intermediateResponseHandler
* An intermediate response handler which can be used to process any
* intermediate responses 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,
SearchResultHandler resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
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 super SearchResultEntry> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
}