You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2010/02/15 02:37:47 UTC
svn commit: r910150 [2/11] - in /directory: apacheds/trunk/
apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/interceptor/context/
apacheds/trunk/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/messages/co...
Modified: directory/clients/ldap/trunk/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/LdapConnection.java
URL: http://svn.apache.org/viewvc/directory/clients/ldap/trunk/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/LdapConnection.java?rev=910150&r1=910149&r2=910150&view=diff
==============================================================================
--- directory/clients/ldap/trunk/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/LdapConnection.java (original)
+++ directory/clients/ldap/trunk/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/LdapConnection.java Mon Feb 15 01:37:34 2010
@@ -32,7 +32,6 @@
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
@@ -42,18 +41,16 @@
import org.apache.directory.ldap.client.api.exception.InvalidConnectionException;
import org.apache.directory.ldap.client.api.exception.LdapException;
+import org.apache.directory.ldap.client.api.future.AddFuture;
import org.apache.directory.ldap.client.api.future.BindFuture;
+import org.apache.directory.ldap.client.api.future.CompareFuture;
+import org.apache.directory.ldap.client.api.future.DeleteFuture;
+import org.apache.directory.ldap.client.api.future.ExtendedFuture;
+import org.apache.directory.ldap.client.api.future.ModifyDnFuture;
+import org.apache.directory.ldap.client.api.future.ModifyFuture;
import org.apache.directory.ldap.client.api.future.ResponseFuture;
-import org.apache.directory.ldap.client.api.listener.AddListener;
-import org.apache.directory.ldap.client.api.listener.BindListener;
-import org.apache.directory.ldap.client.api.listener.CompareListener;
+import org.apache.directory.ldap.client.api.future.SearchFuture;
import org.apache.directory.ldap.client.api.listener.DeleteListener;
-import org.apache.directory.ldap.client.api.listener.ExtendedListener;
-import org.apache.directory.ldap.client.api.listener.IntermediateResponseListener;
-import org.apache.directory.ldap.client.api.listener.ModifyDnListener;
-import org.apache.directory.ldap.client.api.listener.ModifyListener;
-import org.apache.directory.ldap.client.api.listener.OperationResponseListener;
-import org.apache.directory.ldap.client.api.listener.SearchListener;
import org.apache.directory.ldap.client.api.message.AbandonRequest;
import org.apache.directory.ldap.client.api.message.AbstractMessage;
import org.apache.directory.ldap.client.api.message.AddRequest;
@@ -83,7 +80,6 @@
import org.apache.directory.shared.asn1.ber.IAsn1Container;
import org.apache.directory.shared.asn1.codec.DecoderException;
import org.apache.directory.shared.asn1.primitives.OID;
-import org.apache.directory.shared.ldap.codec.LdapConstants;
import org.apache.directory.shared.ldap.codec.LdapMessageCodec;
import org.apache.directory.shared.ldap.codec.LdapMessageContainer;
import org.apache.directory.shared.ldap.codec.LdapResultCodec;
@@ -140,11 +136,8 @@
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandlerAdapter;
-import org.apache.mina.core.session.IoEventType;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
-import org.apache.mina.filter.executor.ExecutorFilter;
-import org.apache.mina.filter.executor.UnorderedThreadPoolExecutor;
import org.apache.mina.filter.ssl.SslFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.slf4j.Logger;
@@ -154,6 +147,10 @@
/**
* This class is the base for every operations sent or received to and
* from a LDAP server.
+ *
+ * A connection instance is necessary to send requests to the server. The connection
+ * is valid until either the client closes it, the server closes it or the
+ * client does an unbind.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
@@ -190,11 +187,8 @@
/** A Message ID which is incremented for each operation */
private AtomicInteger messageId;
- /** a map to hold the response listeners based on the operation id */
- private Map<Integer, OperationResponseListener> listenerMap = new ConcurrentHashMap<Integer, OperationResponseListener>();
-
/** a map to hold the ResponseFutures for all operations */
- private Map<Integer, ResponseFuture> futureMap = new ConcurrentHashMap<Integer, ResponseFuture>();
+ private Map<Integer, ResponseFuture<? extends Response>> futureMap = new ConcurrentHashMap<Integer, ResponseFuture<? extends Response>>();
/** a map to hold the response queues related to the operations */
private Map<Integer, BlockingQueue<? extends Response>> respQueueMap =
@@ -264,6 +258,35 @@
throw new InvalidConnectionException( "Cannot connect on the server, the connection is invalid" );
}
}
+
+
+ private void addToFutureMap( int messageId, ResponseFuture<? extends Response> future )
+ {
+ //System.out.println( "Adding <" + messageId + ", " + future.getClass().getName() + ">" );
+ futureMap.put( messageId, future );
+ }
+
+
+ private ResponseFuture<? extends Response> getFromFutureMap( int messageId )
+ {
+ ResponseFuture<? extends Response> future = futureMap.remove( messageId );
+
+ if ( future != null )
+ {
+ //System.out.println( "Removing <" + messageId + ", " + future.getClass().getName() + ">" );
+ }
+
+ return future;
+ }
+
+
+ private ResponseFuture<? extends Response> peekFromFutureMap( int messageId )
+ {
+ ResponseFuture<? extends Response> future = futureMap.get( messageId );
+ //System.out.println( "Getting <" + messageId + ", " + future.getClass().getName() + ">" );
+
+ return future;
+ }
/**
@@ -443,7 +466,7 @@
config.setUseSsl( false );
config.setLdapPort( config.getDefaultLdapPort() );
config.setLdapHost( config.getDefaultLdapHost() );
- messageId = new AtomicInteger();
+ messageId = new AtomicInteger( 0 );
}
@@ -456,7 +479,8 @@
public LdapConnection( LdapConnectionConfig config )
{
this.config = config;
- messageId = new AtomicInteger();
+ messageId = new AtomicInteger( 0 );
+
}
@@ -471,7 +495,7 @@
config.setUseSsl( useSsl );
config.setLdapPort( useSsl ? config.getDefaultLdapsPort() : config.getDefaultLdapPort() );
config.setLdapHost( config.getDefaultLdapHost() );
- messageId = new AtomicInteger();
+ messageId = new AtomicInteger( 0 );
}
@@ -486,7 +510,7 @@
config.setUseSsl( false );
config.setLdapPort( config.getDefaultLdapPort() );
config.setLdapHost( server );
- messageId = new AtomicInteger();
+ messageId = new AtomicInteger( 0 );
}
@@ -503,7 +527,7 @@
config.setUseSsl( useSsl );
config.setLdapPort( useSsl ? config.getDefaultLdapsPort() : config.getDefaultLdapPort() );
config.setLdapHost( server );
- messageId = new AtomicInteger();
+ messageId = new AtomicInteger( 0 );
}
@@ -585,8 +609,8 @@
// Add an executor so that this connection can be used
// for handling more than one request (mainly because
// we may have to handle some abandon request)
- connector.getFilterChain().addLast( "executor",
- new ExecutorFilter( new UnorderedThreadPoolExecutor( 10 ), IoEventType.MESSAGE_RECEIVED ) );
+ /*connector.getFilterChain().addLast( "executor",
+ new ExecutorFilter( new OrderedThreadPoolExecutor( 10 ), IoEventType.MESSAGE_RECEIVED ) );*/
// Inject the protocolHandler
connector.setHandler( this );
@@ -675,87 +699,141 @@
throw new NullPointerException( msg );
}
- return add( new AddRequest( entry ), null );
+ return add( new AddRequest( entry ) );
+ }
+
+
+ /**
+ * Add an entry to the server asynchronously. This is a non blocking add :
+ * the user has to get for the response from the returned Future.
+ *
+ * @param entry The entry to add
+ * @result the add operation's Future
+ */
+ public AddFuture addAsync( Entry entry ) throws LdapException
+ {
+ if ( entry == null )
+ {
+ String msg = "Cannot add empty entry";
+ LOG.debug( msg );
+ throw new NullPointerException( msg );
+ }
+
+ return addAsync( new AddRequest( entry ) );
}
/**
* Add an entry present in the AddRequest to the server.
+ *
* @param addRequest the request object containing an entry and controls(if any)
* @return the add operation's response
* @throws LdapException
*/
public AddResponse add( AddRequest addRequest ) throws LdapException
{
- return add( addRequest, null );
+ AddFuture addFuture = addAsync( addRequest );
+
+ // Get the result from the future
+ try
+ {
+ // Read the response, waiting for it if not available immediately
+ long timeout = getTimeout( addRequest.getTimeout() );
+
+ // Get the response, blocking
+ AddResponse addResponse = ( AddResponse ) addFuture.get( timeout, TimeUnit.MILLISECONDS );
+
+ if ( addResponse == null )
+ {
+ // We didn't received anything : this is an error
+ LOG.error( "Add failed : timeout occured" );
+ throw new LdapException( TIME_OUT_ERROR );
+ }
+
+ if ( addResponse.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ // Everything is fine, return the response
+ LOG.debug( "Add successful : {}", addResponse );
+ }
+ else
+ {
+ // We have had an error
+ LOG.debug( "Add failed : {}", addResponse );
+ }
+
+ return addResponse;
+ }
+ catch ( TimeoutException te )
+ {
+ // Send an abandon request
+ if ( !addFuture.isCancelled() )
+ {
+ abandon( addRequest.getMessageId() );
+ }
+
+ // We didn't received anything : this is an error
+ LOG.error( "Add failed : timeout occured" );
+ throw new LdapException( TIME_OUT_ERROR );
+ }
+ catch ( Exception ie )
+ {
+ ie.printStackTrace();
+
+ // Catch all other exceptions
+ LOG.error( NO_RESPONSE_ERROR, ie );
+ LdapException ldapException = new LdapException( NO_RESPONSE_ERROR );
+ ldapException.initCause( ie );
+
+ // Send an abandon request
+ if ( !addFuture.isCancelled() )
+ {
+ abandon( addRequest.getMessageId() );
+ }
+
+ throw ldapException;
+ }
}
/**
* Add an entry present in the AddRequest to the server.
+ *
* @param addRequest the request object containing an entry and controls(if any)
- * @param listener A listener used for an asynchronous add operation
- * @return the add operation's response, null if non-null listener is provided
+ * @return the add operation's response
* @throws LdapException
*/
- public AddResponse add( AddRequest addRequest, AddListener listener ) throws LdapException
+ public AddFuture addAsync( AddRequest addRequest ) throws LdapException
{
checkSession();
AddRequestCodec addReqCodec = new AddRequestCodec();
int newId = messageId.incrementAndGet();
- LdapMessageCodec message = new LdapMessageCodec();
- message.setMessageId( newId );
+
+ addRequest.setMessageId( newId );
addReqCodec.setMessageId( newId );
addReqCodec.setEntry( addRequest.getEntry() );
addReqCodec.setEntryDn( addRequest.getEntry().getDn() );
setControls( addRequest.getControls(), addReqCodec );
- message.setProtocolOP( addReqCodec );
-
- BlockingQueue<Response> addResponseQueue = new LinkedBlockingQueue<Response>();
- respQueueMap.put( newId, addResponseQueue );
-
- ResponseFuture<Response> addFuture = new ResponseFuture<Response>( addResponseQueue );
- futureMap.put( newId, addFuture );
+ AddFuture addFuture = new AddFuture( this, newId );
+ addToFutureMap( newId, addFuture );
// Send the request to the server
- ldapSession.write( message );
+ WriteFuture writeFuture = ldapSession.write( addReqCodec );
- AddResponse response = null;
- if ( listener == null )
+ // Wait for the message to be sent to the server
+ if ( !writeFuture.awaitUninterruptibly( getTimeout( 0 ) ) )
{
- try
- {
- long timeout = getTimeout( addRequest.getTimeout() );
- response = ( AddResponse ) addFuture.get( timeout, TimeUnit.MILLISECONDS );
+ // We didn't received anything : this is an error
+ LOG.error( "Add failed : timeout occured" );
- if ( response == null )
- {
- LOG.error( "Add failed : timeout occured" );
- throw new LdapException( TIME_OUT_ERROR );
- }
- }
- catch ( InterruptedException ie )
- {
- LOG.error( OPERATION_CANCELLED, ie );
- throw new LdapException( OPERATION_CANCELLED, ie );
- }
- catch ( Exception e )
- {
- LOG.error( NO_RESPONSE_ERROR );
- removeFromMaps( newId );
- throw new LdapException( NO_RESPONSE_ERROR, e );
- }
- }
- else
- {
- listenerMap.put( newId, listener );
+ throw new LdapException( TIME_OUT_ERROR );
}
-
- return response;
+
+ // Ok, done return the future
+ return addFuture;
}
@@ -810,63 +888,48 @@
*/
private void abandonInternal( AbandonRequest abandonRequest )
{
- // Create the new message and update the messageId
- LdapMessageCodec message = new LdapMessageCodec();
+ // Create the inner abandonRequest
+ AbandonRequestCodec request = new AbandonRequestCodec();
- // Creates the messageID and stores it into the
- // initial message and the transmitted message.
+ // Todo : The Abandon messageID is always 0
int newId = messageId.incrementAndGet();
abandonRequest.setMessageId( newId );
- message.setMessageId( newId );
-
- // Create the inner abandonRequest
- AbandonRequestCodec request = new AbandonRequestCodec();
+ request.setMessageId( newId );
// Inject the data into the request
request.setAbandonedMessageId( abandonRequest.getAbandonedMessageId() );
- // Inject the request into the message
- message.setProtocolOP( request );
-
// Inject the controls
- setControls( abandonRequest.getControls(), message );
+ setControls( abandonRequest.getControls(), request );
LOG.debug( "-----------------------------------------------------------------" );
- LOG.debug( "Sending request \n{}", message );
+ LOG.debug( "Sending request \n{}", request );
// Send the request to the server
- ldapSession.write( message );
+ ldapSession.write( request );
// remove the associated listener if any
int abandonId = abandonRequest.getAbandonedMessageId();
- ResponseFuture rf = futureMap.remove( abandonId );
- OperationResponseListener listener = listenerMap.remove( abandonId );
+ ResponseFuture rf = getFromFutureMap( abandonId );
clearMaps();
// if the listener is not null, this is a async operation and no need to
// send cancel signal on future, sending so will leave a dangling poision object in the corresponding queue
- if ( listener != null )
+ // this is a sync operation send cancel signal to the corresponding ResponseFuture
+ if ( rf != null )
{
- LOG.debug( "removed the listener associated with the abandoned operation with id {}", abandonId );
+ LOG.debug( "sending cancel signal to future" );
+ rf.cancel( true );
}
else
- // this is a sync operation send cancel signal to the corresponding ResponseFuture
{
- if ( rf != null )
- {
- LOG.debug( "sending cancel signal to future" );
- rf.cancel( true );
- }
- else
- {
- // this shouldn't happen
- LOG
- .error(
- "There is no future asscoiated with operation message ID {}, perhaps the operation would have been completed",
- abandonId );
- }
+ // this shouldn't happen
+ LOG
+ .error(
+ "There is no future asscoiated with operation message ID {}, perhaps the operation would have been completed",
+ abandonId );
}
}
@@ -885,13 +948,26 @@
/**
+ * Anonymous asynchronous Bind on a server.
+ *
+ * @return The BindFuture
+ */
+ public BindFuture bindAsync() throws LdapException, IOException
+ {
+ LOG.debug( "Anonymous Bind request" );
+
+ return bindAsync( StringTools.EMPTY, StringTools.EMPTY_BYTES );
+ }
+
+
+ /**
* An Unauthenticated Authentication Bind on a server. (cf RFC 4513,
* par 5.1.2)
*
* @param name The name we use to authenticate the user. It must be a
* valid DN
* @return The BindResponse LdapResponse
- */
+ *
public BindResponse bind( String name ) throws Exception
{
LOG.debug( "Bind request : {}", name );
@@ -901,26 +977,18 @@
/**
- * An Unauthenticated Authentication Bind on a server. (cf RFC 4513,
+ * An Unauthenticated Authentication asynchronous Bind on a server. (cf RFC 4513,
* par 5.1.2)
*
- * @param name The name we use to authenticate the user.
- * @return The BindResponse LdapResponse
- */
- public BindResponse bind( LdapDN name ) throws Exception
+ * @param name The name we use to authenticate the user. It must be a
+ * valid DN
+ * @return The BindFuture
+ *
+ public BindFuture bindAsync( String name ) throws Exception
{
- if ( name == null )
- {
- LOG.debug( "Anonymous Bind request : {}", name );
-
- return bind( StringTools.EMPTY, StringTools.EMPTY_BYTES );
- }
- else
- {
- LOG.debug( "Unauthenticated Bind request : {}", name );
+ LOG.debug( "Bind request : {}", name );
- return bind( name.getName(), StringTools.EMPTY_BYTES );
- }
+ return bindAsync( name, StringTools.EMPTY_BYTES );
}
@@ -941,6 +1009,22 @@
/**
+ * Simple asynchronous Bind on a server.
+ *
+ * @param name The name we use to authenticate the user. It must be a
+ * valid DN
+ * @param credentials The password. It can't be null
+ * @return The BindResponse LdapResponse
+ */
+ public BindFuture bindAsync( String name, String credentials ) throws LdapException, IOException
+ {
+ LOG.debug( "Bind request : {}", name );
+
+ return bindAsync( name, StringTools.getBytesUtf8( credentials ) );
+ }
+
+
+ /**
* Simple Bind on a server.
*
* @param name The name we use to authenticate the user. It must be a
@@ -964,6 +1048,52 @@
/**
+ * Simple asynchronous Bind on a server.
+ *
+ * @param name The name we use to authenticate the user. It must be a
+ * valid DN
+ * @param credentials The password. It can't be null
+ * @return The BindResponse LdapResponse
+ */
+ public BindFuture bindAsync( LdapDN name, String credentials ) throws LdapException, IOException
+ {
+ LOG.debug( "Bind request : {}", name );
+
+ if ( name == null )
+ {
+ return bindAsync( StringTools.EMPTY, StringTools.getBytesUtf8( credentials ) );
+ }
+ else
+ {
+ return bindAsync( name.getName(), StringTools.getBytesUtf8( credentials ) );
+ }
+ }
+
+
+ /**
+ * Simple asynchronous Bind on a server.
+ *
+ * @param name The name we use to authenticate the user. It must be a
+ * valid DN
+ * @param credentials The password. It can't be null
+ * @return The BindResponse LdapResponse
+ */
+ public BindFuture bindAsync( LdapDN name, byte[] credentials ) throws LdapException, IOException
+ {
+ LOG.debug( "Bind request : {}", name );
+
+ if ( name == null )
+ {
+ return bindAsync( StringTools.EMPTY, credentials );
+ }
+ else
+ {
+ return bindAsync( name.getName(), credentials );
+ }
+ }
+
+
+ /**
* Simple Bind on a server.
*
* @param name The name we use to authenticate the user.
@@ -974,7 +1104,14 @@
{
LOG.debug( "Bind request : {}", name );
- return bind( name.getName(), credentials );
+ if ( name == null )
+ {
+ return bind( StringTools.EMPTY, credentials );
+ }
+ else
+ {
+ return bind( name.getName(), credentials );
+ }
}
@@ -986,7 +1123,8 @@
* @param credentials The password.
* @return The BindResponse LdapResponse
*/
- public BindResponse bind( String name, byte[] credentials ) throws LdapException, IOException
+ public BindResponse bind( String name, byte[] credentials )
+ throws LdapException, IOException
{
LOG.debug( "Bind request : {}", name );
@@ -995,21 +1133,30 @@
bindRequest.setName( name );
bindRequest.setCredentials( credentials );
- BindResponse response = bind( bindRequest );
+ return bind( bindRequest );
+ }
- if ( LOG.isDebugEnabled() )
- {
- if ( response.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
- {
- LOG.debug( " Bind successfull" );
- }
- else
- {
- LOG.debug( " Bind failure {}", response );
- }
- }
- return response;
+ /**
+ * Asynchronous Simple Bind on a server.
+ *
+ * @param name The name we use to authenticate the user. It must be a
+ * valid DN
+ * @param credentials The password.
+ * @return The BindFuture
+ */
+ public BindFuture bindAsync( String name, byte[] credentials ) throws LdapException, IOException
+ {
+ LOG.debug( "Bind request : {}", name );
+
+ // Create the BindRequest
+ BindRequest bindRequest = new BindRequest();
+ bindRequest.setName( name );
+ bindRequest.setCredentials( credentials );
+
+ BindFuture bindFuture = bindAsync( bindRequest );
+
+ return bindFuture;
}
@@ -1022,7 +1169,7 @@
*/
public BindResponse bind( BindRequest bindRequest ) throws LdapException, IOException
{
- BindFuture bindFuture = bind( bindRequest, null );
+ BindFuture bindFuture = bindAsync( bindRequest );
// Get the result from the future
try
@@ -1032,7 +1179,14 @@
// Get the response, blocking
BindResponse bindResponse = ( BindResponse ) bindFuture.get( timeout, TimeUnit.MILLISECONDS );
-
+
+ if ( bindResponse == null )
+ {
+ // We didn't received anything : this is an error
+ LOG.error( "Bind failed : timeout occured" );
+ throw new LdapException( TIME_OUT_ERROR );
+ }
+
if ( bindResponse.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
{
authenticated = true;
@@ -1078,40 +1232,116 @@
throw ldapException;
}
}
-
-
+
+
/**
- * Create a LdapMessage ready to be sent.
+ * Create a SearchRequestCodec ready to be sent.
*/
- private LdapMessageCodec createBindMessage( BindRequest bindRequest ) throws LdapException
+ private SearchRequestCodec createSearchMessage( SearchRequest searchRequest ) throws LdapException
{
- LdapMessageCodec bindMessage = new LdapMessageCodec();
+ // Create a new codec SearchRequest object
+ SearchRequestCodec request = new SearchRequestCodec();
// Creates the messageID and stores it into the
// initial message and the transmitted message.
- // As it's a Bind request, reset the MessageId
- // value to zero.
- messageId.set( 0 );
-
- // clear the mappings if any (in case of a second call to bind() without calling unBind())
- clearMaps();
-
- // the bind request should always start with message id 1 (One)
int newId = messageId.incrementAndGet();
- bindRequest.setMessageId( newId );
- bindMessage.setMessageId( newId );
-
- // Create a new codec BindRequest object
- BindRequestCodec request = new BindRequestCodec();
-
- // Set the version
- request.setVersion( LdapConnectionConfig.LDAP_V3 );
+ searchRequest.setMessageId( newId );
+ request.setMessageId( newId );
// Set the name
try
{
- LdapDN dn = new LdapDN( bindRequest.getName() );
- request.setName( dn );
+ LdapDN dn = new LdapDN( searchRequest.getBaseDn() );
+ request.setBaseObject( dn );
+ }
+ catch ( InvalidNameException ine )
+ {
+ String msg = "The given dn '" + searchRequest.getBaseDn() + "' is not valid";
+ LOG.error( msg );
+ LdapException ldapException = new LdapException( msg );
+ ldapException.initCause( ine );
+
+ throw ldapException;
+ }
+
+ // Set the scope
+ request.setScope( searchRequest.getScope() );
+
+ // Set the typesOnly flag
+ request.setDerefAliases( searchRequest.getDerefAliases().getValue() );
+
+ // Set the timeLimit
+ request.setTimeLimit( searchRequest.getTimeLimit() );
+
+ // Set the sizeLimit
+ request.setSizeLimit( searchRequest.getSizeLimit() );
+
+ // Set the typesOnly flag
+ request.setTypesOnly( searchRequest.getTypesOnly() );
+
+ // Set the filter
+ Filter filter = null;
+
+ try
+ {
+ ExprNode filterNode = FilterParser.parse( searchRequest.getFilter() );
+
+ filter = LdapTransformer.transformFilter( filterNode );
+ }
+ catch ( ParseException pe )
+ {
+ String msg = "The given filter '" + searchRequest.getFilter() + "' is not valid";
+ LOG.error( msg );
+ LdapException ldapException = new LdapException( msg );
+ ldapException.initCause( pe );
+
+ throw ldapException;
+ }
+
+ request.setFilter( filter );
+
+ // Set the attributes
+ Set<String> attributes = searchRequest.getAttributes();
+
+ if ( attributes != null )
+ {
+ for ( String attribute : attributes )
+ {
+ request.addAttribute( attribute );
+ }
+ }
+
+ // Add the controls
+ setControls( searchRequest.getControls(), request );
+
+ return request;
+ }
+
+
+ /**
+ * Create a BindRequest ready to be sent.
+ */
+ private BindRequestCodec createBindMessage( BindRequest bindRequest ) throws LdapException
+ {
+ // Create a new codec BindRequest object
+ BindRequestCodec bindRequestCodec = new BindRequestCodec();
+
+ // clear the mappings if any (in case of a second call to bind() without calling unBind())
+ clearMaps();
+
+ // Set the new messageId
+ int newId = messageId.incrementAndGet();
+ bindRequest.setMessageId( newId );
+ bindRequestCodec.setMessageId( newId );
+
+ // Set the version
+ bindRequestCodec.setVersion( LdapConnectionConfig.LDAP_V3 );
+
+ // Set the name
+ try
+ {
+ LdapDN dn = new LdapDN( bindRequest.getName() );
+ bindRequestCodec.setName( dn );
}
catch ( InvalidNameException ine )
{
@@ -1141,26 +1371,22 @@
}
// The authentication
- request.setAuthentication( authentication );
-
- // Stores the BindRequest into the message
- bindMessage.setProtocolOP( request );
+ bindRequestCodec.setAuthentication( authentication );
// Add the controls
- setControls( bindRequest.getControls(), bindMessage );
+ setControls( bindRequest.getControls(), bindRequestCodec );
- return bindMessage;
+ return bindRequestCodec;
}
/**
- * Do a non-blocking bind
+ * Do an asynchronous bind, based on a BindRequest.
*
* @param bindRequest The BindRequest to send
- * @param listener The listener
* @return BindFuture A future
*/
- public BindFuture bind( BindRequest bindRequest, BindListener bindListener ) throws LdapException, IOException
+ public BindFuture bindAsync( BindRequest bindRequest ) throws LdapException, IOException
{
// First switch to anonymous state
authenticated = false;
@@ -1176,36 +1402,27 @@
int newId = bindMessage.getMessageId();
- if ( bindListener != null )
- {
- // This is an asynchronous bind
- listenerMap.put( newId, bindListener );
- }
-
LOG.debug( "-----------------------------------------------------------------" );
LOG.debug( "Sending request \n{}", bindMessage );
- BlockingQueue<BindResponse> bindResponseQueue = new LinkedBlockingQueue<BindResponse>();
- respQueueMap.put( newId, bindResponseQueue );
-
- // Create a future for this Bind opeation
- BindFuture bindFuture = new BindFuture( bindResponseQueue );
+ // Create a future for this Bind operation
+ BindFuture bindFuture = new BindFuture( this, newId );
- futureMap.put( newId, bindFuture );
-
- if ( bindListener != null )
- {
- // If this is an asynchronous operation, associate the ID
- // with the operation listener
- listenerMap.put( newId, bindListener );
- }
+ addToFutureMap( newId, bindFuture );
// Send the request to the server
WriteFuture writeFuture = ldapSession.write( bindMessage );
// Wait for the message to be sent to the server
- writeFuture.awaitUninterruptibly( timeOut );
+ if ( !writeFuture.awaitUninterruptibly( getTimeout( 0 ) ) )
+ {
+ // We didn't received anything : this is an error
+ LOG.error( "Bind failed : timeout occured" );
+
+ throw new LdapException( TIME_OUT_ERROR );
+ }
+ // Ok, done return the future
return bindFuture;
}
@@ -1240,12 +1457,12 @@
searchRequest.setDerefAliases( AliasDerefMode.DEREF_ALWAYS );
// Process the request in blocking mode
- return searchInternal( searchRequest, null );
+ return search( searchRequest );
}
/**
- * Do a search, on the base object, using the given filter. The
+ * Do an asynchronous search, on the base object, using the given filter. The
* SearchRequest parameters default to :
* Scope : ONE
* DerefAlias : ALWAYS
@@ -1255,194 +1472,143 @@
* Attributes : all the user's attributes.
* This method is blocking.
*
- * @param listener a SearchListener used to be informed when a result
- * has been found, or when the search is done
- * @param baseObject The base for the search. It must be a valid
+ * @param baseDn The base for the search. It must be a valid
* DN, and can't be emtpy
- * @param filter The filter to use for this search. It can't be empty
+ * @param filterString The filter to use for this search. It can't be empty
+ * @param scope The sarch scope : OBJECT, ONELEVEL or SUBTREE
* @return A cursor on the result.
*/
- public void search( SearchRequest searchRequest, SearchListener listener ) throws LdapException
+ public SearchFuture searchAsync( String baseDn, String filter, SearchScope scope, String... attributes )
+ throws LdapException
{
- searchInternal( searchRequest, listener );
- }
+ // Create a new SearchRequest object
+ SearchRequest searchRequest = new SearchRequest();
+ searchRequest.setBaseDn( baseDn );
+ searchRequest.setFilter( filter );
+ searchRequest.setScope( scope );
+ searchRequest.addAttributes( attributes );
+ searchRequest.setDerefAliases( AliasDerefMode.DEREF_ALWAYS );
- /**
- * performs search in a synchronous mode (as if a null search listener is passed)
- * @see #search(SearchRequest, SearchListener)
- */
- public Cursor<SearchResponse> search( SearchRequest searchRequest ) throws LdapException
- {
- return searchInternal( searchRequest, null );
+ // Process the request in blocking mode
+ return searchAsync( searchRequest );
}
- private Cursor<SearchResponse> searchInternal( SearchRequest searchRequest, SearchListener searchListener )
- throws LdapException
+ /**
+ * Do a search, on the base object, using the given filter. The
+ * SearchRequest parameters default to :
+ * Scope : ONE
+ * DerefAlias : ALWAYS
+ * SizeLimit : none
+ * TimeLimit : none
+ * TypesOnly : false
+ * Attributes : all the user's attributes.
+ * This method is blocking.
+ *
+ * @param searchRequest The search request to send to the server
+ * @return A Future
+ */
+ public SearchFuture searchAsync( SearchRequest searchRequest ) throws LdapException
{
// If the session has not been establish, or is closed, we get out immediately
checkSession();
- // Create the new message and update the messageId
- LdapMessageCodec searchMessage = new LdapMessageCodec();
+ // Create the server request
+ SearchRequestCodec request = createSearchMessage( searchRequest );
- // Creates the messageID and stores it into the
- // initial message and the transmitted message.
- int newId = messageId.incrementAndGet();
- searchRequest.setMessageId( newId );
- searchMessage.setMessageId( newId );
+ LOG.debug( "-----------------------------------------------------------------" );
+ LOG.debug( "Sending request \n{}", request );
- // Create a new codec SearchRequest object
- SearchRequestCodec request = new SearchRequestCodec();
+ SearchFuture searchFuture = new SearchFuture( this, request.getMessageId() );
+ addToFutureMap( request.getMessageId(), searchFuture );
- // Set the name
- try
- {
- LdapDN dn = new LdapDN( searchRequest.getBaseDn() );
- request.setBaseObject( dn );
- }
- catch ( InvalidNameException ine )
+ // Send the request to the server
+ WriteFuture writeFuture = ldapSession.write( request );
+
+ // Wait for the message to be sent to the server
+ if ( !writeFuture.awaitUninterruptibly( getTimeout( 0 ) ) )
{
- String msg = "The given dn '" + searchRequest.getBaseDn() + "' is not valid";
- LOG.error( msg );
- LdapException ldapException = new LdapException( msg );
- ldapException.initCause( ine );
+ // We didn't received anything : this is an error
+ LOG.error( "Search failed : timeout occured" );
- throw ldapException;
+ throw new LdapException( TIME_OUT_ERROR );
}
+
+ // Ok, done return the future
+ return searchFuture;
- // Set the scope
- request.setScope( searchRequest.getScope() );
-
- // Set the typesOnly flag
- request.setDerefAliases( searchRequest.getDerefAliases().getValue() );
-
- // Set the timeLimit
- request.setTimeLimit( searchRequest.getTimeLimit() );
-
- // Set the sizeLimit
- request.setSizeLimit( searchRequest.getSizeLimit() );
-
- // Set the typesOnly flag
- request.setTypesOnly( searchRequest.getTypesOnly() );
+ }
- // Set the filter
- Filter filter = null;
+ /**
+ * Performs search in a synchronous mode.
+ *
+ * @param searchRequest The search configuration
+ * @return A {@link Cursor} containing Entries and Referencs
+ * @throws LdapException @TODO
+ */
+ public Cursor<SearchResponse> search( SearchRequest searchRequest ) throws LdapException
+ {
+ SearchFuture searchFuture = searchAsync( searchRequest );
+ int messageId = searchRequest.getMessageId();
+
+ // Read the response, waiting for it if not available immediately
try
{
- ExprNode filterNode = FilterParser.parse( searchRequest.getFilter() );
+ long timeout = getTimeout( searchRequest.getTimeout() );
+ SearchResponse searchResponse = null;
+ List<SearchResponse> searchResponses = new ArrayList<SearchResponse>();
+
+ // We may have more than one response, so loop on the queue
+ do
+ {
+ searchResponse = ( SearchResponse ) searchFuture.get( timeout, TimeUnit.MILLISECONDS );
+
+ // Check that we didn't get out because of a timeout
+ if ( searchResponse == null )
+ {
+ // Send an abandon request
+ abandon( messageId );
+
+ // We didn't received anything : this is an error
+ LOG.error( "Search failed : timeout occured" );
+
+ // Remove the future from the map
+ removeFromFutureMaps( messageId );
- filter = LdapTransformer.transformFilter( filterNode );
- }
- catch ( ParseException pe )
- {
- String msg = "The given filter '" + searchRequest.getFilter() + "' is not valid";
- LOG.error( msg );
- LdapException ldapException = new LdapException( msg );
- ldapException.initCause( pe );
-
- throw ldapException;
- }
-
- request.setFilter( filter );
+ throw new LdapException( TIME_OUT_ERROR );
+ }
+
+ if ( !( searchResponse instanceof SearchResultDone ) )
+ {
+ searchResponses.add( searchResponse );
+ }
+ }
+ while ( !( searchResponse instanceof SearchResultDone ) );
- // Set the attributes
- Set<String> attributes = searchRequest.getAttributes();
+ LOG.debug( "Search successful, {} elements found", searchResponses.size() );
- if ( attributes != null )
+ return new ListCursor<SearchResponse>( searchResponses );
+ }
+ catch ( InterruptedException ie )
{
- for ( String attribute : attributes )
- {
- request.addAttribute( attribute );
- }
+ LOG.error( OPERATION_CANCELLED, ie );
+ throw new LdapException( OPERATION_CANCELLED, ie );
}
-
- // Stores the SearchRequest into the message
- searchMessage.setProtocolOP( request );
-
- // Add the controls
- setControls( searchRequest.getControls(), searchMessage );
-
- LOG.debug( "-----------------------------------------------------------------" );
- LOG.debug( "Sending request \n{}", searchMessage );
-
- BlockingQueue<Response> searchResponseQueue = new LinkedBlockingQueue<Response>();
- respQueueMap.put( newId, searchResponseQueue );
-
- ResponseFuture searchFuture = new ResponseFuture( searchResponseQueue );
- futureMap.put( newId, searchFuture );
-
- // Send the request to the server
- ldapSession.write( searchMessage );
-
- if ( searchListener == null )
+ catch ( Exception e )
{
- // Read the response, waiting for it if not available immediately
- try
- {
- long timeout = getTimeout( searchRequest.getTimeout() );
- SearchResponse response = null;
- List<SearchResponse> searchResponses = new ArrayList<SearchResponse>();
-
- // We may have more than one response, so loop on the queue
- do
- {
- response = ( SearchResponse ) searchFuture.get( timeout, TimeUnit.MILLISECONDS );
-
- // Check that we didn't get out because of a timeout
- if ( response == null )
- {
- // Send an abandon request
- abandon( searchMessage.getSearchRequest().getMessageId() );
-
- // We didn't received anything : this is an error
- LOG.error( "Search failed : timeout occured" );
-
- throw new LdapException( TIME_OUT_ERROR );
- }
- else
- {
- if ( ( response instanceof SearchResultEntry ) ||
- ( response instanceof SearchResultReference ) )
- {
- searchResponses.add( response );
- }
- }
- }
- while ( !( response instanceof SearchResultDone ) );
-
- LOG.debug( "Search successful, {} elements found", searchResponses.size() );
+ LOG.error( NO_RESPONSE_ERROR, e );
+ LdapException ldapException = new LdapException( NO_RESPONSE_ERROR );
+ ldapException.initCause( e );
- return new ListCursor<SearchResponse>( searchResponses );
- }
- catch ( InterruptedException ie )
+ // Send an abandon request
+ if ( !searchFuture.isCancelled() )
{
- LOG.error( OPERATION_CANCELLED, ie );
- throw new LdapException( OPERATION_CANCELLED, ie );
+ abandon( messageId );
}
- catch ( Exception e )
- {
- LOG.error( NO_RESPONSE_ERROR, e );
- LdapException ldapException = new LdapException( NO_RESPONSE_ERROR );
- ldapException.initCause( e );
-
- // Send an abandon request
- if ( !searchFuture.isCancelled() )
- {
- abandon( searchMessage.getSearchRequest().getMessageId() );
- }
- throw ldapException;
- }
- }
- else
- {
- // The listener will be called on a MessageReceived event,
- // no need to create a cursor
- listenerMap.put( newId, searchListener );
- return null;
+ throw ldapException;
}
}
@@ -1461,22 +1627,16 @@
// Create the UnbindRequest
UnBindRequestCodec unbindRequest = new UnBindRequestCodec();
- // Encode the request
- LdapMessageCodec unbindMessage = new LdapMessageCodec();
-
// Creates the messageID and stores it into the
// initial message and the transmitted message.
int newId = messageId.incrementAndGet();
unbindRequest.setMessageId( newId );
- unbindMessage.setMessageId( newId );
-
- unbindMessage.setProtocolOP( unbindRequest );
LOG.debug( "-----------------------------------------------------------------" );
- LOG.debug( "Sending Unbind request \n{}", unbindMessage );
+ LOG.debug( "Sending Unbind request \n{}", unbindRequest );
// Send the request to the server
- WriteFuture unbindFuture = ldapSession.write( unbindMessage );
+ WriteFuture unbindFuture = ldapSession.write( unbindRequest );
unbindFuture.awaitUninterruptibly();
@@ -1528,59 +1688,79 @@
{
// Feed the response and store it into the session
LdapMessageCodec response = ( LdapMessageCodec ) message;
-
- LOG.debug( "-------> {} Message received <-------", response.getMessageTypeName() );
+
+ LOG.debug( "-------> {} Message received <-------", response );
// this check is necessary to prevent adding an abandoned operation's
// result(s) to corresponding queue
- ResponseFuture rf = futureMap.get( response.getMessageId() );
+ ResponseFuture<? extends Response> responseFuture = peekFromFutureMap( response.getMessageId() );
- if ( rf == null )
+ if ( responseFuture == null )
{
- LOG.error( "There is no future associated with the messageId {}, ignoring the message", response
+ LOG.info( "There is no future associated with the messageId {}, ignoring the message", response
.getMessageId() );
return;
}
- SearchListener searchListener = null;
int messageId = response.getMessageId();
switch ( response.getMessageType() )
{
- case LdapConstants.ADD_RESPONSE:
- // Store the response into the responseQueue
- AddResponseCodec addRespCodec = response.getAddResponse();
+ case ADD_RESPONSE:
+ // Transform the response
+ AddResponseCodec addRespCodec = (AddResponseCodec)response;
addRespCodec.addControl( response.getCurrentControl() );
addRespCodec.setMessageId( messageId );
- futureMap.remove( addRespCodec.getMessageId() );
- AddListener addListener = ( AddListener ) listenerMap.remove( addRespCodec.getMessageId() );
- AddResponse addResp = convert( addRespCodec );
+ AddResponse addResponse = convert( addRespCodec );
- if ( addListener != null )
+ AddFuture addFuture = (AddFuture)responseFuture;
+
+ if ( addFuture == null )
{
- addListener.entryAdded( this, addResp );
+ LOG.error( "AddFuture is null" );
+ throw new LdapException( "AddFuture is null" );
}
- else
+
+ // remove the listener from the listener map
+ if ( LOG.isDebugEnabled() )
{
- BlockingQueue<AddResponse> respQueue = (BlockingQueue<AddResponse>)respQueueMap.remove( messageId );
- respQueue.add( addResp );
+ if ( addResponse.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ // Everything is fine, return the response
+ LOG.debug( "Add successful : {}", addResponse );
+ }
+ else
+ {
+ // We have had an error
+ LOG.debug( "Add failed : {}", addResponse );
+ }
}
+
+ // Store the response into the future
+ addFuture.set( addResponse );
+
+ // Remove the future from the map
+ removeFromFutureMaps( messageId );
break;
- case LdapConstants.BIND_RESPONSE:
- // Store the response into the responseQueue
- BindResponseCodec bindResponseCodec = response.getBindResponse();
+ case BIND_RESPONSE:
+ // Transform the response
+ BindResponseCodec bindResponseCodec = (BindResponseCodec)response;
bindResponseCodec.setMessageId( messageId );
bindResponseCodec.addControl( response.getCurrentControl() );
BindResponse bindResponse = convert( bindResponseCodec );
- futureMap.remove( bindResponseCodec.getMessageId() );
+ BindFuture bindFuture = (BindFuture)responseFuture;
+ if ( bindFuture == null )
+ {
+ LOG.error( "BindFuture is null" );
+ throw new LdapException( "BindFuture is null" );
+ }
+
// remove the listener from the listener map
- BindListener bindListener = ( BindListener ) listenerMap.remove( bindResponseCodec.getMessageId() );
-
if ( bindResponse.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
{
authenticated = true;
@@ -1594,216 +1774,308 @@
LOG.debug( "Bind failed : {}", bindResponse );
}
- if ( bindListener != null )
- {
- bindListener.bindCompleted( this, bindResponse );
- }
+ // Store the response into the future
+ bindFuture.set( bindResponse );
- // Store the response into the responseQueue
- BlockingQueue<BindResponse> bindResponseQueue = (BlockingQueue<BindResponse>)respQueueMap.remove( messageId );
- bindResponseQueue.add( bindResponse );
+ // Remove the future from the map
+ removeFromFutureMaps( messageId );
break;
- case LdapConstants.COMPARE_RESPONSE:
- // Store the response into the responseQueue
- CompareResponseCodec compResCodec = response.getCompareResponse();
+ case COMPARE_RESPONSE:
+ // Transform the response
+ CompareResponseCodec compResCodec = (CompareResponseCodec)response;
compResCodec.setMessageId( messageId );
compResCodec.addControl( response.getCurrentControl() );
- CompareResponse compareResponse = convert( compResCodec );
-
- futureMap.remove( compareResponse.getMessageId() );
- CompareListener listener = ( CompareListener ) listenerMap.remove( compareResponse.getMessageId() );
+ CompareResponse compareResponse = convert( compResCodec );
- if ( listener != null )
+ CompareFuture compareFuture = (CompareFuture)responseFuture;
+
+ if ( compareFuture == null )
{
- listener.attributeCompared( this, compareResponse );
+ LOG.error( "CompareFuture is null" );
+ throw new LdapException( "CompareFuture is null" );
}
- else
+
+ // remove the listener from the listener map
+ if ( LOG.isDebugEnabled() )
{
- BlockingQueue<CompareResponse> compareResponseQueue = (BlockingQueue<CompareResponse>)respQueueMap.remove( messageId );
- compareResponseQueue.add( compareResponse );
+ if ( compareResponse.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ // Everything is fine, return the response
+ LOG.debug( "Compare successful : {}", compareResponse );
+ }
+ else
+ {
+ // We have had an error
+ LOG.debug( "Compare failed : {}", compareResponse );
+ }
}
+ // Store the response into the future
+ compareFuture.set( compareResponse );
+
+ // Remove the future from the map
+ removeFromFutureMaps( messageId );
+
break;
- case LdapConstants.DEL_RESPONSE:
- // Store the response into the responseQueue
- DelResponseCodec delRespCodec = response.getDelResponse();
- delRespCodec.setMessageId( messageId );
+ case DEL_RESPONSE:
+ // Transform the response
+ DelResponseCodec delRespCodec = (DelResponseCodec)response;
delRespCodec.addControl( response.getCurrentControl() );
- DeleteResponse delResponse = convert( delRespCodec );
+ delRespCodec.setMessageId( messageId );
- futureMap.remove( delResponse.getMessageId() );
- DeleteListener delListener = ( DeleteListener ) listenerMap.remove( delResponse.getMessageId() );
+ DeleteResponse deleteResponse = convert( delRespCodec );
- if ( delListener != null )
+ DeleteFuture deleteFuture = (DeleteFuture)responseFuture;
+
+ if ( deleteFuture == null )
{
- delListener.entryDeleted( this, delResponse );
+ LOG.error( "DeleteFuture is null" );
+ throw new LdapException( "DeleteFuture is null" );
}
- else
+
+ if ( LOG.isDebugEnabled() )
{
- BlockingQueue<DeleteResponse> delResponseQueue = (BlockingQueue<DeleteResponse>)respQueueMap.remove( messageId );
- delResponseQueue.add( delResponse );
+ if ( deleteResponse.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ // Everything is fine, return the response
+ LOG.debug( "Delete successful : {}", deleteResponse );
+ }
+ else
+ {
+ // We have had an error
+ LOG.debug( "Delete failed : {}", deleteResponse );
+ }
}
+
+ // Store the response into the future
+ deleteFuture.set( deleteResponse );
+
+ // Remove the future from the map
+ removeFromFutureMaps( messageId );
break;
- case LdapConstants.EXTENDED_RESPONSE:
- ExtendedResponseCodec extResCodec = response.getExtendedResponse();
+ case EXTENDED_RESPONSE:
+ // Transform the response
+ ExtendedResponseCodec extResCodec = (ExtendedResponseCodec)response;
extResCodec.setMessageId( messageId );
extResCodec.addControl( response.getCurrentControl() );
- ExtendedResponse extResponse = convert( extResCodec );
- ExtendedListener extListener = ( ExtendedListener ) listenerMap.remove( extResCodec.getMessageId() );
+ ExtendedResponse extendedResponse = convert( extResCodec );
+
+ ExtendedFuture extendedFuture = (ExtendedFuture)responseFuture;
- if ( extListener != null )
+ if ( extendedFuture == null )
{
- extListener.extendedOperationCompleted( this, extResponse );
+ LOG.error( "ExtendedFuture is null" );
+ throw new LdapException( "extendedFuture is null" );
}
- else
+
+ // remove the listener from the listener map
+ if ( LOG.isDebugEnabled() )
{
- // Store the response into the responseQueue
- BlockingQueue<ExtendedResponse> extendedResponseQueue = (BlockingQueue<ExtendedResponse>)respQueueMap.remove( messageId );
- extendedResponseQueue.add( extResponse );
+ if ( extendedResponse.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ // Everything is fine, return the response
+ LOG.debug( "Extended successful : {}", extendedResponse );
+ }
+ else
+ {
+ // We have had an error
+ LOG.debug( "Extended failed : {}", extendedResponse );
+ }
}
+ // Store the response into the future
+ extendedFuture.set( extendedResponse );
+
+ // Remove the future from the map
+ removeFromFutureMaps( messageId );
+
break;
//FIXME the way we handle the intermediate responses is broken
- case LdapConstants.INTERMEDIATE_RESPONSE:
+ case INTERMEDIATE_RESPONSE:
// Store the response into the responseQueue
- IntermediateResponseCodec intermediateResponseCodec = response.getIntermediateResponse();
+ IntermediateResponseCodec intermediateResponseCodec = (IntermediateResponseCodec)response;
intermediateResponseCodec.setMessageId( messageId );
intermediateResponseCodec.addControl( response.getCurrentControl() );
IntermediateResponse intrmResp = convert( intermediateResponseCodec );
- IntermediateResponseListener intrmListener = ( IntermediateResponseListener ) listenerMap
- .get( intermediateResponseCodec.getMessageId() );
- if ( intrmListener != null )
- {
- intrmListener.responseReceived( this, intrmResp );
- }
- else
- {
- // Store the response into the responseQueue
- BlockingQueue<IntermediateResponse> intermediateResponseQueue = (BlockingQueue<IntermediateResponse>)respQueueMap.remove( messageId );
- intermediateResponseQueue.add( intrmResp );
- }
+ // Store the response into the responseQueue
+ BlockingQueue<IntermediateResponse> intermediateResponseQueue = (BlockingQueue<IntermediateResponse>)respQueueMap.remove( messageId );
+ intermediateResponseQueue.add( intrmResp );
break;
- case LdapConstants.MODIFY_RESPONSE:
- ModifyResponseCodec modRespCodec = response.getModifyResponse();
+ case MODIFY_RESPONSE:
+ // Transform the response
+ ModifyResponseCodec modRespCodec = (ModifyResponseCodec)response;
modRespCodec.setMessageId( messageId );
modRespCodec.addControl( response.getCurrentControl() );
- ModifyResponse modResp = convert( modRespCodec );
- futureMap.remove( modResp.getMessageId() );
- ModifyListener modListener = ( ModifyListener ) listenerMap.remove( modResp.getMessageId() );
+ ModifyResponse modifyResp = convert( modRespCodec );
+
+ ModifyFuture modifyFuture = (ModifyFuture)responseFuture;
- if ( modListener != null )
+ if ( modifyFuture == null )
{
- modListener.modifyCompleted( this, modResp );
+ LOG.error( "ModifyFuture is null" );
+ throw new LdapException( "ModifyFuture is null" );
}
- else
+
+ if ( LOG.isDebugEnabled() )
{
- BlockingQueue<ModifyResponse> modifyResponseQueue = (BlockingQueue<ModifyResponse>)respQueueMap.remove( messageId );
- modifyResponseQueue.add( modResp );
+ if ( modifyResp.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ // Everything is fine, return the response
+ LOG.debug( "ModifyFuture successful : {}", modifyResp );
+ }
+ else
+ {
+ // We have had an error
+ LOG.debug( "ModifyFuture failed : {}", modifyResp );
+ }
}
+ // Store the response into the future
+ modifyFuture.set( modifyResp );
+
+ // Remove the future from the map
+ removeFromFutureMaps( messageId );
+
break;
- case LdapConstants.MODIFYDN_RESPONSE:
+ case MODIFYDN_RESPONSE:
+ // Transform the response
+ ModifyDNResponseCodec modDnRespCodec = (ModifyDNResponseCodec)response;
+ modDnRespCodec.setMessageId( messageId );
+ modDnRespCodec.addControl( response.getCurrentControl() );
- ModifyDNResponseCodec modDnCodec = response.getModifyDNResponse();
- modDnCodec.addControl( response.getCurrentControl() );
- modDnCodec.setMessageId( messageId );
- ModifyDnResponse modDnResp = convert( modDnCodec );
-
- futureMap.remove( modDnCodec.getMessageId() );
- ModifyDnListener modDnListener = ( ModifyDnListener ) listenerMap.remove( modDnCodec.getMessageId() );
+ ModifyDnResponse modifyDnResp = convert( modDnRespCodec );
+
+ ModifyDnFuture modifyDnFuture = (ModifyDnFuture)responseFuture;
- if ( modDnListener != null )
+ if ( modifyDnFuture == null )
{
- modDnListener.modifyDnCompleted( this, modDnResp );
+ LOG.error( "ModifyDNFuture is null" );
+ throw new LdapException( "ModifyDNFuture is null" );
}
- else
+
+ if ( LOG.isDebugEnabled() )
{
- // Store the response into the responseQueue
- BlockingQueue<ModifyDnResponse> modDnResponseQueue = (BlockingQueue<ModifyDnResponse>)respQueueMap.remove( messageId );
- modDnResponseQueue.add( modDnResp );
+ if ( modifyDnResp.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ // Everything is fine, return the response
+ LOG.debug( "ModifyDN successful : {}", modifyDnResp );
+ }
+ else
+ {
+ // We have had an error
+ LOG.debug( "ModifyDN failed : {}", modifyDnResp );
+ }
}
+ // Store the response into the future
+ modifyDnFuture.set( modifyDnResp );
+
+ // Remove the future from the map
+ removeFromFutureMaps( messageId );
+
break;
-
- case LdapConstants.SEARCH_RESULT_DONE:
+
+ case SEARCH_RESULT_DONE:
// Store the response into the responseQueue
- SearchResultDoneCodec searchResultDoneCodec = response.getSearchResultDone();
+ SearchResultDoneCodec searchResultDoneCodec = (SearchResultDoneCodec)response;
searchResultDoneCodec.setMessageId( messageId );
searchResultDoneCodec.addControl( response.getCurrentControl() );
- SearchResultDone srchDone = convert( searchResultDoneCodec );
+ SearchResultDone searchResultDone = convert( searchResultDoneCodec );
- futureMap.remove( searchResultDoneCodec.getMessageId() );
- // search listener has to be removed from listener map only here
- searchListener = ( SearchListener ) listenerMap.remove( searchResultDoneCodec.getMessageId() );
+ SearchFuture searchFuture = (SearchFuture)responseFuture;
- if ( searchListener != null )
+ if ( searchFuture == null )
{
- searchListener.searchDone( this, srchDone );
+ LOG.error( "SearchFuture is null" );
+ throw new LdapException( "SearchFuture is null" );
}
- else
+
+ if ( LOG.isDebugEnabled() )
{
- BlockingQueue<SearchResultDone> searchDoneResponseQueue = (BlockingQueue<SearchResultDone>)respQueueMap.remove( messageId );
- searchDoneResponseQueue.add( srchDone );
+ if ( searchResultDone.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ // Everything is fine, return the response
+ LOG.debug( "Search successful : {}", searchResultDone );
+ }
+ else
+ {
+ // We have had an error
+ LOG.debug( "Search failed : {}", searchResultDone );
+ }
}
+ // Store the response into the future
+ searchFuture.set( searchResultDone );
+
+ // Remove the future from the map
+ removeFromFutureMaps( messageId );
+
break;
- case LdapConstants.SEARCH_RESULT_ENTRY:
+ case SEARCH_RESULT_ENTRY:
// Store the response into the responseQueue
- SearchResultEntryCodec searchResultEntryCodec = response.getSearchResultEntry();
+ SearchResultEntryCodec searchResultEntryCodec = (SearchResultEntryCodec)response;
searchResultEntryCodec.setMessageId( messageId );
searchResultEntryCodec.addControl( response.getCurrentControl() );
SearchResultEntry srchEntry = convert( searchResultEntryCodec );
- searchListener = ( SearchListener ) listenerMap.get( searchResultEntryCodec.getMessageId() );
- if ( searchListener != null )
+ searchFuture = (SearchFuture)responseFuture;
+
+ if ( searchFuture == null )
{
- searchListener.entryFound( this, srchEntry );
+ LOG.error( "SearchFuture is null" );
+ throw new LdapException( "SearchFuture is null" );
}
- else
+
+ if ( LOG.isDebugEnabled() )
{
- // shouldn't call addToRespQueueAndRemoveQueueRef
- BlockingQueue<SearchResponse> searchResponsequeue = (BlockingQueue<SearchResponse>)respQueueMap.get( messageId );
- searchResponsequeue.add( srchEntry );
+ LOG.debug( "Search entry found : {}", srchEntry );
}
+ // Store the response into the future
+ searchFuture.set( srchEntry );
+
break;
- case LdapConstants.SEARCH_RESULT_REFERENCE:
+ case SEARCH_RESULT_REFERENCE:
// Store the response into the responseQueue
- SearchResultReferenceCodec searchResultReferenceCodec = response.getSearchResultReference();
+ SearchResultReferenceCodec searchResultReferenceCodec = (SearchResultReferenceCodec)response;
searchResultReferenceCodec.setMessageId( messageId );
searchResultReferenceCodec.addControl( response.getCurrentControl() );
- SearchResultReference srchRef = convert( searchResultReferenceCodec );
- searchListener = ( SearchListener ) listenerMap.get( searchResultReferenceCodec.getMessageId() );
+ SearchResultReference searchResultReference = convert( searchResultReferenceCodec );
+
+ searchFuture = (SearchFuture)responseFuture;
- if ( searchListener != null )
+ if ( searchFuture == null )
{
- searchListener.referralFound( this, srchRef );
+ LOG.error( "SearchFuture is null" );
+ throw new LdapException( "SearchFuture is null" );
}
- else
+
+ if ( LOG.isDebugEnabled() )
{
- // shouldn't call addToRespQueueAndRemoveQueueRef
- BlockingQueue<SearchResponse> searchResponsequeue = (BlockingQueue<SearchResponse>)respQueueMap.get( messageId );
- searchResponsequeue.add( srchRef );
+ LOG.debug( "Search reference found : {}", searchResultReference );
}
+ // Store the response into the future
+ searchFuture.set( searchResultReference );
+
break;
default:
@@ -1838,78 +2110,123 @@
modReq.addModification( itr.next(), modOp );
}
- return modify( modReq, null );
+ return modify( modReq );
}
/**
- *
- * performs modify operation based on the modifications present in the ModifyRequest.
+ * Performs an modify operation based on the modifications present in
+ * the ModifyRequest.
*
* @param modRequest the request for modify operation
- * @param listener callback listener which will be called after the operation is completed
- * @return the modify operation's response, null if non-null listener is provided
+ * @return the modify operation's r"esponse
* @throws LdapException in case of modify operation failure or timeout happens
*/
- public ModifyResponse modify( ModifyRequest modRequest, ModifyListener listener ) throws LdapException
+ public ModifyResponse modify( ModifyRequest modRequest ) throws LdapException
+ {
+ ModifyFuture modifyFuture = modifyAsync( modRequest );
+
+ // Get the result from the future
+ try
+ {
+ // Read the response, waiting for it if not available immediately
+ long timeout = getTimeout( modRequest.getTimeout() );
+
+ // Get the response, blocking
+ ModifyResponse modifyResponse = ( ModifyResponse ) modifyFuture.get( timeout, TimeUnit.MILLISECONDS );
+
+ if ( modifyResponse == null )
+ {
+ // We didn't received anything : this is an error
+ LOG.error( "Modify failed : timeout occured" );
+ throw new LdapException( TIME_OUT_ERROR );
+ }
+
+ if ( modifyResponse.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ // Everything is fine, return the response
+ LOG.debug( "Modify successful : {}", modifyResponse );
+ }
+ else
+ {
+ // We have had an error
+ LOG.debug( "Modify failed : {}", modifyResponse );
+ }
+
+ return modifyResponse;
+ }
+ catch ( TimeoutException te )
+ {
+ // Send an abandon request
+ if ( !modifyFuture.isCancelled() )
+ {
+ abandon( modRequest.getMessageId() );
+ }
+
+ // We didn't received anything : this is an error
+ LOG.error( "Modify failed : timeout occured" );
+ throw new LdapException( TIME_OUT_ERROR );
+ }
+ catch ( Exception ie )
+ {
+ ie.printStackTrace();
+
+ // Catch all other exceptions
+ LOG.error( NO_RESPONSE_ERROR, ie );
+ LdapException ldapException = new LdapException( NO_RESPONSE_ERROR );
+ ldapException.initCause( ie );
+
+ // Send an abandon request
+ if ( !modifyFuture.isCancelled() )
+ {
+ abandon( modRequest.getMessageId() );
+ }
+
+ throw ldapException;
+ }
+ }
+
+
+ /**
+ * Performs an asynchronous modify operation based on the modifications present in
+ * the ModifyRequest.
+ *
+ * @param modRequest the request for modify operation
+ * @return the modify operation's future
+ * @throws LdapException in case of modify operation failure or timeout happens
+ */
+ public ModifyFuture modifyAsync( ModifyRequest modRequest ) throws LdapException
{
checkSession();
- LdapMessageCodec modifyMessage = new LdapMessageCodec();
+ ModifyRequestCodec modReqCodec = new ModifyRequestCodec();
int newId = messageId.incrementAndGet();
modRequest.setMessageId( newId );
- modifyMessage.setMessageId( newId );
+ modReqCodec.setMessageId( newId );
- ModifyRequestCodec modReqCodec = new ModifyRequestCodec();
modReqCodec.setModifications( modRequest.getMods() );
modReqCodec.setObject( modRequest.getDn() );
- modifyMessage.setProtocolOP( modReqCodec );
- setControls( modRequest.getControls(), modifyMessage );
-
- BlockingQueue<Response> modifyResponseQueue = new LinkedBlockingQueue<Response>();
- respQueueMap.put( newId, modifyResponseQueue );
-
- ResponseFuture modifyFuture = new ResponseFuture( modifyResponseQueue );
- futureMap.put( newId, modifyFuture );
+ setControls( modRequest.getControls(), modReqCodec );
+
+ ModifyFuture modifyFuture = new ModifyFuture( this, newId );
+ addToFutureMap( newId, modifyFuture );
- ldapSession.write( modifyMessage );
+ // Send the request to the server
+ WriteFuture writeFuture = ldapSession.write( modReqCodec );
- ModifyResponse response = null;
- if ( listener == null )
+ // Wait for the message to be sent to the server
+ if ( !writeFuture.awaitUninterruptibly( getTimeout( 0 ) ) )
{
- try
- {
- long timeout = getTimeout( modRequest.getTimeout() );
- response = ( ModifyResponse ) modifyFuture.get( timeout, TimeUnit.MILLISECONDS );
-
- if ( response == null )
- {
- LOG.error( "Modify failed : timeout occured" );
-
- throw new LdapException( TIME_OUT_ERROR );
- }
- }
- catch ( InterruptedException ie )
- {
- LOG.error( OPERATION_CANCELLED, ie );
- throw new LdapException( OPERATION_CANCELLED, ie );
- }
- catch ( Exception e )
- {
- LOG.error( NO_RESPONSE_ERROR );
- removeFromMaps( newId );
+ // We didn't received anything : this is an error
+ LOG.error( "Modify failed : timeout occured" );
- throw new LdapException( NO_RESPONSE_ERROR, e );
- }
- }
- else
- {
- listenerMap.put( newId, listener );
+ throw new LdapException( TIME_OUT_ERROR );
}
-
- return response;
+
+ // Ok, done return the future
+ return modifyFuture;
}
@@ -1982,7 +2299,7 @@
modDnRequest.setNewRdn( newRdn );
modDnRequest.setDeleteOldRdn( deleteOldRdn );
- return modifyDn( modDnRequest, null );
+ return modifyDn( modDnRequest );
}
@@ -2017,10 +2334,83 @@
modDnRequest.setEntryDn( entryDn );
modDnRequest.setNewSuperior( newSuperiorDn );
- //TODO not setting the below value is resulting in error
- modDnRequest.setNewRdn( entryDn.getRdn() );
+ //TODO not setting the below value is resulting in error
+ modDnRequest.setNewRdn( entryDn.getRdn() );
+
+ return modifyDn( modDnRequest );
+ }
+
+
+ /**
+ *
+ * performs the modifyDn operation based on the given ModifyDnRequest.
+ *
+ * @param modDnRequest the request
+ * @return modifyDn operations response, null if non-null listener is provided
+ * @throws LdapException
+ */
+ public ModifyDnResponse modifyDn( ModifyDnRequest modDnRequest ) throws LdapException
+ {
+ ModifyDnFuture modifyDnFuture = modifyDnAsync( modDnRequest );
+
+ // Get the result from the future
+ try
+ {
+ // Read the response, waiting for it if not available immediately
+ long timeout = getTimeout( modDnRequest.getTimeout() );
+
+ // Get the response, blocking
+ ModifyDnResponse modifyDnResponse = ( ModifyDnResponse ) modifyDnFuture.get( timeout, TimeUnit.MILLISECONDS );
+
+ if ( modifyDnResponse == null )
+ {
+ // We didn't received anything : this is an error
+ LOG.error( "ModifyDN failed : timeout occured" );
+ throw new LdapException( TIME_OUT_ERROR );
+ }
+
+ if ( modifyDnResponse.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ // Everything is fine, return the response
+ LOG.debug( "ModifyDN successful : {}", modifyDnResponse );
+ }
+ else
+ {
+ // We have had an error
+ LOG.debug( "Modify failed : {}", modifyDnResponse );
+ }
+
+ return modifyDnResponse;
+ }
+ catch ( TimeoutException te )
+ {
+ // Send an abandon request
+ if ( !modifyDnFuture.isCancelled() )
+ {
+ abandon( modDnRequest.getMessageId() );
+ }
+
+ // We didn't received anything : this is an error
+ LOG.error( "Modify failed : timeout occured" );
+ throw new LdapException( TIME_OUT_ERROR );
+ }
+ catch ( Exception ie )
+ {
+ ie.printStackTrace();
+
+ // Catch all other exceptions
+ LOG.error( NO_RESPONSE_ERROR, ie );
+ LdapException ldapException = new LdapException( NO_RESPONSE_ERROR );
+ ldapException.initCause( ie );
+
+ // Send an abandon request
+ if ( !modifyDnFuture.isCancelled() )
+ {
+ abandon( modDnRequest.getMessageId() );
+ }
- return modifyDn( modDnRequest, null );
+ throw ldapException;
+ }
}
@@ -2033,70 +2423,40 @@
* @return modifyDn operations response, null if non-null listener is provided
* @throws LdapException
*/
- public ModifyDnResponse modifyDn( ModifyDnRequest modDnRequest, ModifyDnListener listener ) throws LdapException
+ public ModifyDnFuture modifyDnAsync( ModifyDnRequest modDnRequest ) throws LdapException
{
checkSession();
- LdapMessageCodec modifyDnMessage = new LdapMessageCodec();
+ ModifyDNRequestCodec modDnCodec = new ModifyDNRequestCodec();
int newId = messageId.incrementAndGet();
modDnRequest.setMessageId( newId );
- modifyDnMessage.setMessageId( newId );
+ modDnCodec.setMessageId( newId );
- ModifyDNRequestCodec modDnCodec = new ModifyDNRequestCodec();
modDnCodec.setEntry( modDnRequest.getEntryDn() );
modDnCodec.setNewRDN( modDnRequest.getNewRdn() );
modDnCodec.setDeleteOldRDN( modDnRequest.isDeleteOldRdn() );
modDnCodec.setNewSuperior( modDnRequest.getNewSuperior() );
- modifyDnMessage.setProtocolOP( modDnCodec );
- setControls( modDnRequest.getControls(), modifyDnMessage );
+ setControls( modDnRequest.getControls(), modDnCodec );
- BlockingQueue<Response> modifyDNResponseQueue = new LinkedBlockingQueue<Response>();
- respQueueMap.put( newId, modifyDNResponseQueue );
+ ModifyDnFuture modifyDnFuture = new ModifyDnFuture( this, newId );
+ addToFutureMap( newId, modifyDnFuture );
- ResponseFuture modifyDNFuture = new ResponseFuture( modifyDNResponseQueue );
- futureMap.put( newId, modifyDNFuture );
-
- ldapSession.write( modifyDnMessage );
+ // Send the request to the server
+ WriteFuture writeFuture = ldapSession.write( modDnCodec );
- if ( listener == null )
+ // Wait for the message to be sent to the server
+ if ( !writeFuture.awaitUninterruptibly( getTimeout( 0 ) ) )
{
- ModifyDnResponse response = null;
- try
- {
- long timeout = getTimeout( modDnRequest.getTimeout() );
- response = ( ModifyDnResponse ) modifyDNFuture.get( timeout, TimeUnit.MILLISECONDS );
-
- if ( response == null )
- {
- LOG.error( "Modifying DN failed : timeout occured" );
-
- throw new LdapException( TIME_OUT_ERROR );
- }
- }
- catch ( InterruptedException ie )
- {
- LOG.error( OPERATION_CANCELLED, ie );
- throw new LdapException( OPERATION_CANCELLED, ie );
- }
- catch ( Exception e )
- {
- LOG.error( NO_RESPONSE_ERROR );
- removeFromMaps( newId );
-
- LdapException ldapException = new LdapException( NO_RESPONSE_ERROR );
- ldapException.initCause( e );
- throw ldapException;
- }
+ // We didn't received anything : this is an error
+ LOG.error( "Modify failed : timeout occured" );
- return response;
- }
- else
- {
- listenerMap.put( newId, listener );
- return null;
+ throw new LdapException( TIME_OUT_ERROR );
}
+
+ // Ok, done return the future
+ return modifyDnFuture;
}
@@ -2126,7 +2486,7 @@
{
DeleteRequest deleteRequest = new DeleteRequest( new LdapDN( dn ) );
- return delete( deleteRequest, null );
+ return delete( deleteRequest );
}
catch ( InvalidNameException e )
{
@@ -2146,7 +2506,7 @@
{
DeleteRequest deleteRequest = new DeleteRequest( dn );
- return delete( deleteRequest, null );
+ return delete( deleteRequest );
}
@@ -2165,7 +2525,7 @@
{
DeleteRequest delRequest = new DeleteRequest( dn );
delRequest.add( new ControlImpl( treeDeleteOid ) );
- return delete( delRequest, null );
+ return delete( delRequest );
}
else
{
@@ -2195,7 +2555,7 @@
{
DeleteRequest delRequest = new DeleteRequest( ldapDn );
delRequest.add( new ControlImpl( treeDeleteOid ) );
- return delete( delRequest, null );
+ return delete( delRequest );
}
else
{
@@ -2272,7 +2632,7 @@
LOG.debug( "deleting {}", dn.getName() );
cursorMap.remove( dn );
cursor.close();
- delResponse = delete( new DeleteRequest( dn ), listener );
+ delResponse = delete( new DeleteRequest( dn ) );
}
else
{
@@ -2291,7 +2651,7 @@
cursorMap.remove( dn );
cursor.close();
LOG.debug( "deleting {}", dn.getName() );
- delResponse = delete( new DeleteRequest( dn ), listener );
+ delResponse = delete( new DeleteRequest( dn ) );
}
}
catch ( Exception e )
@@ -2306,88 +2666,115 @@
/**
- * Performs a synchronous delete operation based on the delete request object.
+ * Performs a delete operation based on the delete request object.
*
- * @param delRequest the delete operation's request
+ * @param deleteRequest the delete operation's request
* @return delete operation's response, null if a non-null listener value is provided
* @throws LdapException If the DN is not valid or if the deletion failed
*/
- public DeleteResponse delete( DeleteRequest delRequest ) throws LdapException
+ public DeleteResponse delete( DeleteRequest deleteRequest ) throws LdapException
{
- // Just call the delete method with a null listener
- return delete( delRequest, null );
- }
+ DeleteFuture deleteFuture = deleteAsync( deleteRequest );
+
+ // Get the result from the future
+ try
+ {
+ // Read the response, waiting for it if not available immediately
+ long timeout = getTimeout( deleteRequest.getTimeout() );
+
+ // Get the response, blocking
+ DeleteResponse delResponse = ( DeleteResponse ) deleteFuture.get( timeout, TimeUnit.MILLISECONDS );
+
+ if ( delResponse == null )
+ {
+ // We didn't received anything : this is an error
+ LOG.error( "Delete failed : timeout occured" );
+ throw new LdapException( TIME_OUT_ERROR );
+ }
+
+ if ( delResponse.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS )
+ {
+ // Everything is fine, return the response
+ LOG.debug( "Delete successful : {}", delResponse );
+ }
+ else
+ {
+ // We have had an error
+ LOG.debug( "Delete failed : {}", delResponse );
+ }
+
+ return delResponse;
+ }
+ catch ( TimeoutException te )
+ {
+ // Send an abandon request
+ if ( !deleteFuture.isCancelled() )
+ {
+ abandon( deleteRequest.getMessageId() );
+ }
+
+ // We didn't received anything : this is an error
+ LOG.error( "Del failed : timeout occured" );
+ throw new LdapException( TIME_OUT_ERROR );
+ }
+ catch ( Exception ie )
+ {
+ ie.printStackTrace();
+
+ // Catch all other exceptions
+ LOG.error( NO_RESPONSE_ERROR, ie );
+ LdapException ldapException = new LdapException( NO_RESPONSE_ERROR );
+ ldapException.initCause( ie );
+ // Send an abandon request
+ if ( !deleteFuture.isCancelled() )
+ {
+ abandon( deleteRequest.getMessageId() );
+ }
+ throw ldapException;
+ }
+ }
+
+
/**
- * Performs a delete operation based on the delete request object.
+ * Performs an asynchronous delete operation based on the delete request object.
*
* @param delRequest the delete operation's request
- * @param listener the delete operation response listener
* @return delete operation's response, null if a non-null listener value is provided
* @throws LdapException If the DN is not valid or if the deletion failed
*/
- public DeleteResponse delete( DeleteRequest delRequest, DeleteListener listener ) throws LdapException
+ public DeleteFuture deleteAsync( DeleteRequest delRequest ) throws LdapException
{
checkSession();
- LdapMessageCodec deleteMessage = new LdapMessageCodec();
+ DelRequestCodec delReqCodec = new DelRequestCodec();
int newId = messageId.incrementAndGet();
+
delRequest.setMessageId( newId );
- deleteMessage.setMessageId( newId );
+ delReqCodec.setMessageId( newId );
- DelRequestCodec delCodec = new DelRequestCodec();
- delCodec.setEntry( delRequest.getTargetDn() );
+ delReqCodec.setEntry( delRequest.getTargetDn() );
+ setControls( delRequest.getControls(), delReqCodec );
- deleteMessage.setProtocolOP( delCodec );
- setControls( delRequest.getControls(), deleteMessage );
+ DeleteFuture deleteFuture = new DeleteFuture( this, newId );
+ addToFutureMap( newId, deleteFuture );
- BlockingQueue<Response> deleteResponseQueue = new LinkedBlockingQueue<Response>();
- respQueueMap.put( newId, deleteResponseQueue );
-
- ResponseFuture deleteFuture = new ResponseFuture( deleteResponseQueue );
- futureMap.put( newId, deleteFuture );
-
[... 464 lines stripped ...]