From 6439bba5cc09d6febc59bdc9e0d9bc25f1f1eb18 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Wed, 01 Sep 2010 09:04:15 +0000
Subject: [PATCH] Various improvements:
---
sdk/src/com/sun/opends/sdk/ldap/LDAPConnection.java | 140 +++++++++++++++++++++-------------------------
1 files changed, 65 insertions(+), 75 deletions(-)
diff --git a/sdk/src/com/sun/opends/sdk/ldap/LDAPConnection.java b/sdk/src/com/sun/opends/sdk/ldap/LDAPConnection.java
index d3bed34..25f7d84 100644
--- a/sdk/src/com/sun/opends/sdk/ldap/LDAPConnection.java
+++ b/sdk/src/com/sun/opends/sdk/ldap/LDAPConnection.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package com.sun.opends.sdk.ldap;
@@ -30,9 +30,9 @@
import java.io.IOException;
-import java.util.HashMap;
-import java.util.Iterator;
+import java.net.InetSocketAddress;
import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@@ -79,8 +79,9 @@
private boolean bindOrStartTLSInProgress = false;
- private final HashMap<Integer, AbstractLDAPFutureResultImpl<?>>
- pendingRequests = new HashMap<Integer, AbstractLDAPFutureResultImpl<?>>();
+ private final ConcurrentHashMap<Integer, AbstractLDAPFutureResultImpl<?>>
+ pendingRequests =
+ new ConcurrentHashMap<Integer, AbstractLDAPFutureResultImpl<?>>();
private final Object stateLock = new Object();
@@ -112,21 +113,7 @@
*/
public FutureResult<Void> abandon(final AbandonRequest request)
{
- // First remove the future associated with the request to be abandoned.
- final AbstractLDAPFutureResultImpl<?> pendingRequest = pendingRequests
- .remove(request.getMessageID());
-
- if (pendingRequest == null)
- {
- // There has never been a request with the specified message ID or the
- // response has already been received and handled. We can ignore this
- // abandon request.
-
- // Message ID will be -1 since no request was sent.
- return new CompletedFutureResult<Void>((Void) null);
- }
-
- pendingRequest.cancel(false);
+ final AbstractLDAPFutureResultImpl<?> pendingRequest;
final int messageID = nextMsgID.getAndIncrement();
synchronized (stateLock)
@@ -144,8 +131,23 @@
return new CompletedFutureResult<Void>(ErrorResultException
.wrap(errorResult), messageID);
}
+
+ // First remove the future associated with the request to be abandoned.
+ pendingRequest = pendingRequests.remove(request.getMessageID());
}
+ if (pendingRequest == null)
+ {
+ // There has never been a request with the specified message ID or the
+ // response has already been received and handled. We can ignore this
+ // abandon request.
+
+ // Message ID will be -1 since no request was sent.
+ return new CompletedFutureResult<Void>((Void) null);
+ }
+
+ pendingRequest.cancel(false);
+
try
{
final ASN1BufferWriter asn1Writer = ASN1BufferWriter.getWriter();
@@ -178,7 +180,7 @@
* {@inheritDoc}
*/
public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
{
final int messageID = nextMsgID.getAndIncrement();
@@ -256,8 +258,10 @@
BindClient context;
try
{
- context = request
- .createBindClient(connection.getPeerAddress().toString());
+ context = request.createBindClient(
+ connection.getPeerAddress() instanceof InetSocketAddress ?
+ ((InetSocketAddress)connection.getPeerAddress()).getHostName() :
+ connection.getPeerAddress().toString());
}
catch (final Exception e)
{
@@ -414,7 +418,7 @@
* {@inheritDoc}
*/
public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
{
final int messageID = nextMsgID.getAndIncrement();
@@ -568,7 +572,7 @@
* {@inheritDoc}
*/
public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
{
final int messageID = nextMsgID.getAndIncrement();
@@ -626,7 +630,7 @@
* {@inheritDoc}
*/
public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
{
final int messageID = nextMsgID.getAndIncrement();
@@ -696,14 +700,12 @@
* {@inheritDoc}
*/
public FutureResult<Result> search(final SearchRequest request,
- final ResultHandler<Result> resultHandler,
- final SearchResultHandler searchResultHandler,
+ final SearchResultHandler resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
{
final int messageID = nextMsgID.getAndIncrement();
final LDAPSearchFutureResultImpl future = new LDAPSearchFutureResultImpl(
- messageID, request, resultHandler, searchResultHandler,
- intermediateResponseHandler, this);
+ messageID, request, resultHandler, intermediateResponseHandler, this);
synchronized (stateLock)
{
@@ -753,9 +755,17 @@
int addPendingRequest(final AbstractLDAPFutureResultImpl<?> request)
+ throws ErrorResultException
{
final int newMsgID = nextMsgID.getAndIncrement();
- pendingRequests.put(newMsgID, request);
+ synchronized(stateLock)
+ {
+ if(connectionInvalidReason != null)
+ {
+ throw ErrorResultException.wrap(connectionInvalidReason);
+ }
+ pendingRequests.put(newMsgID, request);
+ }
return newMsgID;
}
@@ -767,21 +777,20 @@
long delay = timeout;
if (timeout > 0)
{
- synchronized (stateLock)
+ for (int requestID : pendingRequests.keySet())
{
- for (final Iterator<AbstractLDAPFutureResultImpl<?>> i = pendingRequests
- .values().iterator(); i.hasNext();)
+ final AbstractLDAPFutureResultImpl<?> future =
+ pendingRequests.get(requestID);
+ if(future != null)
{
- final AbstractLDAPFutureResultImpl<?> future = i.next();
final long diff = (future.getTimestamp() + timeout) - currentTime;
- if (diff <= 0)
+ if (diff <= 0 && pendingRequests.remove(requestID) != null)
{
StaticUtils.DEBUG_LOG.fine("Cancelling expired future result: "
+ future);
final Result result = Responses
.newResult(ResultCode.CLIENT_SIDE_TIMEOUT);
future.adaptErrorResult(result);
- i.remove();
abandon(Requests.newAbandonRequest(future.getRequestID()));
}
@@ -805,7 +814,7 @@
synchronized (stateLock)
{
- if (isClosed)
+ if (isClosed || connectionInvalidReason != null)
{
// Already closed.
return;
@@ -822,51 +831,29 @@
notifyErrorOccurred = true;
}
- if (connectionInvalidReason != null)
- {
- // Already invalid.
- return;
- }
-
// Mark the connection as invalid.
- connectionInvalidReason = reason;
+ connectionInvalidReason =
+ reason.getResultCode() == ResultCode.CLIENT_SIDE_USER_CANCELLED ?
+ reason : Responses.newResult(
+ ResultCode.CLIENT_SIDE_USER_CANCELLED).setCause(
+ ErrorResultException.wrap(reason)).setDiagnosticMessage(
+ "Connection closed: " + reason.getDiagnosticMessage());
}
// First abort all outstanding requests.
- for (final AbstractLDAPFutureResultImpl<?> future : pendingRequests
- .values())
+ for (int requestID : pendingRequests.keySet())
{
- if (!bindOrStartTLSInProgress)
+ final AbstractLDAPFutureResultImpl<?> future =
+ pendingRequests.remove(requestID);
+ if(future != null)
{
- final int messageID = nextMsgID.getAndIncrement();
- final AbandonRequest abandon = Requests.newAbandonRequest(future
- .getRequestID());
- try
- {
- final ASN1BufferWriter asn1Writer = ASN1BufferWriter.getWriter();
- try
- {
- ldapWriter.abandonRequest(asn1Writer, messageID, abandon);
- connection.write(asn1Writer.getBuffer(), null);
- }
- finally
- {
- asn1Writer.recycle();
- }
- }
- catch (final IOException e)
- {
- // Underlying channel probably blown up. Just ignore.
- }
+ future.adaptErrorResult(reason);
}
-
- future.adaptErrorResult(reason);
}
- pendingRequests.clear();
// Now try cleanly closing the connection if possible.
// Only send unbind if specified.
- if (unbindRequest != null)
+ if (unbindRequest != null && !isDisconnectNotification)
{
try
{
@@ -902,7 +889,7 @@
{
for (final ConnectionEventListener listener : listeners)
{
- listener.connectionClosed();
+ listener.handleConnectionClosed();
}
}
@@ -910,7 +897,7 @@
{
for (final ConnectionEventListener listener : listeners)
{
- listener.connectionErrorOccurred(isDisconnectNotification,
+ listener.handleConnectionError(isDisconnectNotification,
ErrorResultException.wrap(reason));
}
}
@@ -942,7 +929,7 @@
for (final ConnectionEventListener listener : listeners)
{
- listener.connectionReceivedUnsolicitedNotification(result);
+ listener.handleUnsolicitedNotification(result);
}
}
@@ -993,6 +980,7 @@
synchronized void startTLS(final SSLContext sslContext,
+ final String[] protocols, final String[] cipherSuites,
final CompletionHandler<SSLEngine> completionHandler) throws IOException
{
if (isTLSEnabled())
@@ -1005,6 +993,8 @@
sslEngineConfigurator = new SSLEngineConfigurator(sslContext, true, false,
false);
+ sslEngineConfigurator.setEnabledProtocols(protocols);
+ sslEngineConfigurator.setEnabledCipherSuites(cipherSuites);
sslFilter = new SSLFilter(null, sslEngineConfigurator);
installFilter(sslFilter);
sslFilter.handshake(connection, completionHandler);
--
Gitblit v1.10.0