From 8f4c882e39b040cca1210fcc169424f721be16c8 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:
---
opendj-sdk/sdk/src/org/opends/sdk/AbstractConnectionFactory.java | 4
opendj-sdk/sdk/src/org/opends/sdk/SearchResultReferenceIOException.java | 81 +
opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPServerFilter.java | 532 +++++-
opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ArgumentParserConnectionFactory.java | 4
opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPSearchFutureResultImpl.java | 7
opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPConnectionFactoryImpl.java | 10
opendj-sdk/sdk/src/org/opends/sdk/requests/StartTLSExtendedRequestImpl.java | 52
opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/InternalConnection.java | 36
opendj-sdk/sdk/src/org/opends/sdk/SearchResultHandler.java | 5
opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ArgumentParser.java | 5
opendj-sdk/sdk/src/org/opends/sdk/LDAPConnectionFactory.java | 4
opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/ConnectionFactoryTestCase.java | 105 +
opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingConnectionFactory.java | 2
opendj-sdk/sdk/src/org/opends/sdk/schema/Schema.java | 251 +-
opendj-sdk/sdk/src/com/sun/opends/sdk/tools/AuthenticatedConnectionFactory.java | 38
opendj-sdk/sdk/src/org/opends/sdk/LDAPOptions.java | 76 +
opendj-sdk/sdk/src/org/opends/sdk/SynchronousConnection.java | 23
opendj-sdk/sdk/src/com/sun/opends/sdk/tools/PromptingTrustManager.java | 11
opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/GlobalTransportFactory.java | 32
opendj-sdk/sdk/src/com/sun/opends/sdk/tools/PerformanceRunner.java | 19
opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPBindFutureResultImpl.java | 12
opendj-sdk/sdk/src/org/opends/sdk/AVA.java | 2
opendj-sdk/sdk/src/com/sun/opends/sdk/util/AbstractFutureResult.java | 18
opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPFutureResultImpl.java | 4
opendj-sdk/sdk/src/org/opends/sdk/Connection.java | 62
opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPExtendedFutureResultImpl.java | 13
opendj-sdk/sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java | 66
opendj-sdk/sdk/src/org/opends/sdk/ldif/ConnectionEntryReader.java | 311 ++++
opendj-sdk/sdk/src/org/opends/sdk/InternalConnectionFactory.java | 2
opendj-sdk/sdk/examples/org/opends/sdk/examples/DummyServer.java | 80
opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java | 2
opendj-sdk/sdk/src/org/opends/sdk/schema/SchemaBuilder.java | 150 ++
opendj-sdk/sdk/src/org/opends/sdk/ConnectionFactory.java | 4
opendj-sdk/sdk/lib/grizzly.jar | 0
opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/SynchronousConnectionTestCase.java | 9
opendj-sdk/sdk/src/com/sun/opends/sdk/tools/DataSource.java | 28
opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPConnection.java | 140 -
opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java | 36
opendj-sdk/sdk/src/org/opends/sdk/LDAPClientContext.java | 91 +
opendj-sdk/sdk/src/org/opends/sdk/AsynchronousConnection.java | 155 +-
opendj-sdk/sdk/src/org/opends/sdk/requests/DigestMD5SASLBindRequestImpl.java | 34
opendj-sdk/sdk/src/org/opends/sdk/requests/StartTLSExtendedRequest.java | 56
opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LDAPServer.java | 883 +++++++----
opendj-sdk/sdk/src/org/opends/sdk/requests/ExternalSASLBindRequestImpl.java | 34
opendj-sdk/sdk/src/com/sun/opends/sdk/tools/SearchRate.java | 8
opendj-sdk/sdk/src/org/opends/sdk/ServerConnection.java | 78
opendj-sdk/sdk/src/org/opends/sdk/controls/EntryChangeNotificationResponseControl.java | 21
opendj-sdk/sdk/src/org/opends/sdk/AbstractConnection.java | 59
opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ModRate.java | 6
/dev/null | 56
opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPClientFilter.java | 407 +++--
opendj-sdk/sdk/src/org/opends/sdk/requests/CRAMMD5SASLBindRequestImpl.java | 35
opendj-sdk/sdk/src/org/opends/sdk/AbstractAsynchronousConnection.java | 28
opendj-sdk/sdk/src/org/opends/sdk/LDAPUrl.java | 2
opendj-sdk/sdk/src/org/opends/sdk/RootDSE.java | 4
opendj-sdk/sdk/src/com/sun/opends/sdk/messages/messages.properties | 12
opendj-sdk/sdk/src/org/opends/sdk/ConnectionPool.java | 42
opendj-sdk/sdk/src/com/sun/opends/sdk/tools/LDAPSearch.java | 22
opendj-sdk/sdk/src/org/opends/sdk/ConnectionEventListener.java | 30
59 files changed, 2,887 insertions(+), 1,412 deletions(-)
diff --git a/opendj-sdk/sdk/examples/org/opends/sdk/examples/DummyServer.java b/opendj-sdk/sdk/examples/org/opends/sdk/examples/DummyServer.java
index 4179cec..8c924bc 100644
--- a/opendj-sdk/sdk/examples/org/opends/sdk/examples/DummyServer.java
+++ b/opendj-sdk/sdk/examples/org/opends/sdk/examples/DummyServer.java
@@ -63,15 +63,17 @@
- public void abandon(final Integer context, final AbandonRequest request)
- throws UnsupportedOperationException
+ @Override
+ public void handleAbandon(final Integer context,
+ final AbandonRequest request) throws UnsupportedOperationException
{
}
- public void add(final Integer context, final AddRequest request,
- final ResultHandler<Result> handler,
+ @Override
+ public void handleAdd(final Integer context, final AddRequest request,
+ final ResultHandler<? super Result> handler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException
{
@@ -79,7 +81,8 @@
- public void bind(final Integer context, final int version,
+ @Override
+ public void handleBind(final Integer context, final int version,
final BindRequest request,
final ResultHandler<? super BindResult> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
@@ -90,21 +93,9 @@
- public void closed(final Integer context, final UnbindRequest request)
- {
- System.out.println(request);
- }
-
-
-
- public void closed(final Throwable error)
- {
- System.out.println(error);
- }
-
-
-
- public void compare(final Integer context, final CompareRequest request,
+ @Override
+ public void handleCompare(final Integer context,
+ final CompareRequest request,
final ResultHandler<? super CompareResult> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException
@@ -113,8 +104,27 @@
- public void delete(final Integer context, final DeleteRequest request,
- final ResultHandler<Result> handler,
+ @Override
+ public void handleConnectionClosed(final Integer context,
+ final UnbindRequest request)
+ {
+ System.out.println(request);
+ }
+
+
+
+ @Override
+ public void handleConnectionException(final Throwable error)
+ {
+ System.out.println(error);
+ }
+
+
+
+ @Override
+ public void handleDelete(final Integer context,
+ final DeleteRequest request,
+ final ResultHandler<? super Result> handler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException
{
@@ -122,9 +132,10 @@
- public <R extends ExtendedResult> void extendedRequest(
+ @Override
+ public <R extends ExtendedResult> void handleExtendedRequest(
final Integer context, final ExtendedRequest<R> request,
- final ResultHandler<R> resultHandler,
+ final ResultHandler<? super R> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException
{
@@ -133,14 +144,16 @@
final R result = request.getResultDecoder().adaptExtendedErrorResult(
ResultCode.SUCCESS, "", "");
resultHandler.handleResult(result);
- clientContext.startTLS(sslContext);
+ clientContext.startTLS(sslContext, null, null, false, false);
}
}
- public void modify(final Integer context, final ModifyRequest request,
- final ResultHandler<Result> resultHandler,
+ @Override
+ public void handleModify(final Integer context,
+ final ModifyRequest request,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException
{
@@ -148,8 +161,10 @@
- public void modifyDN(final Integer context, final ModifyDNRequest request,
- final ResultHandler<Result> resultHandler,
+ @Override
+ public void handleModifyDN(final Integer context,
+ final ModifyDNRequest request,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException
{
@@ -157,8 +172,10 @@
- public void search(final Integer context, final SearchRequest request,
- final ResultHandler<Result> resultHandler,
+ @Override
+ public void handleSearch(final Integer context,
+ final SearchRequest request,
+ final ResultHandler<? super Result> resultHandler,
final SearchResultHandler searchResulthandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException
@@ -252,6 +269,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public ServerConnection<Integer> accept(final LDAPClientContext context)
{
System.out.println("Connection from: " + context.getPeerAddress());
diff --git a/opendj-sdk/sdk/lib/grizzly.jar b/opendj-sdk/sdk/lib/grizzly.jar
index 30f4360..137fb72 100644
--- a/opendj-sdk/sdk/lib/grizzly.jar
+++ b/opendj-sdk/sdk/lib/grizzly.jar
Binary files differ
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/GlobalTransportFactory.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/GlobalTransportFactory.java
index b3e1279..85d102d 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/GlobalTransportFactory.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/GlobalTransportFactory.java
@@ -76,6 +76,12 @@
private int selectors;
+ private int linger = -1;
+
+ private boolean tcpNoDelay = true;
+
+ private boolean reuseAddress = true;
+
private TCPNIOTransport globalTCPNIOTransport = null;
@@ -117,12 +123,15 @@
* @return instance of TCP {@link com.sun.grizzly.Transport}.
*/
@Override
- public TCPNIOTransport createTCPTransport()
+ public synchronized TCPNIOTransport createTCPTransport()
{
if (globalTCPNIOTransport == null)
{
globalTCPNIOTransport = setupTransport(new TCPNIOTransport());
globalTCPNIOTransport.setSelectorRunnersCount(selectors);
+ globalTCPNIOTransport.setLinger(linger);
+ globalTCPNIOTransport.setTcpNoDelay(tcpNoDelay);
+ globalTCPNIOTransport.setReuseAddress(reuseAddress);
try
{
@@ -178,6 +187,27 @@
ThreadPoolConfig.DEFAULT.setMaxPoolSize(threads);
ThreadPoolConfig.DEFAULT.setPoolName("OpenDS SDK Worker(Grizzly)");
+ final String lingerStr = System
+ .getProperty("org.opends.sdk.ldap.transport.linger");
+ if (lingerStr != null)
+ {
+ linger = Integer.parseInt(lingerStr);
+ }
+
+ final String tcpNoDelayStr = System
+ .getProperty("org.opends.sdk.ldap.transport.tcpNoDelay");
+ if (tcpNoDelayStr != null)
+ {
+ tcpNoDelay = Integer.parseInt(tcpNoDelayStr) != 0;
+ }
+
+ final String reuseAddressStr = System
+ .getProperty("org.opends.sdk.ldap.transport.reuseAddress");
+ if (reuseAddressStr != null)
+ {
+ reuseAddress = Integer.parseInt(reuseAddressStr) != 0;
+ }
+
super.initialize();
}
}
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/InternalConnection.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/InternalConnection.java
index aa897ee..00d07e7 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/InternalConnection.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/InternalConnection.java
@@ -49,7 +49,7 @@
*/
public final class InternalConnection extends AbstractAsynchronousConnection
{
- private final class InternalBindFutureResultImpl extends
+ private static final class InternalBindFutureResultImpl extends
AbstractLDAPFutureResultImpl<BindResult> implements
FutureResult<BindResult>
{
@@ -125,7 +125,7 @@
NullPointerException
{
final int i = messageID.getAndIncrement();
- serverConnection.abandon(i, request);
+ serverConnection.handleAbandon(i, request);
return new CompletedFutureResult<Void>((Void) null, i);
}
@@ -135,7 +135,7 @@
* {@inheritDoc}
*/
public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -143,7 +143,7 @@
final int i = messageID.getAndIncrement();
final LDAPFutureResultImpl future = new LDAPFutureResultImpl(i, request,
resultHandler, intermediateResponseHandler, this);
- serverConnection.add(i, request, future, future);
+ serverConnection.handleAdd(i, request, future, future);
return future;
}
@@ -173,7 +173,7 @@
final int i = messageID.getAndIncrement();
final InternalBindFutureResultImpl future = new InternalBindFutureResultImpl(
i, request, resultHandler, intermediateResponseHandler, this);
- serverConnection.bind(i, 3, request, future, future);
+ serverConnection.handleBind(i, 3, request, future, future);
return future;
}
@@ -185,7 +185,7 @@
public void close(final UnbindRequest request, final String reason)
{
final int i = messageID.getAndIncrement();
- serverConnection.closed(i, request);
+ serverConnection.handleConnectionClosed(i, request);
}
@@ -202,7 +202,7 @@
final int i = messageID.getAndIncrement();
final LDAPCompareFutureResultImpl future = new LDAPCompareFutureResultImpl(
i, request, resultHandler, intermediateResponseHandler, this);
- serverConnection.compare(i, request, future, future);
+ serverConnection.handleCompare(i, request, future, future);
return future;
}
@@ -212,7 +212,7 @@
* {@inheritDoc}
*/
public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -220,7 +220,7 @@
final int i = messageID.getAndIncrement();
final LDAPFutureResultImpl future = new LDAPFutureResultImpl(i, request,
resultHandler, intermediateResponseHandler, this);
- serverConnection.delete(i, request, future, future);
+ serverConnection.handleDelete(i, request, future, future);
return future;
}
@@ -239,7 +239,7 @@
final int i = messageID.getAndIncrement();
final LDAPExtendedFutureResultImpl<R> future = new LDAPExtendedFutureResultImpl<R>(
i, request, resultHandler, intermediateResponseHandler, this);
- serverConnection.extendedRequest(i, request, future, future);
+ serverConnection.handleExtendedRequest(i, request, future, future);
return future;
}
@@ -271,7 +271,7 @@
* {@inheritDoc}
*/
public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -279,7 +279,7 @@
final int i = messageID.getAndIncrement();
final LDAPFutureResultImpl future = new LDAPFutureResultImpl(i, request,
resultHandler, intermediateResponseHandler, this);
- serverConnection.modify(i, request, future, future);
+ serverConnection.handleModify(i, request, future, future);
return future;
}
@@ -289,7 +289,7 @@
* {@inheritDoc}
*/
public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -297,7 +297,7 @@
final int i = messageID.getAndIncrement();
final LDAPFutureResultImpl future = new LDAPFutureResultImpl(i, request,
resultHandler, intermediateResponseHandler, this);
- serverConnection.modifyDN(i, request, future, future);
+ serverConnection.handleModifyDN(i, request, future, future);
return future;
}
@@ -319,17 +319,15 @@
* {@inheritDoc}
*/
public FutureResult<Result> search(final SearchRequest request,
- final ResultHandler<Result> resultHandler,
- final SearchResultHandler searchResulthandler,
+ final SearchResultHandler resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
final int i = messageID.getAndIncrement();
final LDAPSearchFutureResultImpl future = new LDAPSearchFutureResultImpl(i,
- request, resultHandler, searchResulthandler,
- intermediateResponseHandler, this);
- serverConnection.search(i, request, future, future, future);
+ request, resultHandler, intermediateResponseHandler, this);
+ serverConnection.handleSearch(i, request, future, future, future);
return future;
}
}
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPBindFutureResultImpl.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPBindFutureResultImpl.java
index 4fda984..9d9b058 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPBindFutureResultImpl.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPBindFutureResultImpl.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;
@@ -58,6 +58,16 @@
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean isCancelable() {
+ return false;
+ }
+
+
+
@Override
public String toString()
{
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPClientFilter.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPClientFilter.java
index a1e1618..ea42e73 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPClientFilter.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPClientFilter.java
@@ -77,21 +77,25 @@
{
final LDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(ctx
.getConnection());
- final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
- .removePendingRequest(messageID);
-
- if (pendingRequest != null)
+ if(ldapConnection != null)
{
- if (pendingRequest instanceof LDAPFutureResultImpl)
+ final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
+ .removePendingRequest(messageID);
+
+ if (pendingRequest != null)
{
- final LDAPFutureResultImpl future = (LDAPFutureResultImpl) pendingRequest;
- if (future.getRequest() instanceof AddRequest)
+ if (pendingRequest instanceof LDAPFutureResultImpl)
{
- future.setResultOrError(result);
- return;
+ final LDAPFutureResultImpl future =
+ (LDAPFutureResultImpl) pendingRequest;
+ if (future.getRequest() instanceof AddRequest)
+ {
+ future.setResultOrError(result);
+ return;
+ }
}
+ throw new UnexpectedResponseException(messageID, result);
}
- throw new UnexpectedResponseException(messageID, result);
}
}
@@ -104,73 +108,79 @@
{
final LDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(ctx
.getConnection());
- final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
- .removePendingRequest(messageID);
-
- if (pendingRequest != null)
+ if(ldapConnection != null)
{
- if (pendingRequest instanceof LDAPBindFutureResultImpl)
+ final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
+ .removePendingRequest(messageID);
+
+ if (pendingRequest != null)
{
- final LDAPBindFutureResultImpl future = ((LDAPBindFutureResultImpl) pendingRequest);
- final BindClient bindClient = future.getBindClient();
-
- try
+ if (pendingRequest instanceof LDAPBindFutureResultImpl)
{
- if (!bindClient.evaluateResult(result))
- {
- // The server is expecting a multi stage bind response.
- final int msgID = ldapConnection
- .addPendingRequest(pendingRequest);
+ final LDAPBindFutureResultImpl future =
+ ((LDAPBindFutureResultImpl) pendingRequest);
+ final BindClient bindClient = future.getBindClient();
- final ASN1BufferWriter asn1Writer = ASN1BufferWriter.getWriter();
- try
+ try
+ {
+ if (!bindClient.evaluateResult(result))
{
- final GenericBindRequest nextRequest = bindClient
- .nextBindRequest();
- new LDAPWriter().bindRequest(asn1Writer, msgID, 3, nextRequest);
- ctx.write(asn1Writer.getBuffer(), null);
+ // The server is expecting a multi stage bind response.
+ final int msgID = ldapConnection
+ .addPendingRequest(pendingRequest);
+
+ final ASN1BufferWriter asn1Writer =
+ ASN1BufferWriter.getWriter();
+ try
+ {
+ final GenericBindRequest nextRequest = bindClient
+ .nextBindRequest();
+ new LDAPWriter().bindRequest(asn1Writer, msgID, 3,
+ nextRequest);
+ ctx.write(asn1Writer.getBuffer(), null);
+ }
+ finally
+ {
+ asn1Writer.close();
+ }
+ return;
}
- finally
- {
- asn1Writer.close();
- }
+ }
+ catch (final ErrorResultException e)
+ {
+ future.adaptErrorResult(e.getResult());
return;
}
- }
- catch (final ErrorResultException e)
- {
- future.adaptErrorResult(e.getResult());
- return;
- }
- catch (final IOException e)
- {
- // FIXME: I18N need to have a better error message.
- // FIXME: Is this the best result code?
- final Result errorResult = Responses.newResult(
- ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
- "An error occurred during multi-stage authentication")
- .setCause(e);
- future.adaptErrorResult(errorResult);
- return;
- }
-
- if (result.getResultCode() == ResultCode.SUCCESS)
- {
- final ConnectionSecurityLayer l = bindClient
- .getConnectionSecurityLayer();
- if (l != null)
+ catch (final IOException e)
{
- // The connection needs to be secured by the SASL
- // mechanism.
- ldapConnection.installFilter(new SASLFilter(l));
+ // FIXME: I18N need to have a better error message.
+ // FIXME: Is this the best result code?
+ final Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
+ "An error occurred during multi-stage authentication")
+ .setCause(e);
+ future.adaptErrorResult(errorResult);
+ return;
}
- }
- ldapConnection.setBindOrStartTLSInProgress(false);
- future.setResultOrError(result);
- return;
+ if (result.getResultCode() == ResultCode.SUCCESS)
+ {
+ final ConnectionSecurityLayer l = bindClient
+ .getConnectionSecurityLayer();
+ if (l != null)
+ {
+ // The connection needs to be secured by the SASL
+ // mechanism.
+ ldapConnection.installFilter(new SASLFilter(l));
+ }
+ }
+
+ ldapConnection.setBindOrStartTLSInProgress(false);
+ future.setResultOrError(result);
+ return;
+ }
+ throw new UnexpectedResponseException(messageID, result);
}
- throw new UnexpectedResponseException(messageID, result);
}
}
@@ -183,18 +193,22 @@
{
final LDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(ctx
.getConnection());
- final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
- .removePendingRequest(messageID);
-
- if (pendingRequest != null)
+ if(ldapConnection != null)
{
- if (pendingRequest instanceof LDAPCompareFutureResultImpl)
+ final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
+ .removePendingRequest(messageID);
+
+ if (pendingRequest != null)
{
- final LDAPCompareFutureResultImpl future = (LDAPCompareFutureResultImpl) pendingRequest;
- future.setResultOrError(result);
- return;
+ if (pendingRequest instanceof LDAPCompareFutureResultImpl)
+ {
+ final LDAPCompareFutureResultImpl future =
+ (LDAPCompareFutureResultImpl) pendingRequest;
+ future.setResultOrError(result);
+ return;
+ }
+ throw new UnexpectedResponseException(messageID, result);
}
- throw new UnexpectedResponseException(messageID, result);
}
}
@@ -206,21 +220,25 @@
{
final LDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(ctx
.getConnection());
- final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
- .removePendingRequest(messageID);
-
- if (pendingRequest != null)
+ if(ldapConnection != null)
{
- if (pendingRequest instanceof LDAPFutureResultImpl)
+ final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
+ .removePendingRequest(messageID);
+
+ if (pendingRequest != null)
{
- final LDAPFutureResultImpl future = (LDAPFutureResultImpl) pendingRequest;
- if (future.getRequest() instanceof DeleteRequest)
+ if (pendingRequest instanceof LDAPFutureResultImpl)
{
- future.setResultOrError(result);
- return;
+ final LDAPFutureResultImpl future =
+ (LDAPFutureResultImpl) pendingRequest;
+ if (future.getRequest() instanceof DeleteRequest)
+ {
+ future.setResultOrError(result);
+ return;
+ }
}
+ throw new UnexpectedResponseException(messageID, result);
}
- throw new UnexpectedResponseException(messageID, result);
}
}
@@ -233,48 +251,54 @@
{
final LDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(ctx
.getConnection());
- if (messageID == 0)
+ if(ldapConnection != null)
{
- if ((result.getOID() != null)
- && result.getOID().equals(OID_NOTICE_OF_DISCONNECTION))
+ if (messageID == 0)
{
+ if ((result.getOID() != null)
+ && result.getOID().equals(OID_NOTICE_OF_DISCONNECTION))
+ {
- final Result errorResult = Responses
- .newResult(result.getResultCode()).setDiagnosticMessage(
- result.getDiagnosticMessage());
- ldapConnection.close(null, true, errorResult);
- return;
+ final Result errorResult = Responses
+ .newResult(result.getResultCode()).setDiagnosticMessage(
+ result.getDiagnosticMessage());
+ ldapConnection.close(null, true, errorResult);
+ return;
+ }
+ else
+ {
+ // Unsolicited notification received.
+ ldapConnection.handleUnsolicitedNotification(result);
+ }
}
- else
- {
- // Unsolicited notification received.
- ldapConnection.handleUnsolicitedNotification(result);
- }
- }
- final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
- .removePendingRequest(messageID);
+ final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
+ .removePendingRequest(messageID);
- if (pendingRequest instanceof LDAPExtendedFutureResultImpl<?>)
- {
- final LDAPExtendedFutureResultImpl<?> extendedFuture =
- ((LDAPExtendedFutureResultImpl<?>) pendingRequest);
- try
+ if(pendingRequest != null)
{
- handleExtendedResult0(ldapConnection, extendedFuture, result);
+ if (pendingRequest instanceof LDAPExtendedFutureResultImpl<?>)
+ {
+ final LDAPExtendedFutureResultImpl<?> extendedFuture =
+ ((LDAPExtendedFutureResultImpl<?>) pendingRequest);
+ try
+ {
+ handleExtendedResult0(ldapConnection, extendedFuture, result);
+ }
+ catch (final DecodeException de)
+ {
+ // FIXME: should the connection be closed as well?
+ final Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_DECODING_ERROR).setDiagnosticMessage(
+ de.getLocalizedMessage()).setCause(de);
+ extendedFuture.adaptErrorResult(errorResult);
+ }
+ }
+ else
+ {
+ throw new UnexpectedResponseException(messageID, result);
+ }
}
- catch (final DecodeException de)
- {
- // FIXME: should the connection be closed as well?
- final Result errorResult = Responses.newResult(
- ResultCode.CLIENT_SIDE_DECODING_ERROR).setDiagnosticMessage(
- de.getLocalizedMessage()).setCause(de);
- extendedFuture.adaptErrorResult(errorResult);
- }
- }
- else
- {
- throw new UnexpectedResponseException(messageID, result);
}
}
@@ -287,12 +311,15 @@
{
final LDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(ctx
.getConnection());
- final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
- .getPendingRequest(messageID);
-
- if (pendingRequest != null)
+ if(ldapConnection != null)
{
- pendingRequest.handleIntermediateResponse(response);
+ final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
+ .getPendingRequest(messageID);
+
+ if (pendingRequest != null)
+ {
+ pendingRequest.handleIntermediateResponse(response);
+ }
}
}
@@ -305,21 +332,25 @@
{
final LDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(ctx
.getConnection());
- final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
- .removePendingRequest(messageID);
-
- if (pendingRequest != null)
+ if(ldapConnection != null)
{
- if (pendingRequest instanceof LDAPFutureResultImpl)
+ final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
+ .removePendingRequest(messageID);
+
+ if (pendingRequest != null)
{
- final LDAPFutureResultImpl future = (LDAPFutureResultImpl) pendingRequest;
- if (future.getRequest() instanceof ModifyDNRequest)
+ if (pendingRequest instanceof LDAPFutureResultImpl)
{
- future.setResultOrError(result);
- return;
+ final LDAPFutureResultImpl future =
+ (LDAPFutureResultImpl) pendingRequest;
+ if (future.getRequest() instanceof ModifyDNRequest)
+ {
+ future.setResultOrError(result);
+ return;
+ }
}
+ throw new UnexpectedResponseException(messageID, result);
}
- throw new UnexpectedResponseException(messageID, result);
}
}
@@ -331,21 +362,25 @@
{
final LDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(ctx
.getConnection());
- final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
- .removePendingRequest(messageID);
-
- if (pendingRequest != null)
+ if(ldapConnection != null)
{
- if (pendingRequest instanceof LDAPFutureResultImpl)
+ final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
+ .removePendingRequest(messageID);
+
+ if (pendingRequest != null)
{
- final LDAPFutureResultImpl future = (LDAPFutureResultImpl) pendingRequest;
- if (future.getRequest() instanceof ModifyRequest)
+ if (pendingRequest instanceof LDAPFutureResultImpl)
{
- future.setResultOrError(result);
- return;
+ final LDAPFutureResultImpl future =
+ (LDAPFutureResultImpl) pendingRequest;
+ if (future.getRequest() instanceof ModifyRequest)
+ {
+ future.setResultOrError(result);
+ return;
+ }
}
+ throw new UnexpectedResponseException(messageID, result);
}
- throw new UnexpectedResponseException(messageID, result);
}
}
@@ -357,19 +392,22 @@
{
final LDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(ctx
.getConnection());
- final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
- .removePendingRequest(messageID);
-
- if (pendingRequest != null)
+ if(ldapConnection != null)
{
- if (pendingRequest instanceof LDAPSearchFutureResultImpl)
+ final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
+ .removePendingRequest(messageID);
+
+ if (pendingRequest != null)
{
- ((LDAPSearchFutureResultImpl) pendingRequest)
- .setResultOrError(result);
- }
- else
- {
- throw new UnexpectedResponseException(messageID, result);
+ if (pendingRequest instanceof LDAPSearchFutureResultImpl)
+ {
+ ((LDAPSearchFutureResultImpl) pendingRequest)
+ .setResultOrError(result);
+ }
+ else
+ {
+ throw new UnexpectedResponseException(messageID, result);
+ }
}
}
}
@@ -383,18 +421,21 @@
{
final LDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(ctx
.getConnection());
- final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
- .getPendingRequest(messageID);
-
- if (pendingRequest != null)
+ if(ldapConnection != null)
{
- if (pendingRequest instanceof LDAPSearchFutureResultImpl)
+ final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
+ .getPendingRequest(messageID);
+
+ if (pendingRequest != null)
{
- ((LDAPSearchFutureResultImpl) pendingRequest).handleEntry(entry);
- }
- else
- {
- throw new UnexpectedResponseException(messageID, entry);
+ if (pendingRequest instanceof LDAPSearchFutureResultImpl)
+ {
+ ((LDAPSearchFutureResultImpl) pendingRequest).handleEntry(entry);
+ }
+ else
+ {
+ throw new UnexpectedResponseException(messageID, entry);
+ }
}
}
}
@@ -408,19 +449,22 @@
{
final LDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(ctx
.getConnection());
- final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
- .getPendingRequest(messageID);
-
- if (pendingRequest != null)
+ if(ldapConnection != null)
{
- if (pendingRequest instanceof LDAPSearchFutureResultImpl)
+ final AbstractLDAPFutureResultImpl<?> pendingRequest = ldapConnection
+ .getPendingRequest(messageID);
+
+ if (pendingRequest != null)
{
- ((LDAPSearchFutureResultImpl) pendingRequest)
- .handleReference(reference);
- }
- else
- {
- throw new UnexpectedResponseException(messageID, reference);
+ if (pendingRequest instanceof LDAPSearchFutureResultImpl)
+ {
+ ((LDAPSearchFutureResultImpl) pendingRequest)
+ .handleReference(reference);
+ }
+ else
+ {
+ throw new UnexpectedResponseException(messageID, reference);
+ }
}
}
}
@@ -445,6 +489,7 @@
final StartTLSExtendedRequest request = (StartTLSExtendedRequest) future
.getRequest();
conn.startTLS(request.getSSLContext(),
+ request.getEnabledProtocols(), request.getEnabledCipherSuites(),
new EmptyCompletionHandler<SSLEngine>()
{
@Override
@@ -521,7 +566,7 @@
{
// FIXME: what other sort of IOExceptions can be thrown?
// FIXME: Is this the best result code?
- errorResult = Responses.newResult(ResultCode.CLIENT_SIDE_DECODING_ERROR)
+ errorResult = Responses.newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR)
.setCause(error);
}
ldapConnection.close(null, false, errorResult);
@@ -568,6 +613,16 @@
ldapReader.decode(asn1Reader, CLIENT_RESPONSE_HANDLER, ctx);
}
}
+ catch(IOException ioe)
+ {
+ final LDAPConnection ldapConnection =
+ LDAP_CONNECTION_ATTR.get(ctx.getConnection());
+ final Result errorResult =
+ Responses.newResult(ResultCode.CLIENT_SIDE_DECODING_ERROR)
+ .setCause(ioe).setDiagnosticMessage(ioe.getMessage());
+ ldapConnection.close(null, false, errorResult);
+ throw ioe;
+ }
finally
{
asn1Reader.disposeBytesRead();
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPConnection.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPConnection.java
index d3bed34..25f7d84 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPConnection.java
+++ b/opendj-sdk/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);
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPConnectionFactoryImpl.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPConnectionFactoryImpl.java
index ce244bb..d56efdd 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPConnectionFactoryImpl.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPConnectionFactoryImpl.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;
@@ -62,7 +62,7 @@
implements ConnectionFactory
{
- @SuppressWarnings("unchecked")
+ @SuppressWarnings("rawtypes")
private final class FutureResultImpl implements CompletionHandler<Connection>
{
private final FutureResultTransformer<Result, AsynchronousConnection> futureStartTLSResult;
@@ -123,6 +123,8 @@
{
final StartTLSExtendedRequest startTLS = Requests
.newStartTLSExtendedRequest(options.getSSLContext());
+ startTLS.setEnabledCipherSuites(options.getEnabledCipherSuites());
+ startTLS.setEnabledProtocols(options.getEnabledProtocols());
return connection.extendedRequest(startTLS, handler);
}
@@ -131,6 +133,8 @@
try
{
connection.startTLS(options.getSSLContext(),
+ options.getEnabledProtocols(),
+ options.getEnabledCipherSuites(),
new EmptyCompletionHandler<SSLEngine>()
{
@Override
@@ -269,7 +273,7 @@
*/
@Override
public FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> handler)
+ final ResultHandler<? super AsynchronousConnection> handler)
{
final FutureResultImpl future = new FutureResultImpl(handler);
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPExtendedFutureResultImpl.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPExtendedFutureResultImpl.java
index 50a786d..1c162a6 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPExtendedFutureResultImpl.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPExtendedFutureResultImpl.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;
@@ -31,6 +31,7 @@
import org.opends.sdk.*;
import org.opends.sdk.requests.ExtendedRequest;
+import org.opends.sdk.requests.StartTLSExtendedRequest;
import org.opends.sdk.responses.ExtendedResult;
@@ -74,6 +75,16 @@
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean isCancelable() {
+ return !request.getOID().equals(StartTLSExtendedRequest.OID);
+ }
+
+
+
R decodeResult(final ExtendedResult result, final DecodeOptions options)
throws DecodeException
{
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPFutureResultImpl.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPFutureResultImpl.java
index 58a914e..3733164 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPFutureResultImpl.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPFutureResultImpl.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;
@@ -47,7 +47,7 @@
LDAPFutureResultImpl(final int messageID, final Request request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler,
final AsynchronousConnection connection)
{
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPSearchFutureResultImpl.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPSearchFutureResultImpl.java
index 5385a1c..70a8e2d 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPSearchFutureResultImpl.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPSearchFutureResultImpl.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;
@@ -53,14 +53,13 @@
LDAPSearchFutureResultImpl(final int messageID, final SearchRequest request,
- final ResultHandler<Result> resultHandler,
- final SearchResultHandler searchResultHandler,
+ final SearchResultHandler resultHandler,
final IntermediateResponseHandler intermediateResponseHandler,
final AsynchronousConnection connection)
{
super(messageID, resultHandler, intermediateResponseHandler, connection);
this.request = request;
- this.searchResultHandler = searchResultHandler;
+ this.searchResultHandler = resultHandler;
}
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPServerFilter.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPServerFilter.java
index c21c31b..3bd1034 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPServerFilter.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/ldap/LDAPServerFilter.java
@@ -33,8 +33,7 @@
import java.io.IOException;
import java.net.InetSocketAddress;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.*;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
@@ -66,8 +65,8 @@
private abstract class AbstractHandler<R extends Result> implements
IntermediateResponseHandler, ResultHandler<R>
{
- protected int messageID;
- protected Connection<?> connection;
+ protected final int messageID;
+ protected final Connection<?> connection;
@@ -80,6 +79,7 @@
+ @Override
public boolean handleIntermediateResponse(
final IntermediateResponse response)
{
@@ -91,7 +91,7 @@
}
catch (final IOException ioe)
{
- closeConnection(connection, ioe);
+ notifyConnectionException(connection, ioe);
return false;
}
finally
@@ -114,6 +114,7 @@
+ @Override
public void handleErrorResult(final ErrorResultException error)
{
handleResult(error.getResult());
@@ -121,6 +122,7 @@
+ @Override
public void handleResult(final Result result)
{
final ASN1BufferWriter asn1Writer = ASN1BufferWriter.getWriter();
@@ -131,7 +133,7 @@
}
catch (final IOException ioe)
{
- closeConnection(connection, ioe);
+ notifyConnectionException(connection, ioe);
}
finally
{
@@ -151,6 +153,7 @@
+ @Override
public void handleErrorResult(final ErrorResultException error)
{
final Result result = error.getResult();
@@ -175,6 +178,7 @@
+ @Override
public void handleResult(final BindResult result)
{
final ASN1BufferWriter asn1Writer = ASN1BufferWriter.getWriter();
@@ -185,7 +189,7 @@
}
catch (final IOException ioe)
{
- closeConnection(connection, ioe);
+ notifyConnectionException(connection, ioe);
}
finally
{
@@ -198,7 +202,16 @@
private final class ClientContextImpl implements LDAPClientContext
{
- protected Connection<?> connection;
+ private final Connection<?> connection;
+
+ // Connection state guarded by stateLock.
+ private final Object stateLock = new Object();
+ private List<ConnectionEventListener> connectionEventListeners = null;
+ private boolean isClosed = false;
+ private Throwable connectionError = null;
+ private ExtendedResult disconnectNotification = null;
+
+ private ServerConnection<Integer> serverConnection = null;
@@ -209,20 +222,64 @@
- public void disconnect(final boolean sendNotification)
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addConnectionEventListener(
+ final ConnectionEventListener listener) throws NullPointerException
{
- if (sendNotification)
+ Validator.ensureNotNull(listener);
+
+ boolean invokeImmediately = false;
+ synchronized (stateLock)
{
- final GenericExtendedResult notification = Responses
- .newGenericExtendedResult(ResultCode.SUCCESS);
- notification.setOID(OID_NOTICE_OF_DISCONNECTION);
- sendUnsolicitedNotification(notification);
+ if (isClosed)
+ {
+ invokeImmediately = true;
+ }
+ else
+ {
+ if (connectionEventListeners == null)
+ {
+ connectionEventListeners = new LinkedList<ConnectionEventListener>();
+ }
+ connectionEventListeners.add(listener);
+ }
}
- closeConnection(connection, -1, null);
+
+ // Invoke listener immediately if this connection is already closed.
+ if (invokeImmediately)
+ {
+ invokeListener(listener);
+ }
}
+ @Override
+ public void disconnect()
+ {
+ LDAPServerFilter.notifyConnectionClosed(connection, -1, null);
+ }
+
+
+
+ @Override
+ public void disconnect(final ResultCode resultCode, final String message)
+ {
+ Validator.ensureNotNull(resultCode);
+
+ final GenericExtendedResult notification = Responses
+ .newGenericExtendedResult(resultCode)
+ .setOID(OID_NOTICE_OF_DISCONNECTION).setDiagnosticMessage(message);
+ sendUnsolicitedNotification(notification);
+ disconnect();
+ }
+
+
+
+ @Override
public InetSocketAddress getLocalAddress()
{
return (InetSocketAddress) connection.getLocalAddress();
@@ -230,6 +287,7 @@
+ @Override
public InetSocketAddress getPeerAddress()
{
return (InetSocketAddress) connection.getPeerAddress();
@@ -237,6 +295,7 @@
+ @Override
public int getSecurityStrengthFactor()
{
int ssf = 0;
@@ -260,6 +319,43 @@
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isClosed()
+ {
+ final boolean tmp;
+ synchronized (stateLock)
+ {
+ tmp = isClosed;
+ }
+ return tmp;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeConnectionEventListener(
+ final ConnectionEventListener listener) throws NullPointerException
+ {
+ Validator.ensureNotNull(listener);
+
+ synchronized (stateLock)
+ {
+ if (connectionEventListeners != null)
+ {
+ connectionEventListeners.remove(listener);
+ }
+ }
+ }
+
+
+
+ @Override
public void sendUnsolicitedNotification(final ExtendedResult notification)
{
final ASN1BufferWriter asn1Writer = ASN1BufferWriter.getWriter();
@@ -270,16 +366,49 @@
}
catch (final IOException ioe)
{
- closeConnection(connection, ioe);
+ LDAPServerFilter.notifyConnectionException(connection, ioe);
}
finally
{
asn1Writer.recycle();
}
+
+ // Update state and notify event listeners if necessary, only if the
+ // notification was sent successfully.
+ if (notification.getOID().equals(OID_NOTICE_OF_DISCONNECTION))
+ {
+ // Don't notify listeners yet - wait for disconnect.
+ synchronized (stateLock)
+ {
+ disconnectNotification = notification;
+ }
+ }
+ else
+ {
+ // Notify listeners.
+ List<ConnectionEventListener> tmpList = null;
+ synchronized (stateLock)
+ {
+ if (!isClosed && connectionEventListeners != null)
+ {
+ tmpList = new ArrayList<ConnectionEventListener>(
+ connectionEventListeners);
+ }
+ }
+
+ if (tmpList != null)
+ {
+ for (final ConnectionEventListener listener : tmpList)
+ {
+ listener.handleUnsolicitedNotification(notification);
+ }
+ }
+ }
}
+ @Override
public void startSASL(final ConnectionSecurityLayer bindContext)
{
installFilter(connection, new SASLFilter(bindContext));
@@ -287,15 +416,119 @@
- public void startTLS(final SSLContext sslContext)
+ @Override
+ public void startTLS(final SSLContext sslContext, final String[] protocols,
+ final String[] suites, final boolean wantClientAuth,
+ final boolean needClientAuth)
{
Validator.ensureNotNull(sslContext);
SSLEngineConfigurator sslEngineConfigurator;
sslEngineConfigurator = new SSLEngineConfigurator(sslContext, false,
false, false);
+ sslEngineConfigurator.setEnabledCipherSuites(suites);
+ sslEngineConfigurator.setEnabledProtocols(protocols);
+ sslEngineConfigurator.setWantClientAuth(wantClientAuth);
+ sslEngineConfigurator.setNeedClientAuth(needClientAuth);
installFilter(connection, new SSLFilter(sslEngineConfigurator, null));
}
+
+
+
+ private ServerConnection<Integer> getServerConnection()
+ {
+ return serverConnection;
+ }
+
+
+
+ private void invokeListener(final ConnectionEventListener listener)
+ {
+ if (connectionError != null)
+ {
+ final Result result;
+ if (connectionError instanceof DecodeException)
+ {
+ final DecodeException e = (DecodeException) connectionError;
+ result = Responses.newResult(ResultCode.PROTOCOL_ERROR)
+ .setDiagnosticMessage(e.getMessage()).setCause(connectionError);
+ }
+ else
+ {
+ result = Responses.newResult(ResultCode.OTHER)
+ .setDiagnosticMessage(connectionError.getMessage())
+ .setCause(connectionError);
+ }
+ listener
+ .handleConnectionError(false, ErrorResultException.wrap(result));
+ }
+ else if (disconnectNotification != null)
+ {
+ listener.handleConnectionError(true,
+ ErrorResultException.wrap(disconnectNotification));
+ }
+ else
+ {
+ listener.handleConnectionClosed();
+ }
+ }
+
+
+
+ private void notifyConnectionClosed(final int messageID,
+ final UnbindRequest unbindRequest)
+ {
+ final List<ConnectionEventListener> tmpList;
+ synchronized (stateLock)
+ {
+ if (!isClosed)
+ {
+ isClosed = true;
+ }
+ tmpList = connectionEventListeners;
+ connectionEventListeners = null;
+ }
+ if (tmpList != null)
+ {
+ for (final ConnectionEventListener listener : tmpList)
+ {
+ invokeListener(listener);
+ }
+ }
+ }
+
+
+
+ private void notifyConnectionException(final Throwable error)
+ {
+ final List<ConnectionEventListener> tmpList;
+ synchronized (stateLock)
+ {
+ if (!isClosed)
+ {
+ connectionError = error;
+ isClosed = true;
+ }
+ tmpList = connectionEventListeners;
+ connectionEventListeners = null;
+ }
+ if (tmpList != null)
+ {
+ for (final ConnectionEventListener listener : tmpList)
+ {
+ invokeListener(listener);
+ }
+ }
+ }
+
+
+
+ private void setServerConnection(
+ final ServerConnection<Integer> serverConnection)
+ {
+ this.serverConnection = serverConnection;
+ }
+
}
@@ -309,6 +542,7 @@
+ @Override
public void handleErrorResult(final ErrorResultException error)
{
final Result result = error.getResult();
@@ -333,6 +567,7 @@
+ @Override
public void handleResult(final CompareResult result)
{
final ASN1BufferWriter asn1Writer = ASN1BufferWriter.getWriter();
@@ -343,7 +578,7 @@
}
catch (final IOException ioe)
{
- closeConnection(connection, ioe);
+ notifyConnectionException(connection, ioe);
}
finally
{
@@ -363,6 +598,7 @@
+ @Override
public void handleErrorResult(final ErrorResultException error)
{
handleResult(error.getResult());
@@ -370,6 +606,7 @@
+ @Override
public void handleResult(final Result result)
{
final ASN1BufferWriter asn1Writer = ASN1BufferWriter.getWriter();
@@ -380,7 +617,7 @@
}
catch (final IOException ioe)
{
- closeConnection(connection, ioe);
+ notifyConnectionException(connection, ioe);
}
finally
{
@@ -401,6 +638,7 @@
+ @Override
public void handleErrorResult(final ErrorResultException error)
{
final Result result = error.getResult();
@@ -425,6 +663,7 @@
+ @Override
public void handleResult(final ExtendedResult result)
{
final ASN1BufferWriter asn1Writer = ASN1BufferWriter.getWriter();
@@ -435,7 +674,7 @@
}
catch (final IOException ioe)
{
- closeConnection(connection, ioe);
+ notifyConnectionException(connection, ioe);
}
finally
{
@@ -455,6 +694,7 @@
+ @Override
public void handleErrorResult(final ErrorResultException error)
{
handleResult(error.getResult());
@@ -462,6 +702,7 @@
+ @Override
public void handleResult(final Result result)
{
final ASN1BufferWriter asn1Writer = ASN1BufferWriter.getWriter();
@@ -472,7 +713,7 @@
}
catch (final IOException ioe)
{
- closeConnection(connection, ioe);
+ notifyConnectionException(connection, ioe);
}
finally
{
@@ -492,6 +733,7 @@
+ @Override
public void handleErrorResult(final ErrorResultException error)
{
handleResult(error.getResult());
@@ -499,6 +741,7 @@
+ @Override
public void handleResult(final Result result)
{
final ASN1BufferWriter asn1Writer = ASN1BufferWriter.getWriter();
@@ -509,7 +752,7 @@
}
catch (final IOException ioe)
{
- closeConnection(connection, ioe);
+ notifyConnectionException(connection, ioe);
}
finally
{
@@ -530,6 +773,7 @@
+ @Override
public boolean handleEntry(final SearchResultEntry entry)
{
final ASN1BufferWriter asn1Writer = ASN1BufferWriter.getWriter();
@@ -540,7 +784,7 @@
}
catch (final IOException ioe)
{
- closeConnection(connection, ioe);
+ notifyConnectionException(connection, ioe);
return false;
}
finally
@@ -552,6 +796,7 @@
+ @Override
public void handleErrorResult(final ErrorResultException error)
{
handleResult(error.getResult());
@@ -559,6 +804,7 @@
+ @Override
public boolean handleReference(final SearchResultReference reference)
{
final ASN1BufferWriter asn1Writer = ASN1BufferWriter.getWriter();
@@ -569,7 +815,7 @@
}
catch (final IOException ioe)
{
- closeConnection(connection, ioe);
+ notifyConnectionException(connection, ioe);
return false;
}
finally
@@ -581,6 +827,7 @@
+ @Override
public void handleResult(final Result result)
{
final ASN1BufferWriter asn1Writer = ASN1BufferWriter.getWriter();
@@ -591,7 +838,7 @@
}
catch (final IOException ioe)
{
- closeConnection(connection, ioe);
+ notifyConnectionException(connection, ioe);
}
finally
{
@@ -627,24 +874,101 @@
private static final LDAPWriter LDAP_WRITER = new LDAPWriter();
- private static final Attribute<ServerConnection<Integer>>
- LDAP_CONNECTION_ATTR = Grizzly.DEFAULT_ATTRIBUTE_BUILDER.
- createAttribute("LDAPServerConnection");
+ private static final Attribute<ClientContextImpl> LDAP_CONNECTION_ATTR =
+ Grizzly.DEFAULT_ATTRIBUTE_BUILDER
+ .createAttribute("LDAPServerConnection");
private static final Attribute<ASN1BufferReader> LDAP_ASN1_READER_ATTR =
- Grizzly.DEFAULT_ATTRIBUTE_BUILDER.createAttribute("LDAPASN1Reader");
+ Grizzly.DEFAULT_ATTRIBUTE_BUILDER
+ .createAttribute("LDAPASN1Reader");
- private final AbstractLDAPMessageHandler<FilterChainContext>
- serverRequestHandler = new AbstractLDAPMessageHandler<FilterChainContext>()
+
+
+ private static void notifyConnectionClosed(final Connection<?> connection,
+ final int messageID, final UnbindRequest unbindRequest)
+ {
+ final ClientContextImpl clientContext = LDAP_CONNECTION_ATTR
+ .remove(connection);
+ if (clientContext != null)
+ {
+ // First notify connection event listeners.
+ clientContext.notifyConnectionClosed(messageID, unbindRequest);
+
+ // Notify the server connection: it may be null if disconnect is invoked
+ // during accept.
+ final ServerConnection<Integer> serverConnection = clientContext
+ .getServerConnection();
+ if (serverConnection != null)
+ {
+ serverConnection.handleConnectionClosed(messageID, unbindRequest);
+ }
+
+ // If this close was a result of an unbind request then the connection
+ // won't actually be closed yet. To avoid TIME_WAIT TCP state, let the
+ // client disconnect.
+ if (unbindRequest != null)
+ {
+ return;
+ }
+
+ // Close the connection.
+ try
+ {
+ connection.close();
+ }
+ catch (final IOException e)
+ {
+ StaticUtils.DEBUG_LOG.warning("Error closing connection: " + e);
+ }
+ }
+ }
+
+
+
+ private static void notifyConnectionException(final Connection<?> connection,
+ final Throwable error)
+ {
+ final ClientContextImpl clientContext = LDAP_CONNECTION_ATTR
+ .remove(connection);
+ if (clientContext != null)
+ {
+ // First notify connection event listeners.
+ clientContext.notifyConnectionException(error);
+
+ // Notify the server connection: it may be null if disconnect is invoked
+ // during accept.
+ final ServerConnection<Integer> serverConnection = clientContext
+ .getServerConnection();
+ if (serverConnection != null)
+ {
+ serverConnection.handleConnectionException(error);
+ }
+
+ // Close the connection.
+ try
+ {
+ connection.close();
+ }
+ catch (final IOException e)
+ {
+ StaticUtils.DEBUG_LOG.warning("Error closing connection: " + e);
+ }
+ }
+ }
+
+
+
+ private final AbstractLDAPMessageHandler<FilterChainContext> serverRequestHandler =
+ new AbstractLDAPMessageHandler<FilterChainContext>()
{
@Override
public void abandonRequest(final FilterChainContext ctx,
final int messageID, final AbandonRequest request)
throws UnexpectedRequestException
{
- final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(ctx
- .getConnection());
- conn.abandon(messageID, request);
+ final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(
+ ctx.getConnection()).getServerConnection();
+ conn.handleAbandon(messageID, request);
}
@@ -653,10 +977,10 @@
public void addRequest(final FilterChainContext ctx, final int messageID,
final AddRequest request) throws UnexpectedRequestException
{
- final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(ctx
- .getConnection());
+ final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(
+ ctx.getConnection()).getServerConnection();
final AddHandler handler = new AddHandler(messageID, ctx.getConnection());
- conn.add(messageID, request, handler, handler);
+ conn.handleAdd(messageID, request, handler, handler);
}
@@ -666,11 +990,11 @@
final int version, final GenericBindRequest bindContext)
throws UnexpectedRequestException
{
- final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(ctx
- .getConnection());
- final BindHandler handler = new BindHandler(messageID, ctx
- .getConnection());
- conn.bind(messageID, version, bindContext, handler, handler);
+ final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(
+ ctx.getConnection()).getServerConnection();
+ final BindHandler handler = new BindHandler(messageID,
+ ctx.getConnection());
+ conn.handleBind(messageID, version, bindContext, handler, handler);
}
@@ -680,11 +1004,11 @@
final int messageID, final CompareRequest request)
throws UnexpectedRequestException
{
- final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(ctx
- .getConnection());
- final CompareHandler handler = new CompareHandler(messageID, ctx
- .getConnection());
- conn.compare(messageID, request, handler, handler);
+ final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(
+ ctx.getConnection()).getServerConnection();
+ final CompareHandler handler = new CompareHandler(messageID,
+ ctx.getConnection());
+ conn.handleCompare(messageID, request, handler, handler);
}
@@ -694,11 +1018,11 @@
final int messageID, final DeleteRequest request)
throws UnexpectedRequestException
{
- final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(ctx
- .getConnection());
- final DeleteHandler handler = new DeleteHandler(messageID, ctx
- .getConnection());
- conn.delete(messageID, request, handler, handler);
+ final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(
+ ctx.getConnection()).getServerConnection();
+ final DeleteHandler handler = new DeleteHandler(messageID,
+ ctx.getConnection());
+ conn.handleDelete(messageID, request, handler, handler);
}
@@ -708,12 +1032,12 @@
final FilterChainContext ctx, final int messageID,
final ExtendedRequest<R> request) throws UnexpectedRequestException
{
- final ExtendedHandler<R> handler = new ExtendedHandler<R>(messageID, ctx
- .getConnection());
+ final ExtendedHandler<R> handler = new ExtendedHandler<R>(messageID,
+ ctx.getConnection());
- final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(ctx
- .getConnection());
- conn.extendedRequest(messageID, request, handler, handler);
+ final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(
+ ctx.getConnection()).getServerConnection();
+ conn.handleExtendedRequest(messageID, request, handler, handler);
}
@@ -723,11 +1047,11 @@
final int messageID, final ModifyDNRequest request)
throws UnexpectedRequestException
{
- final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(ctx
- .getConnection());
- final ModifyDNHandler handler = new ModifyDNHandler(messageID, ctx
- .getConnection());
- conn.modifyDN(messageID, request, handler, handler);
+ final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(
+ ctx.getConnection()).getServerConnection();
+ final ModifyDNHandler handler = new ModifyDNHandler(messageID,
+ ctx.getConnection());
+ conn.handleModifyDN(messageID, request, handler, handler);
}
@@ -737,11 +1061,11 @@
final int messageID, final ModifyRequest request)
throws UnexpectedRequestException
{
- final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(ctx
- .getConnection());
- final ModifyHandler handler = new ModifyHandler(messageID, ctx
- .getConnection());
- conn.modify(messageID, request, handler, handler);
+ final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(
+ ctx.getConnection()).getServerConnection();
+ final ModifyHandler handler = new ModifyHandler(messageID,
+ ctx.getConnection());
+ conn.handleModify(messageID, request, handler, handler);
}
@@ -751,11 +1075,11 @@
final int messageID, final SearchRequest request)
throws UnexpectedRequestException
{
- final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(ctx
- .getConnection());
- final SearchHandler handler = new SearchHandler(messageID, ctx
- .getConnection());
- conn.search(messageID, request, handler, handler, handler);
+ final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR.get(
+ ctx.getConnection()).getServerConnection();
+ final SearchHandler handler = new SearchHandler(messageID,
+ ctx.getConnection());
+ conn.handleSearch(messageID, request, handler, handler, handler);
}
@@ -764,7 +1088,7 @@
public void unbindRequest(final FilterChainContext ctx,
final int messageID, final UnbindRequest request)
{
- closeConnection(ctx.getConnection(), messageID, request);
+ notifyConnectionClosed(ctx.getConnection(), messageID, request);
}
@@ -774,13 +1098,14 @@
final int messageID, final byte messageTag,
final ByteString messageBytes)
{
- closeConnection(ctx.getConnection(), new UnsupportedMessageException(
- messageID, messageTag, messageBytes));
+ notifyConnectionException(ctx.getConnection(),
+ new UnsupportedMessageException(messageID, messageTag, messageBytes));
}
};
-
private final int maxASN1ElementSize;
+
private final LDAPReader ldapReader;
+
private final LDAPListenerImpl listener;
@@ -799,7 +1124,7 @@
public void exceptionOccurred(final FilterChainContext ctx,
final Throwable error)
{
- closeConnection(ctx.getConnection(), error);
+ notifyConnectionException(ctx.getConnection(), error);
}
@@ -810,12 +1135,13 @@
{
final Connection<?> connection = ctx.getConnection();
connection.configureBlocking(true);
- ServerConnection<Integer> serverConn;
try
{
- serverConn = listener.getConnectionFactory().accept(
- new ClientContextImpl(connection));
- LDAP_CONNECTION_ATTR.set(connection, serverConn);
+ final ClientContextImpl clientContext = new ClientContextImpl(connection);
+ final ServerConnection<Integer> serverConn = listener
+ .getConnectionFactory().accept(clientContext);
+ clientContext.setServerConnection(serverConn);
+ LDAP_CONNECTION_ATTR.set(connection, clientContext);
}
catch (final ErrorResultException e)
{
@@ -831,7 +1157,7 @@
public NextAction handleClose(final FilterChainContext ctx)
throws IOException
{
- closeConnection(ctx.getConnection(), -1, null);
+ notifyConnectionClosed(ctx.getConnection(), -1, null);
return ctx.getStopAction();
}
@@ -867,48 +1193,6 @@
- private void closeConnection(final Connection<?> connection,
- final int messageID, final UnbindRequest unbindRequest)
- {
- final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR
- .remove(connection);
- if (conn != null)
- {
- conn.closed(messageID, unbindRequest);
- try
- {
- connection.close();
- }
- catch (final IOException e)
- {
- StaticUtils.DEBUG_LOG.warning("Error closing connection: " + e);
- }
- }
- }
-
-
-
- private void closeConnection(final Connection<?> connection,
- final Throwable error)
- {
- final ServerConnection<Integer> conn = LDAP_CONNECTION_ATTR
- .remove(connection);
- if (conn != null)
- {
- conn.closed(error);
- try
- {
- connection.close();
- }
- catch (final IOException e)
- {
- StaticUtils.DEBUG_LOG.warning("Error closing connection: " + e);
- }
- }
- }
-
-
-
private synchronized void installFilter(final Connection<?> connection,
final com.sun.grizzly.filterchain.Filter filter)
{
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/messages/messages.properties b/opendj-sdk/sdk/src/com/sun/opends/sdk/messages/messages.properties
index 7b8f5c4..5cb6e2b 100755
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/messages/messages.properties
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/messages/messages.properties
@@ -5834,3 +5834,15 @@
contained the OID '%s', when '%s' was expected
SEVERE_ERR_VIRTUAL_ATTRS_ONLY_INVALID_CONTROL_VALUE=Cannot decode the provided \
virtual attributes only control because it contains a value
+WARN_CLIENT_DUPLICATE_MESSAGE_ID=The Directory Server is already processing \
+ another request on the same client connection with the same message ID of %d
+INFO_CANCELED_BY_ABANDON_REQUEST=The operation was canceled because the client \
+ issued an abandon request (message ID %d) for this operation
+INFO_CANCELED_BY_CANCEL_REQUEST=The operation was canceled because the client \
+ issued a cancel request (message ID %d) for this operation
+INFO_CANCELED_BY_CLIENT_DISCONNECT=The operation was canceled because the \
+ client disconnected
+INFO_CANCELED_BY_CLIENT_ERROR=The operation was canceled because the \
+ client connection failed
+
+
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ArgumentParser.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ArgumentParser.java
index 546185a..8f60c53 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ArgumentParser.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ArgumentParser.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2006-2009 Sun Microsystems, Inc.
+ * Copyright 2006-2010 Sun Microsystems, Inc.
*/
package com.sun.opends.sdk.tools;
@@ -327,7 +327,8 @@
if (versionArgument != null)
{
- if (shortID == versionArgument.getShortIdentifier())
+ if (shortID != null &&
+ shortID.equals(versionArgument.getShortIdentifier()))
{
// Update the version argument to not display its short
// identifier.
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ArgumentParserConnectionFactory.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ArgumentParserConnectionFactory.java
index b3ba2d5..78f7329 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ArgumentParserConnectionFactory.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ArgumentParserConnectionFactory.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package com.sun.opends.sdk.tools;
@@ -332,7 +332,7 @@
*/
@Override
public FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> handler)
+ final ResultHandler<? super AsynchronousConnection> handler)
{
return connFactory.getAsynchronousConnection(handler);
}
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/AuthenticatedConnectionFactory.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/AuthenticatedConnectionFactory.java
index 9f1460a..a331e0e 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/AuthenticatedConnectionFactory.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/AuthenticatedConnectionFactory.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package com.sun.opends.sdk.tools;
@@ -103,7 +103,7 @@
public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -113,7 +113,7 @@
public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -197,7 +197,7 @@
public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -207,7 +207,7 @@
public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -283,7 +283,7 @@
public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -293,7 +293,7 @@
public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -305,7 +305,7 @@
public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -315,7 +315,7 @@
public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -344,7 +344,7 @@
* {@inheritDoc}
*/
public FutureResult<RootDSE> readRootDSE(
- final ResultHandler<RootDSE> handler)
+ final ResultHandler<? super RootDSE> handler)
throws UnsupportedOperationException, IllegalStateException
{
return connection.readRootDSE(handler);
@@ -356,7 +356,7 @@
* {@inheritDoc}
*/
public FutureResult<Schema> readSchema(final DN name,
- final ResultHandler<Schema> handler)
+ final ResultHandler<? super Schema> handler)
throws UnsupportedOperationException, IllegalStateException
{
return connection.readSchema(name, handler);
@@ -368,7 +368,7 @@
* {@inheritDoc}
*/
public FutureResult<Schema> readSchemaForEntry(final DN name,
- final ResultHandler<Schema> handler)
+ final ResultHandler<? super Schema> handler)
throws UnsupportedOperationException, IllegalStateException
{
return connection.readSchemaForEntry(name, handler);
@@ -448,24 +448,22 @@
public FutureResult<Result> search(final SearchRequest request,
- final ResultHandler<Result> resultHandler,
- final SearchResultHandler searchResulthandler)
+ final SearchResultHandler handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
- return connection.search(request, resultHandler, searchResulthandler);
+ return connection.search(request, handler);
}
public FutureResult<Result> search(final SearchRequest request,
- final ResultHandler<Result> resultHandler,
- final SearchResultHandler searchResulthandler,
+ final SearchResultHandler resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
- return connection.search(request, resultHandler, searchResulthandler,
+ return connection.search(request, resultHandler,
intermediateResponseHandler);
}
@@ -592,7 +590,7 @@
private FutureResultImpl(final BindRequest request,
- final ResultHandler<AsynchronousConnection> handler)
+ final ResultHandler<? super AsynchronousConnection> handler)
{
this.bindRequest = request;
this.futureBindResult = new FutureResultTransformer<BindResult, AsynchronousConnection>(
@@ -684,7 +682,7 @@
@Override
public FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> handler)
+ final ResultHandler<? super AsynchronousConnection> handler)
{
final FutureResultImpl future = new FutureResultImpl(request, handler);
future.futureConnectionResult.setFutureResult(parentFactory
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/DataSource.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/DataSource.java
index 4c4438f..bb529f7 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/DataSource.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/DataSource.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package com.sun.opends.sdk.tools;
@@ -65,10 +65,17 @@
{
lines = new ArrayList<String>();
final BufferedReader in = new BufferedReader(new FileReader(file));
- String line;
- while ((line = in.readLine()) != null)
+ try
{
- lines.add(line);
+ String line;
+ while ((line = in.readLine()) != null)
+ {
+ lines.add(line);
+ }
+ }
+ finally
+ {
+ in.close();
}
}
@@ -151,10 +158,17 @@
lines = new ArrayList<String>();
random = new Random(seed);
final BufferedReader in = new BufferedReader(new FileReader(file));
- String line;
- while ((line = in.readLine()) != null)
+ try
{
- lines.add(line);
+ String line;
+ while ((line = in.readLine()) != null)
+ {
+ lines.add(line);
+ }
+ }
+ finally
+ {
+ in.close();
}
}
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/LDAPSearch.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/LDAPSearch.java
index 1741c99..d8a8316 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/LDAPSearch.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/LDAPSearch.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package com.sun.opends.sdk.tools;
@@ -180,6 +180,26 @@
println(LocalizableMessage.raw(reference.toString()));
return true;
}
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void handleErrorResult(ErrorResultException error)
+ {
+ // Ignore.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void handleResult(Result result)
+ {
+ // Ignore.
+ }
}
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ModRate.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ModRate.java
index 2e689e8..548180c 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ModRate.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/ModRate.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package com.sun.opends.sdk.tools;
@@ -334,6 +334,10 @@
try
{
+ if(System.getProperty("org.opends.sdk.ldap.transport.linger") == null)
+ {
+ System.setProperty("org.opends.sdk.ldap.transport.linger", "0");
+ }
connectionFactory = new ArgumentParserConnectionFactory(argParser, this);
runner = new ModifyPerformanceRunner(argParser, this);
propertiesFileArgument = new StringArgument("propertiesFilePath", null,
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/PerformanceRunner.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/PerformanceRunner.java
index 03c0bce..24b5f56 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/PerformanceRunner.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/PerformanceRunner.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package com.sun.opends.sdk.tools;
@@ -214,8 +214,8 @@
if (successCount > 0)
{
strings[2] = String.format("%.3f",
- (waitTime - (gcDuration - lastGCDuration)) / successCount
- / 1000000.0);
+ (waitTime - (gcDuration - lastGCDuration))
+ / (double) successCount / 1000000.0);
}
else
{
@@ -224,7 +224,7 @@
if (totalSuccessCount > 0)
{
strings[3] = String.format("%.3f", (totalWaitTime - gcDuration)
- / totalSuccessCount / 1000000.0);
+ / (double) totalSuccessCount / 1000000.0);
}
else
{
@@ -438,7 +438,8 @@
R handler;
final double targetTimeInMS =
- (1.0 / (targetThroughput / (numThreads * numConnections))) * 1000.0;
+ (1.0 / (targetThroughput /
+ (double) (numThreads * numConnections))) * 1000.0;
double sleepTimeInMS = 0;
long start;
while (!stopRequested && !(maxIterations > 0 && count >= maxIterations))
@@ -706,7 +707,7 @@
int parent;
while (child > start)
{
- parent = (int) Math.floor((child - 1) / 2);
+ parent = (int) Math.floor((child - 1) / 2.0);
if (get(parent) > get(child))
{
swap(parent, child);
@@ -865,14 +866,14 @@
- public void connectionClosed()
+ public void handleConnectionClosed()
{
// Ignore
}
- public synchronized void connectionErrorOccurred(
+ public synchronized void handleConnectionError(
final boolean isDisconnectNotification, final ErrorResultException error)
{
if (!stopRequested)
@@ -889,7 +890,7 @@
- public void connectionReceivedUnsolicitedNotification(
+ public void handleUnsolicitedNotification(
final ExtendedResult notification)
{
// Ignore
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/PromptingTrustManager.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/PromptingTrustManager.java
index 2274f92..53d55ca 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/PromptingTrustManager.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/PromptingTrustManager.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2008 Sun Microsystems, Inc.
+ * Copyright 2008-2010 Sun Microsystems, Inc.
*/
package com.sun.opends.sdk.tools;
@@ -161,7 +161,14 @@
else
{
final FileInputStream fos = new FileInputStream(onDiskTrustStorePath);
- onDiskTrustStore.load(fos, DEFAULT_PASSWORD);
+ try
+ {
+ onDiskTrustStore.load(fos, DEFAULT_PASSWORD);
+ }
+ finally
+ {
+ fos.close();
+ }
}
final TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/SearchRate.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/SearchRate.java
index 830a88a..c30c921 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/SearchRate.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/SearchRate.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package com.sun.opends.sdk.tools;
@@ -169,7 +169,7 @@
sr.setFilter(String.format(filter, data));
sr.setName(String.format(baseDN, data));
}
- return connection.search(sr, handler, handler);
+ return connection.search(sr, handler);
}
}
@@ -393,6 +393,10 @@
try
{
+ if(System.getProperty("org.opends.sdk.ldap.transport.linger") == null)
+ {
+ System.setProperty("org.opends.sdk.ldap.transport.linger", "0");
+ }
connectionFactory = new ArgumentParserConnectionFactory(argParser, this);
runner = new SearchPerformanceRunner(argParser, this);
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/util/AbstractFutureResult.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/util/AbstractFutureResult.java
index a0b0120..1d478d0 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/util/AbstractFutureResult.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/util/AbstractFutureResult.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package com.sun.opends.sdk.util;
@@ -125,7 +125,7 @@
boolean innerCancel(final boolean mayInterruptIfRunning)
{
- if (!setStatePending())
+ if (!isCancelable() || !setStatePending())
{
return false;
}
@@ -410,6 +410,20 @@
/**
+ * Indicates whether this future result can be canceled.
+ *
+ * @return {@code true} if this future result is cancelable or {@code false}
+ * otherwise.
+ */
+ protected boolean isCancelable()
+ {
+ // Return true by default.
+ return true;
+ }
+
+
+
+ /**
* Appends a string representation of this future's state to the provided
* builder.
*
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/AVA.java b/opendj-sdk/sdk/src/org/opends/sdk/AVA.java
index 3949155..6ed0388 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/AVA.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/AVA.java
@@ -164,7 +164,7 @@
return;
}
- if ((length % 2) == 1)
+ if ((length % 2) != 0)
{
final LocalizableMessage message = ERR_HEX_DECODE_INVALID_LENGTH
.get(hexBuffer);
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/AbstractAsynchronousConnection.java b/opendj-sdk/sdk/src/org/opends/sdk/AbstractAsynchronousConnection.java
index 0f2ae0d..56ec077 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/AbstractAsynchronousConnection.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/AbstractAsynchronousConnection.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
@@ -53,8 +53,7 @@
{
private static final class SingleEntryFuture implements
- FutureResult<SearchResultEntry>, ResultHandler<Result>,
- SearchResultHandler
+ FutureResult<SearchResultEntry>, SearchResultHandler
{
private final ResultHandler<? super SearchResultEntry> handler;
@@ -231,7 +230,7 @@
* {@inheritDoc}
*/
public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -280,7 +279,7 @@
* {@inheritDoc}
*/
public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -316,7 +315,7 @@
* {@inheritDoc}
*/
public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -329,7 +328,7 @@
* {@inheritDoc}
*/
public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -358,7 +357,8 @@
/**
* {@inheritDoc}
*/
- public FutureResult<RootDSE> readRootDSE(final ResultHandler<RootDSE> handler)
+ public FutureResult<RootDSE> readRootDSE(
+ final ResultHandler<? super RootDSE> handler)
throws UnsupportedOperationException, IllegalStateException
{
return RootDSE.readRootDSE(this, handler);
@@ -370,7 +370,7 @@
* {@inheritDoc}
*/
public FutureResult<Schema> readSchema(final DN name,
- final ResultHandler<Schema> handler)
+ final ResultHandler<? super Schema> handler)
throws UnsupportedOperationException, IllegalStateException
{
return Schema.readSchema(this, name, handler);
@@ -382,7 +382,7 @@
* {@inheritDoc}
*/
public FutureResult<Schema> readSchemaForEntry(final DN name,
- final ResultHandler<Schema> handler)
+ final ResultHandler<? super Schema> handler)
throws UnsupportedOperationException, IllegalStateException
{
return Schema.readSchema(this, name, handler);
@@ -394,12 +394,11 @@
* {@inheritDoc}
*/
public FutureResult<Result> search(final SearchRequest request,
- final ResultHandler<Result> resultHandler,
- final SearchResultHandler searchResulthandler)
+ final SearchResultHandler handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
- return search(request, resultHandler, searchResulthandler, null);
+ return search(request, handler, null);
}
@@ -414,8 +413,7 @@
NullPointerException
{
final SingleEntryFuture innerFuture = new SingleEntryFuture(handler);
- final FutureResult<Result> future = search(request, innerFuture,
- innerFuture);
+ final FutureResult<Result> future = search(request, innerFuture);
innerFuture.setResultFuture(future);
return innerFuture;
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnection.java b/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnection.java
index 64576de..c56e848 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnection.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnection.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
@@ -34,9 +34,10 @@
import static com.sun.opends.sdk.messages.Messages.ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES;
import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import org.opends.sdk.ldif.ConnectionEntryReader;
import org.opends.sdk.requests.Requests;
import org.opends.sdk.requests.SearchRequest;
import org.opends.sdk.responses.*;
@@ -84,6 +85,26 @@
return true;
}
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void handleErrorResult(ErrorResultException error)
+ {
+ // Ignore.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void handleResult(Result result)
+ {
+ // Ignore.
+ }
+
}
@@ -353,6 +374,26 @@
}
return true;
}
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void handleErrorResult(ErrorResultException error)
+ {
+ // Ignore.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void handleResult(Result result)
+ {
+ // Ignore.
+ }
};
return search(request, handler);
@@ -363,18 +404,16 @@
/**
* {@inheritDoc}
*/
- public List<SearchResultEntry> search(final String baseObject,
+ public ConnectionEntryReader search(final String baseObject,
final SearchScope scope, final String filter,
- final String... attributeDescriptions) throws ErrorResultException,
- InterruptedException, LocalizedIllegalArgumentException,
- UnsupportedOperationException, IllegalStateException,
+ final String... attributeDescriptions)
+ throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
- final List<SearchResultEntry> entries = new LinkedList<SearchResultEntry>();
+ final BlockingQueue<Response> entries = new LinkedBlockingQueue<Response>();
final SearchRequest request = Requests.newSearchRequest(baseObject, scope,
filter, attributeDescriptions);
- search(request, entries);
- return entries;
+ return search(request, entries);
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnectionFactory.java b/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnectionFactory.java
index 4805de0..7ae9ee2 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnectionFactory.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnectionFactory.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
@@ -50,7 +50,7 @@
* {@inheritDoc}
*/
public abstract FutureResult<AsynchronousConnection> getAsynchronousConnection(
- ResultHandler<AsynchronousConnection> handler);
+ ResultHandler<? super AsynchronousConnection> handler);
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/AsynchronousConnection.java b/opendj-sdk/sdk/src/org/opends/sdk/AsynchronousConnection.java
index 5651403..4c0f60f 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/AsynchronousConnection.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/AsynchronousConnection.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
@@ -120,10 +120,10 @@
* Abandons the unfinished operation identified in the provided abandon
* request.
* <p>
- * 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.
+ * 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.
* <p>
* <b>Note:</b> a more convenient approach to abandoning unfinished operations
* is provided via the {@link FutureResult#cancel(boolean)} method.
@@ -134,8 +134,8 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
@@ -158,12 +158,13 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
- FutureResult<Result> add(AddRequest request, ResultHandler<Result> handler)
+ FutureResult<Result> add(AddRequest request,
+ ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
@@ -184,13 +185,13 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
FutureResult<Result> add(AddRequest request,
- ResultHandler<Result> resultHandler,
+ ResultHandler<? super Result> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
@@ -206,8 +207,8 @@
* 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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If the {@code listener} was {@code null}.
*/
@@ -229,8 +230,8 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
@@ -256,8 +257,8 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
@@ -329,8 +330,8 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
@@ -357,8 +358,8 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
@@ -383,14 +384,15 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
FutureResult<Result> delete(DeleteRequest request,
- ResultHandler<Result> handler) throws UnsupportedOperationException,
- IllegalStateException, NullPointerException;
+ ResultHandler<? super Result> handler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException;
@@ -410,13 +412,13 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
FutureResult<Result> delete(DeleteRequest request,
- ResultHandler<Result> resultHandler,
+ ResultHandler<? super Result> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
@@ -438,8 +440,8 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
@@ -467,8 +469,8 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
@@ -505,9 +507,9 @@
/**
* 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.
+ * 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.
*/
@@ -528,14 +530,15 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
FutureResult<Result> modify(ModifyRequest request,
- ResultHandler<Result> handler) throws UnsupportedOperationException,
- IllegalStateException, NullPointerException;
+ ResultHandler<? super Result> handler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException;
@@ -555,13 +558,13 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
FutureResult<Result> modify(ModifyRequest request,
- ResultHandler<Result> resultHandler,
+ ResultHandler<? super Result> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
@@ -581,14 +584,15 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
FutureResult<Result> modifyDN(ModifyDNRequest request,
- ResultHandler<Result> handler) throws UnsupportedOperationException,
- IllegalStateException, NullPointerException;
+ ResultHandler<? super Result> handler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException;
@@ -608,13 +612,13 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
FutureResult<Result> modifyDN(ModifyDNRequest request,
- ResultHandler<Result> resultHandler,
+ ResultHandler<? super Result> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
@@ -649,8 +653,8 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If the {@code name} was {@code null}.
*/
@@ -676,10 +680,10 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
*/
- FutureResult<RootDSE> readRootDSE(ResultHandler<RootDSE> handler)
+ FutureResult<RootDSE> readRootDSE(ResultHandler<? super RootDSE> handler)
throws UnsupportedOperationException, IllegalStateException;
@@ -703,10 +707,10 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
*/
- FutureResult<Schema> readSchema(DN name, ResultHandler<Schema> handler)
+ FutureResult<Schema> readSchema(DN name, ResultHandler<? super Schema> handler)
throws UnsupportedOperationException, IllegalStateException;
@@ -734,10 +738,11 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
*/
- FutureResult<Schema> readSchemaForEntry(DN name, ResultHandler<Schema> handler)
+ FutureResult<Schema> readSchemaForEntry(DN name,
+ ResultHandler<? super Schema> handler)
throws UnsupportedOperationException, IllegalStateException;
@@ -765,10 +770,7 @@
*
* @param request
* The search request.
- * @param resultHandler
- * A result handler which can be used to asynchronously process the
- * operation result when it is received, may be {@code null}.
- * @param searchResulthandler
+ * @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}.
@@ -776,14 +778,13 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
FutureResult<Result> search(SearchRequest request,
- ResultHandler<Result> resultHandler,
- SearchResultHandler searchResulthandler)
+ SearchResultHandler handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
@@ -795,9 +796,6 @@
* @param request
* The search request.
* @param resultHandler
- * A result handler which can be used to asynchronously process the
- * operation result when it is received, may be {@code null}.
- * @param searchResulthandler
* A search result handler which can be used to asynchronously
* process the search result entries and references as they are
* received, may be {@code null}.
@@ -808,14 +806,13 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
FutureResult<Result> search(SearchRequest request,
- ResultHandler<Result> resultHandler,
- SearchResultHandler searchResulthandler,
+ SearchResultHandler resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException;
@@ -841,8 +838,8 @@
* @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}.
+ * If this connection has already been closed, i.e. if
+ * {@code isClosed() == true}.
* @throws NullPointerException
* If the {@code request} was {@code null}.
*/
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java b/opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java
index a0030c0..1027917 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
@@ -85,7 +85,7 @@
public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -95,7 +95,7 @@
public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -179,7 +179,7 @@
public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -189,7 +189,7 @@
public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -254,7 +254,7 @@
public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -264,7 +264,7 @@
public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -276,7 +276,7 @@
public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -286,7 +286,7 @@
public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -315,7 +315,7 @@
* {@inheritDoc}
*/
public FutureResult<RootDSE> readRootDSE(
- final ResultHandler<RootDSE> handler)
+ final ResultHandler<? super RootDSE> handler)
throws UnsupportedOperationException, IllegalStateException
{
return connection.readRootDSE(handler);
@@ -327,7 +327,7 @@
* {@inheritDoc}
*/
public FutureResult<Schema> readSchema(final DN name,
- final ResultHandler<Schema> handler)
+ final ResultHandler<? super Schema> handler)
throws UnsupportedOperationException, IllegalStateException
{
return connection.readSchema(name, handler);
@@ -339,7 +339,7 @@
* {@inheritDoc}
*/
public FutureResult<Schema> readSchemaForEntry(final DN name,
- final ResultHandler<Schema> handler)
+ final ResultHandler<? super Schema> handler)
throws UnsupportedOperationException, IllegalStateException
{
return connection.readSchemaForEntry(name, handler);
@@ -356,24 +356,22 @@
public FutureResult<Result> search(final SearchRequest request,
- final ResultHandler<Result> resultHandler,
- final SearchResultHandler searchResulthandler)
+ final SearchResultHandler handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
- return connection.search(request, resultHandler, searchResulthandler);
+ return connection.search(request, handler);
}
public FutureResult<Result> search(final SearchRequest request,
- final ResultHandler<Result> resultHandler,
- final SearchResultHandler searchResulthandler,
+ final SearchResultHandler resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
- return connection.search(request, resultHandler, searchResulthandler,
+ return connection.search(request, resultHandler,
intermediateResponseHandler);
}
@@ -496,7 +494,7 @@
*/
@Override
public FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> handler)
+ final ResultHandler<? super AsynchronousConnection> handler)
{
final FutureResultImpl future = new FutureResultImpl(request, handler);
future.futureConnectionResult.setFutureResult(parentFactory
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/Connection.java b/opendj-sdk/sdk/src/org/opends/sdk/Connection.java
index 96828e1..c5fab52 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/Connection.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/Connection.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
@@ -31,8 +31,9 @@
import java.io.Closeable;
import java.util.Collection;
-import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import org.opends.sdk.ldif.ConnectionEntryReader;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.*;
import org.opends.sdk.schema.Schema;
@@ -1102,21 +1103,19 @@
/**
* Searches the Directory Server using the provided search parameters. Any
- * matching entries returned by the search will be added to a {@code List}
- * which is returned if the search succeeds. Search result references will be
- * discarded.
+ * matching entries returned by the search will be exposed through the
+ * {@code EntryReader} interface.
* <p>
- * <b>Warning:</b> Usage of this method is discouraged if the search request
- * is expected to yield a large number of search results since the entire set
- * of results will be stored in memory, potentially causing an {@code
- * OutOfMemoryError}.
+ * <b>Warning:</b> When using a queue with an optional capacity bound,
+ * the connection will stop reading responses and wait if necessary for
+ * space to become available.
* <p>
* This method is equivalent to the following code:
*
* <pre>
* SearchRequest request = new SearchRequest(baseDN, scope, filter,
* attributeDescriptions);
- * connection.search(request, new LinkedList<SearchResultEntry>());
+ * connection.search(request, new LinkedBlockingQueue<Response>());
* </pre>
*
* @param baseObject
@@ -1129,16 +1128,7 @@
* order for an entry to be returned.
* @param attributeDescriptions
* The names of the attributes to be included with each entry.
- * @return A list containing any matching entries returned by the search.
- * @throws ErrorResultException
- * If the result code indicates that the request failed for some
- * reason.
- * @throws InterruptedException
- * If the current thread was interrupted while waiting.
- * @throws LocalizedIllegalArgumentException
- * If {@code baseObject} could not be decoded using the default
- * schema or if {@code filter} is not a valid LDAP string
- * representation of a filter.
+ * @return An entry reader exposing the returned entries.
* @throws UnsupportedOperationException
* If this connection does not support search operations.
* @throws IllegalStateException
@@ -1148,13 +1138,39 @@
* If the {@code baseObject}, {@code scope}, or {@code filter} were
* {@code null}.
*/
- List<SearchResultEntry> search(String baseObject, SearchScope scope,
+ ConnectionEntryReader search(String baseObject, SearchScope scope,
String filter, String... attributeDescriptions)
- throws ErrorResultException, InterruptedException,
- LocalizedIllegalArgumentException, UnsupportedOperationException,
+ throws UnsupportedOperationException,
IllegalStateException, NullPointerException;
+ /**
+ * Searches the Directory Server using the provided search parameters. Any
+ * matching entries returned by the search will be exposed through the
+ * {@code EntryReader} interface.
+ * <p>
+ * <b>Warning:</b> When using a queue with an optional capacity bound,
+ * the connection will stop reading responses and wait if necessary for
+ * space to become available.
+ *
+ * @param request
+ * The search request.
+ * @param entries
+ * The queue to which matching entries should be added.
+ * @return 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} or {@code entries} was {@code null}.
+ */
+ ConnectionEntryReader search(SearchRequest request,
+ BlockingQueue<Response> entries)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException;
+
/**
* Searches the Directory Server for a single entry using the provided search
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/ConnectionEventListener.java b/opendj-sdk/sdk/src/org/opends/sdk/ConnectionEventListener.java
index 6225618..f94355b 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/ConnectionEventListener.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/ConnectionEventListener.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
@@ -39,16 +39,6 @@
* An object that registers to be notified when a connection is closed by the
* application, receives an unsolicited notification, or experiences a fatal
* error.
- * <p>
- * TODO: isolate fatal connection errors as a sub-type of ErrorResultException.
- * <p>
- * TODO: do we need client initiated close notification as in JCA / JDBC? A
- * simpler approach would be for the connection pool to wrap the underlying
- * physical connection with its own. It can then intercept the close request
- * from the client. This has the disadvantage in that we lose any specialized
- * methods exposed by the underlying physical connection (i.e. if the physical
- * connection extends Connection and provides additional methods) since the
- * connection pool effectively hides them via its wrapper.
*/
public interface ConnectionEventListener extends EventListener
{
@@ -58,7 +48,7 @@
* notified immediately after the application calls the {@code close} method
* on the associated connection.
*/
- void connectionClosed();
+ void handleConnectionClosed();
@@ -69,10 +59,10 @@
* the provided {@link ErrorResultException} to the application.
* <p>
* <b>Note:</b> disconnect notifications are treated as fatal connection
- * errors and are handled by this method. In this case {@code
- * isDisconnectNotification} will be {@code true} and {@code error} will
- * contain the result code and any diagnostic information contained in the
- * notification message.
+ * errors and are handled by this method. In this case
+ * {@code isDisconnectNotification} will be {@code true} and {@code error}
+ * will contain the result code and any diagnostic information contained in
+ * the notification message.
*
* @param isDisconnectNotification
* {@code true} if the error was triggered by a disconnect
@@ -80,7 +70,7 @@
* @param error
* The exception that is about to be thrown to the application.
*/
- void connectionErrorOccurred(boolean isDisconnectNotification,
+ void handleConnectionError(boolean isDisconnectNotification,
ErrorResultException error);
@@ -90,10 +80,10 @@
* received the provided unsolicited notification from the server.
* <p>
* <b>Note:</b> disconnect notifications are treated as fatal connection
- * errors and are handled by the {@link #connectionErrorOccurred} method.
+ * errors and are handled by the {@link #handleConnectionError} method.
*
* @param notification
- * The unsolicited notification
+ * The unsolicited notification.
*/
- void connectionReceivedUnsolicitedNotification(ExtendedResult notification);
+ void handleUnsolicitedNotification(ExtendedResult notification);
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/ConnectionFactory.java b/opendj-sdk/sdk/src/org/opends/sdk/ConnectionFactory.java
index 1737262..45417cb 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/ConnectionFactory.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/ConnectionFactory.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
@@ -66,7 +66,7 @@
* @return A future which can be used to retrieve the asynchronous connection.
*/
FutureResult<AsynchronousConnection> getAsynchronousConnection(
- ResultHandler<AsynchronousConnection> handler);
+ ResultHandler<? super AsynchronousConnection> handler);
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/ConnectionPool.java b/opendj-sdk/sdk/src/org/opends/sdk/ConnectionPool.java
index de641ce..1789d1d 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/ConnectionPool.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/ConnectionPool.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
@@ -104,7 +104,7 @@
public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -118,7 +118,7 @@
public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -254,14 +254,14 @@
- public void connectionClosed()
+ public void handleConnectionClosed()
{
// Ignore - we intercept close via the close method.
}
- public void connectionErrorOccurred(final boolean isDisconnectNotification,
+ public void handleConnectionError(final boolean isDisconnectNotification,
final ErrorResultException error)
{
// Remove this connection from the pool if its in there. If not,
@@ -289,7 +289,7 @@
- public void connectionReceivedUnsolicitedNotification(
+ public void handleUnsolicitedNotification(
final ExtendedResult notification)
{
// Ignore
@@ -298,7 +298,7 @@
public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -312,7 +312,7 @@
public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -386,7 +386,7 @@
public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -400,7 +400,7 @@
public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -416,7 +416,7 @@
public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -430,7 +430,7 @@
public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -467,7 +467,7 @@
* {@inheritDoc}
*/
public FutureResult<RootDSE> readRootDSE(
- final ResultHandler<RootDSE> handler)
+ final ResultHandler<? super RootDSE> handler)
throws UnsupportedOperationException, IllegalStateException
{
if (isClosed())
@@ -483,7 +483,7 @@
* {@inheritDoc}
*/
public FutureResult<Schema> readSchema(final DN name,
- final ResultHandler<Schema> handler)
+ final ResultHandler<? super Schema> handler)
throws UnsupportedOperationException, IllegalStateException
{
if (isClosed())
@@ -499,7 +499,7 @@
* {@inheritDoc}
*/
public FutureResult<Schema> readSchemaForEntry(final DN name,
- final ResultHandler<Schema> handler)
+ final ResultHandler<? super Schema> handler)
throws UnsupportedOperationException, IllegalStateException
{
if (isClosed())
@@ -523,8 +523,7 @@
public FutureResult<Result> search(final SearchRequest request,
- final ResultHandler<Result> resultHandler,
- final SearchResultHandler searchResulthandler)
+ final SearchResultHandler handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -532,14 +531,13 @@
{
throw new IllegalStateException();
}
- return connection.search(request, resultHandler, searchResulthandler);
+ return connection.search(request, handler);
}
public FutureResult<Result> search(final SearchRequest request,
- final ResultHandler<Result> resultHandler,
- final SearchResultHandler searchResulthandler,
+ final SearchResultHandler resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -548,7 +546,7 @@
{
throw new IllegalStateException();
}
- return connection.search(request, resultHandler, searchResulthandler,
+ return connection.search(request, resultHandler,
intermediateResponseHandler);
}
@@ -654,7 +652,7 @@
@Override
public synchronized FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> handler)
+ final ResultHandler<? super AsynchronousConnection> handler)
{
// This entire method is synchronized to ensure new connects are
// done synchronously to avoid the "pending connect" case.
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java b/opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java
index 4843021..4910e44 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java
@@ -78,7 +78,7 @@
@Override
public FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> resultHandler)
+ final ResultHandler<? super AsynchronousConnection> resultHandler)
{
final ResultHandler<AsynchronousConnection> handler =
new ResultHandler<AsynchronousConnection>()
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java b/opendj-sdk/sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java
index e3fb48f..ccf41df 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
@@ -53,7 +53,7 @@
* operations.
*/
private final class AsynchronousConnectionImpl implements
- AsynchronousConnection, ConnectionEventListener, ResultHandler<Result>
+ AsynchronousConnection, ConnectionEventListener, SearchResultHandler
{
private final AsynchronousConnection connection;
@@ -80,7 +80,7 @@
public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -90,7 +90,7 @@
public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -179,14 +179,14 @@
- public void connectionClosed()
+ public void handleConnectionClosed()
{
// Ignore - we intercept close through the close method.
}
- public void connectionErrorOccurred(final boolean isDisconnectNotification,
+ public void handleConnectionError(final boolean isDisconnectNotification,
final ErrorResultException error)
{
synchronized (activeConnections)
@@ -198,7 +198,7 @@
- public void connectionReceivedUnsolicitedNotification(
+ public void handleUnsolicitedNotification(
final ExtendedResult notification)
{
// Do nothing
@@ -207,7 +207,7 @@
public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -217,7 +217,7 @@
public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -261,6 +261,17 @@
+ /**
+ * {@inheritDoc}
+ */
+ public boolean handleEntry(SearchResultEntry entry)
+ {
+ // Ignore.
+ return true;
+ }
+
+
+
public void handleErrorResult(final ErrorResultException error)
{
connection.close(Requests.newUnbindRequest(), "Heartbeat retured error: "
@@ -269,6 +280,17 @@
+ /**
+ * {@inheritDoc}
+ */
+ public boolean handleReference(SearchResultReference reference)
+ {
+ // Ignore.
+ return true;
+ }
+
+
+
public void handleResult(final Result result)
{
lastSuccessfulPing = System.currentTimeMillis();
@@ -299,7 +321,7 @@
public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -309,7 +331,7 @@
public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -321,7 +343,7 @@
public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<Result> handler)
+ final ResultHandler<? super Result> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -331,7 +353,7 @@
public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<Result> resultHandler,
+ final ResultHandler<? super Result> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
@@ -360,7 +382,7 @@
* {@inheritDoc}
*/
public FutureResult<RootDSE> readRootDSE(
- final ResultHandler<RootDSE> handler)
+ final ResultHandler<? super RootDSE> handler)
throws UnsupportedOperationException, IllegalStateException
{
return connection.readRootDSE(handler);
@@ -372,7 +394,7 @@
* {@inheritDoc}
*/
public FutureResult<Schema> readSchema(final DN name,
- final ResultHandler<Schema> handler)
+ final ResultHandler<? super Schema> handler)
throws UnsupportedOperationException, IllegalStateException
{
return connection.readSchema(name, handler);
@@ -384,7 +406,7 @@
* {@inheritDoc}
*/
public FutureResult<Schema> readSchemaForEntry(final DN name,
- final ResultHandler<Schema> handler)
+ final ResultHandler<? super Schema> handler)
throws UnsupportedOperationException, IllegalStateException
{
return connection.readSchemaForEntry(name, handler);
@@ -401,24 +423,22 @@
public FutureResult<Result> search(final SearchRequest request,
- final ResultHandler<Result> resultHandler,
- final SearchResultHandler searchResultHandler)
+ final SearchResultHandler handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
- return connection.search(request, resultHandler, searchResultHandler);
+ return connection.search(request, handler);
}
public FutureResult<Result> search(final SearchRequest request,
- final ResultHandler<Result> resultHandler,
- final SearchResultHandler searchResulthandler,
+ final SearchResultHandler resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
- return connection.search(request, resultHandler, searchResulthandler,
+ return connection.search(request, resultHandler,
intermediateResponseHandler);
}
@@ -590,7 +610,7 @@
@Override
public FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> handler)
+ final ResultHandler<? super AsynchronousConnection> handler)
{
final FutureResultImpl future = new FutureResultImpl(handler);
future.setFutureResult(parentFactory.getAsynchronousConnection(future));
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/InternalConnectionFactory.java b/opendj-sdk/sdk/src/org/opends/sdk/InternalConnectionFactory.java
index ba990db..8749d7a 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/InternalConnectionFactory.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/InternalConnectionFactory.java
@@ -61,7 +61,7 @@
@Override
public FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> handler)
+ final ResultHandler<? super AsynchronousConnection> handler)
{
final ServerConnection<Integer> serverConnection;
try
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/LDAPClientContext.java b/opendj-sdk/sdk/src/org/opends/sdk/LDAPClientContext.java
index 194c7c4..878e020 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/LDAPClientContext.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/LDAPClientContext.java
@@ -46,13 +46,45 @@
public interface LDAPClientContext
{
/**
- * Disconnects the client and optionally sends a disconnect notification.
+ * Registers the provided connection event listener so that it will be
+ * notified when the underlying connection is closed by the client, receives
+ * an unsolicited notification, or experiences a fatal error.
+ * <p>
+ * This method provides a event notification mechanism which can be used by
+ * asynchronous request handler implementations to detect connection
+ * termination.
*
- * @param sendNotification
- * {@code true} to send a disconnect notification, or {@code false}
- * otherwise.
+ * @param listener
+ * The listener which wants to be notified when events occur on the
+ * underlying connection.
+ * @throws NullPointerException
+ * If the {@code listener} was {@code null}.
+ * @see #isClosed
*/
- void disconnect(boolean sendNotification);
+ void addConnectionEventListener(ConnectionEventListener listener)
+ throws NullPointerException;
+
+
+
+ /**
+ * Disconnects the client without sending a disconnect notification.
+ */
+ void disconnect();
+
+
+
+ /**
+ * Disconnects the client and sends a disconnect notification, if possible,
+ * containing the provided result code and diagnostic message.
+ *
+ * @param resultCode
+ * The result code which should be included with the disconnect
+ * notification.
+ * @param message
+ * The diagnostic message, which may be empty or {@code null}
+ * indicating that none was provided.
+ */
+ void disconnect(ResultCode resultCode, String message);
@@ -86,6 +118,39 @@
/**
+ * Returns {@code true} if the underlying connection is closed by the client,
+ * receives an unsolicited notification, or experiences a fatal error.
+ * <p>
+ * This method provides a polling mechanism which can be used by synchronous
+ * request handler implementations to detect connection termination.
+ *
+ * @return {@code true} if the underlying connection is closed by the client,
+ * receives an unsolicited notification, or experiences a fatal error,
+ * otherwise {@code false}.
+ * @see #addConnectionEventListener
+ */
+ boolean isClosed();
+
+
+
+ /**
+ * Removes the provided connection event listener from this client context so
+ * that it will no longer be notified when the underlying 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 the underlying connection.
+ * @throws NullPointerException
+ * If the {@code listener} was {@code null}.
+ */
+ void removeConnectionEventListener(ConnectionEventListener listener)
+ throws NullPointerException;
+
+
+
+ /**
* Sends an unsolicited notification to the client.
*
* @param notification
@@ -112,7 +177,19 @@
*
* @param sslContext
* The {@code SSLContext} which should be used to secure the
- * connection.
+ * @param protocols
+ * Names of all the protocols to enable or {@code null} to use the
+ * default protocols.
+ * @param suites
+ * Names of all the suites to enable or {@code null} to use the
+ * default cipher suites.
+ * @param wantClientAuth
+ * Set to {@code true} if client authentication is requested, or
+ * {@code false} if no client authentication is desired.
+ * @param needClientAuth
+ * Set to {@code true} if client authentication is required, or
+ * {@code false} if no client authentication is desired.
*/
- void startTLS(SSLContext sslContext);
+ void startTLS(SSLContext sslContext, String[] protocols, String[] suites,
+ boolean wantClientAuth, boolean needClientAuth);
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/LDAPConnectionFactory.java b/opendj-sdk/sdk/src/org/opends/sdk/LDAPConnectionFactory.java
index 25a52e6..5cbde4a 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/LDAPConnectionFactory.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/LDAPConnectionFactory.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
@@ -134,7 +134,7 @@
* {@inheritDoc}
*/
public FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> handler)
+ final ResultHandler<? super AsynchronousConnection> handler)
{
return impl.getAsynchronousConnection(handler);
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/LDAPOptions.java b/opendj-sdk/sdk/src/org/opends/sdk/LDAPOptions.java
index 0c17217..f58cbfa 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/LDAPOptions.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/LDAPOptions.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
@@ -50,6 +50,16 @@
private DecodeOptions decodeOptions;
+ /**
+ * The list of cipher suite
+ */
+ private String[] enabledCipherSuites = null;
+
+ /**
+ * the list of protocols
+ */
+ private String[] enabledProtocols = null;
+
/**
@@ -80,6 +90,8 @@
this.timeoutInMillis = options.timeoutInMillis;
this.useStartTLS = options.useStartTLS;
this.decodeOptions = new DecodeOptions(options.decodeOptions);
+ this.enabledCipherSuites = options.enabledCipherSuites;
+ this.enabledProtocols = options.enabledProtocols;
}
@@ -224,4 +236,66 @@
return useStartTLS;
}
+ /**
+ * Set the protocol versions enabled for secure connections with the
+ * Directory Server.
+ *
+ * The protocols must be supported by the SSLContext specified in
+ * {@link #setSSLContext(SSLContext)}. Following a successful call to
+ * this method, only the protocols listed in the protocols parameter are
+ * enabled for use.
+ *
+ * @param protocols Names of all the protocols to enable or {@code null} to
+ * use the default protocols.
+ * @return A reference to this LDAP connection options.
+ */
+ public final LDAPOptions setEnabledProtocols(String[] protocols)
+ {
+ this.enabledProtocols = protocols;
+ return this;
+ }
+
+ /**
+ * Set the cipher suites enabled for secure connections with the
+ * Directory Server.
+ *
+ * The suites must be supported by the SSLContext specified in
+ * {@link #setSSLContext(SSLContext)}. Following a successful call to
+ * this method, only the suites listed in the protocols parameter are
+ * enabled for use.
+ *
+ * @param suites Names of all the suites to enable or {@code null} to
+ * use the default cipher suites.
+ * @return A reference to this LDAP connection options.
+ */
+ public final LDAPOptions setEnabledCipherSuites(String[] suites)
+ {
+ this.enabledCipherSuites = suites;
+ return this;
+ }
+
+ /**
+ * Returns the names of the protocol versions which are currently enabled
+ * for secure connections with the Directory Server.
+ *
+ * @return an array of protocols or {@code null} if the default protocols
+ * are to be used.
+ */
+ public final String[] getEnabledProtocols()
+ {
+ return this.enabledProtocols;
+ }
+
+ /**
+ * Returns the names of the protocol versions which are currently enabled
+ * for secure connections with the Directory Server.
+ *
+ * @return an array of protocols or {@code null} if the default protocols
+ * are to be used.
+ */
+ public final String[] getEnabledCipherSuites()
+ {
+ return this.enabledCipherSuites;
+ }
+
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/LDAPUrl.java b/opendj-sdk/sdk/src/org/opends/sdk/LDAPUrl.java
index d7a23fb..37d5938 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/LDAPUrl.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/LDAPUrl.java
@@ -463,7 +463,7 @@
else
{
listenPort = port.intValue();
- if (listenPort < 1 && listenPort > Integer.MAX_VALUE)
+ if (listenPort < 1 || listenPort > 65535)
{
final LocalizableMessage msg = ERR_LDAPURL_BAD_PORT.get(listenPort);
throw new LocalizedIllegalArgumentException(msg);
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingConnectionFactory.java b/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingConnectionFactory.java
index 5e416d7..af4b0b7 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingConnectionFactory.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingConnectionFactory.java
@@ -54,7 +54,7 @@
@Override
public FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> resultHandler)
+ final ResultHandler<? super AsynchronousConnection> resultHandler)
{
ConnectionFactory factory;
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/RootDSE.java b/opendj-sdk/sdk/src/org/opends/sdk/RootDSE.java
index 9410450..b5762dd 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/RootDSE.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/RootDSE.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
@@ -156,7 +156,7 @@
*/
public static FutureResult<RootDSE> readRootDSE(
final AsynchronousConnection connection,
- final ResultHandler<RootDSE> handler)
+ final ResultHandler<? super RootDSE> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/SearchResultHandler.java b/opendj-sdk/sdk/src/org/opends/sdk/SearchResultHandler.java
index fc059b0..9f870d5 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/SearchResultHandler.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/SearchResultHandler.java
@@ -22,13 +22,14 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
+import org.opends.sdk.responses.Result;
import org.opends.sdk.responses.SearchResultEntry;
import org.opends.sdk.responses.SearchResultReference;
@@ -48,7 +49,7 @@
* avoid keeping the invoking thread from dispatching to other completion
* handlers.
*/
-public interface SearchResultHandler
+public interface SearchResultHandler extends ResultHandler<Result>
{
/**
* Invoked each time a search result entry is returned from an asynchronous
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/SearchResultReferenceIOException.java b/opendj-sdk/sdk/src/org/opends/sdk/SearchResultReferenceIOException.java
new file mode 100644
index 0000000..ea7ba1a
--- /dev/null
+++ b/opendj-sdk/sdk/src/org/opends/sdk/SearchResultReferenceIOException.java
@@ -0,0 +1,81 @@
+/*
+ * 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 2010 Sun Microsystems, Inc.
+ */
+
+package org.opends.sdk;
+
+
+
+import java.io.IOException;
+
+import org.opends.sdk.responses.SearchResultReference;
+
+import com.sun.opends.sdk.util.Validator;
+
+
+
+/**
+ * Thrown when an iteration over a set of search results using a
+ * {@code ConnectionEntryReader} encounters a {@code SearchResultReference}.
+ */
+@SuppressWarnings("serial")
+public final class SearchResultReferenceIOException extends IOException
+{
+ private final SearchResultReference reference;
+
+
+
+ /**
+ * Creates a new referral result IO exception with the provided
+ * {@code SearchResultReference}.
+ *
+ * @param reference
+ * The {@code SearchResultReference} which may be later retrieved by
+ * the {@link #getReference} method.
+ * @throws NullPointerException
+ * If {@code reference} was {@code null}.
+ */
+ public SearchResultReferenceIOException(final SearchResultReference reference)
+ throws NullPointerException
+ {
+ super(Validator.ensureNotNull(reference).toString());
+ this.reference = reference;
+ }
+
+
+
+ /**
+ * Returns the {@code SearchResultReference} which was encountered while
+ * processing the search results.
+ *
+ * @return The {@code SearchResultReference} which was encountered while
+ * processing the search results.
+ */
+ public SearchResultReference getReference()
+ {
+ return reference;
+ }
+}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/ServerConnection.java b/opendj-sdk/sdk/src/org/opends/sdk/ServerConnection.java
index ef81e2a..950f6dc 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/ServerConnection.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/ServerConnection.java
@@ -56,7 +56,7 @@
* @throws UnsupportedOperationException
* If this server connection does not handle abandon requests.
*/
- void abandon(C requestContext, AbandonRequest request)
+ void handleAbandon(C requestContext, AbandonRequest request)
throws UnsupportedOperationException;
@@ -77,8 +77,8 @@
* @throws UnsupportedOperationException
* If this server connection does not handle add requests.
*/
- void add(C requestContext, AddRequest request,
- ResultHandler<Result> resultHandler,
+ void handleAdd(C requestContext, AddRequest request,
+ ResultHandler<? super Result> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException;
@@ -102,7 +102,7 @@
* @throws UnsupportedOperationException
* If this server connection does not handle bind requests.
*/
- void bind(C requestContext, int version, BindRequest request,
+ void handleBind(C requestContext, int version, BindRequest request,
ResultHandler<? super BindResult> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException;
@@ -110,30 +110,6 @@
/**
- * Invoked when the client closes the connection, possibly using an unbind
- * request.
- *
- * @param requestContext
- * The request context.
- * @param request
- * The unbind request, which may be {@code null} if one was not sent
- * before the connection was closed.
- */
- void closed(C requestContext, UnbindRequest request);
-
-
-
- /**
- * Invoked when an error occurs on the connection and it is no longer usable.
- *
- * @param error
- * The exception describing the problem that occurred.
- */
- void closed(Throwable error);
-
-
-
- /**
* Invoked when a compare request is received from a client.
*
* @param requestContext
@@ -149,7 +125,7 @@
* @throws UnsupportedOperationException
* If this server connection does not handle compare requests.
*/
- void compare(C requestContext, CompareRequest request,
+ void handleCompare(C requestContext, CompareRequest request,
ResultHandler<? super CompareResult> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException;
@@ -157,6 +133,30 @@
/**
+ * Invoked when the client closes the connection, possibly using an unbind
+ * request.
+ *
+ * @param requestContext
+ * The request context.
+ * @param request
+ * The unbind request, which may be {@code null} if one was not sent
+ * before the connection was closed.
+ */
+ void handleConnectionClosed(C requestContext, UnbindRequest request);
+
+
+
+ /**
+ * Invoked when an error occurs on the connection and it is no longer usable.
+ *
+ * @param error
+ * The exception describing the problem that occurred.
+ */
+ void handleConnectionException(Throwable error);
+
+
+
+ /**
* Invoked when a delete request is received from a client.
*
* @param requestContext
@@ -172,8 +172,8 @@
* @throws UnsupportedOperationException
* If this server connection does not handle delete requests.
*/
- void delete(C requestContext, DeleteRequest request,
- ResultHandler<Result> resultHandler,
+ void handleDelete(C requestContext, DeleteRequest request,
+ ResultHandler<? super Result> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException;
@@ -197,8 +197,8 @@
* @throws UnsupportedOperationException
* If this server connection does not handle extended requests.
*/
- <R extends ExtendedResult> void extendedRequest(C requestContext,
- ExtendedRequest<R> request, ResultHandler<R> resultHandler,
+ <R extends ExtendedResult> void handleExtendedRequest(C requestContext,
+ ExtendedRequest<R> request, ResultHandler<? super R> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException;
@@ -220,8 +220,8 @@
* @throws UnsupportedOperationException
* If this server connection does not handle modify requests.
*/
- void modify(C requestContext, ModifyRequest request,
- ResultHandler<Result> resultHandler,
+ void handleModify(C requestContext, ModifyRequest request,
+ ResultHandler<? super Result> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException;
@@ -243,8 +243,8 @@
* @throws UnsupportedOperationException
* If this server connection does not handle modify DN requests.
*/
- void modifyDN(C requestContext, ModifyDNRequest request,
- ResultHandler<Result> resultHandler,
+ void handleModifyDN(C requestContext, ModifyDNRequest request,
+ ResultHandler<? super Result> resultHandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException;
@@ -269,8 +269,8 @@
* @throws UnsupportedOperationException
* If this server connection does not handle search requests.
*/
- void search(C requestContext, SearchRequest request,
- ResultHandler<Result> resultHandler,
+ void handleSearch(C requestContext, SearchRequest request,
+ ResultHandler<? super Result> resultHandler,
SearchResultHandler searchResulthandler,
IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException;
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/SynchronousConnection.java b/opendj-sdk/sdk/src/org/opends/sdk/SynchronousConnection.java
index 1d82232..b1bac79 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/SynchronousConnection.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/SynchronousConnection.java
@@ -22,22 +22,21 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk;
+import org.opends.sdk.ldif.ConnectionEntryReader;
import org.opends.sdk.requests.*;
-import org.opends.sdk.responses.BindResult;
-import org.opends.sdk.responses.CompareResult;
-import org.opends.sdk.responses.ExtendedResult;
-import org.opends.sdk.responses.Result;
+import org.opends.sdk.responses.*;
import org.opends.sdk.schema.Schema;
import com.sun.opends.sdk.util.Validator;
+import java.util.concurrent.BlockingQueue;
/**
@@ -350,8 +349,7 @@
InterruptedException, UnsupportedOperationException,
IllegalStateException, NullPointerException
{
- final FutureResult<Result> future = connection.search(request, null,
- handler);
+ final FutureResult<Result> future = connection.search(request, handler);
try
{
return future.get();
@@ -363,4 +361,15 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
+ public ConnectionEntryReader search(final SearchRequest request,
+ BlockingQueue<Response> entries)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return new ConnectionEntryReader(getAsynchronousConnection(),
+ request, entries);
+ }
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/controls/EntryChangeNotificationResponseControl.java b/opendj-sdk/sdk/src/org/opends/sdk/controls/EntryChangeNotificationResponseControl.java
index 1c3a5b4..6c29336 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/controls/EntryChangeNotificationResponseControl.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/controls/EntryChangeNotificationResponseControl.java
@@ -157,16 +157,19 @@
final Schema schema = options.getSchemaResolver().resolveSchema(
previousDNString);
- DN previousDN;
- try
+ DN previousDN = null;
+ if (previousDNString != null)
{
- previousDN = DN.valueOf(previousDNString, schema);
- }
- catch (final LocalizedIllegalArgumentException e)
- {
- final LocalizableMessage message = ERR_ECN_INVALID_PREVIOUS_DN
- .get(getExceptionMessage(e));
- throw DecodeException.error(message, e);
+ try
+ {
+ previousDN = DN.valueOf(previousDNString, schema);
+ }
+ catch (final LocalizedIllegalArgumentException e)
+ {
+ final LocalizableMessage message = ERR_ECN_INVALID_PREVIOUS_DN
+ .get(getExceptionMessage(e));
+ throw DecodeException.error(message, e);
+ }
}
return new EntryChangeNotificationResponseControl(control.isCritical(),
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/ldif/ConnectionEntryReader.java b/opendj-sdk/sdk/src/org/opends/sdk/ldif/ConnectionEntryReader.java
new file mode 100644
index 0000000..17a0be2
--- /dev/null
+++ b/opendj-sdk/sdk/src/org/opends/sdk/ldif/ConnectionEntryReader.java
@@ -0,0 +1,311 @@
+/*
+ * 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 2010 Sun Microsystems, Inc.
+ */
+
+package org.opends.sdk.ldif;
+
+
+
+import java.io.InterruptedIOException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.opends.sdk.*;
+import org.opends.sdk.requests.SearchRequest;
+import org.opends.sdk.responses.*;
+
+import com.sun.opends.sdk.util.Validator;
+
+
+
+/**
+ * A {@code ConnectionEntryReader} is a bridge from
+ * {@code AsynchronousConnection}s to {@code EntryReader}s. A connection entry
+ * reader allows applications to iterate over search results as they are
+ * returned from the server during a search operation.
+ * <p>
+ * The Search operation is performed synchronously, blocking until a search
+ * result entry is received. If a search result indicates that the search
+ * operation has failed for some reason then the error result is propagated to
+ * the caller using an {@code ErrorResultIOException}. If a search result
+ * reference is returned then it is propagated to the caller using a
+ * {@code SearchResultReferenceIOException}.
+ * <p>
+ * The following code illustrates how a {@code ConnectionEntryReader} may be
+ * used:
+ *
+ * <pre>
+ * Connection connection = ...;
+ * ConnectionEntryReader results = connection.search(
+ * "dc=example,dc=com",
+ * SearchScope.WHOLE_SUBTREE,
+ * "(objectClass=person)");
+ * SearchResultEntry entry;
+ * try
+ * {
+ * while ((entry = results.readEntry()) != null)
+ * {
+ * // Process search result entry.
+ * }
+ * }
+ * catch (Exception e)
+ * {
+ * // Handle exceptions
+ * }
+ * finally
+ * {
+ * results.close();
+ * }
+ * </pre>
+ */
+public final class ConnectionEntryReader implements EntryReader
+{
+
+ /**
+ * Result handler that places all responses in a queue.
+ */
+ private final static class BufferHandler implements SearchResultHandler
+ {
+ private final BlockingQueue<Response> responses;
+ private volatile boolean isInterrupted = false;
+
+
+
+ private BufferHandler(final BlockingQueue<Response> responses)
+ {
+ this.responses = responses;
+ }
+
+
+
+ @Override
+ public boolean handleEntry(final SearchResultEntry entry)
+ {
+ try
+ {
+ responses.put(entry);
+ return true;
+ }
+ catch (final InterruptedException e)
+ {
+ // Prevent the reader from waiting for a result that will never arrive.
+ isInterrupted = true;
+
+ Thread.currentThread().interrupt();
+ return false;
+ }
+ }
+
+
+
+ @Override
+ public void handleErrorResult(final ErrorResultException error)
+ {
+ try
+ {
+ responses.put(error.getResult());
+ }
+ catch (final InterruptedException e)
+ {
+ // Prevent the reader from waiting for a result that will never arrive.
+ isInterrupted = true;
+
+ Thread.currentThread().interrupt();
+ }
+ }
+
+
+
+ @Override
+ public boolean handleReference(final SearchResultReference reference)
+ {
+ try
+ {
+ responses.put(reference);
+ return true;
+ }
+ catch (final InterruptedException e)
+ {
+ // Prevent the reader from waiting for a result that will never arrive.
+ isInterrupted = true;
+
+ Thread.currentThread().interrupt();
+ return false;
+ }
+ }
+
+
+
+ @Override
+ public void handleResult(final Result result)
+ {
+ try
+ {
+ responses.put(result);
+ }
+ catch (final InterruptedException e)
+ {
+ // Prevent the reader from waiting for a result that will never arrive.
+ isInterrupted = true;
+
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+
+
+ private final BufferHandler buffer;
+ private final FutureResult<Result> future;
+
+
+
+ /**
+ * Creates a new connection entry reader whose destination is the provided
+ * connection using an unbounded {@code LinkedBlockingQueue}.
+ *
+ * @param connection
+ * The connection to use.
+ * @param searchRequest
+ * The search request to retrieve entries with.
+ * @throws NullPointerException
+ * If {@code connection} was {@code null}.
+ */
+ public ConnectionEntryReader(final AsynchronousConnection connection,
+ final SearchRequest searchRequest) throws NullPointerException
+ {
+ this(connection, searchRequest, new LinkedBlockingQueue<Response>());
+ }
+
+
+
+ /**
+ * Creates a new connection entry reader whose destination is the provided
+ * connection.
+ *
+ * @param connection
+ * The connection to use.
+ * @param searchRequest
+ * The search request to retrieve entries with.
+ * @param entries
+ * The {@code BlockingQueue} implementation to use when queuing the
+ * returned entries.
+ * @throws NullPointerException
+ * If {@code connection} was {@code null}.
+ */
+ public ConnectionEntryReader(final AsynchronousConnection connection,
+ final SearchRequest searchRequest, final BlockingQueue<Response> entries)
+ throws NullPointerException
+ {
+ Validator.ensureNotNull(connection);
+ buffer = new BufferHandler(entries);
+ future = connection.search(searchRequest, buffer);
+ }
+
+
+
+ /**
+ * Closes this connection entry reader, cancelling the search request if it is
+ * still active.
+ */
+ @Override
+ public void close()
+ {
+ // Cancel the search if it is still running.
+ future.cancel(true);
+ }
+
+
+
+ /**
+ * Returns the next search result entry contained in the search results,
+ * waiting if necessary until one becomes available.
+ *
+ * @return The next search result entry, or {@code null} if there are no more
+ * entries in the search results.
+ * @throws SearchResultReferenceIOException
+ * If the next search response was a search result reference. This
+ * connection entry reader may still contain remaining search
+ * results and references which can be retrieved using additional
+ * calls to this method.
+ * @throws ErrorResultIOException
+ * If the result code indicates that the search operation failed for
+ * some reason.
+ * @throws InterruptedIOException
+ * If the current thread was interrupted while waiting.
+ */
+ @Override
+ public SearchResultEntry readEntry() throws SearchResultReferenceIOException,
+ ErrorResultIOException, InterruptedIOException
+ {
+ Response r;
+ try
+ {
+ while ((r = buffer.responses.poll(50, TimeUnit.MILLISECONDS)) == null)
+ {
+ if (buffer.isInterrupted)
+ {
+ // The worker thread processing the result was interrupted so no
+ // result will ever arrive. We don't want to hang this thread forever
+ // while we wait, so terminate now.
+ r = Responses.newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR);
+ break;
+ }
+ }
+ }
+ catch (final InterruptedException e)
+ {
+ throw new InterruptedIOException(e.getMessage());
+ }
+
+ if (r instanceof SearchResultEntry)
+ {
+ return (SearchResultEntry) r;
+ }
+ else if (r instanceof SearchResultReference)
+ {
+ throw new SearchResultReferenceIOException((SearchResultReference) r);
+ }
+ else if (r instanceof Result)
+ {
+ final Result result = (Result) r;
+ if (result.isSuccess())
+ {
+ return null;
+ }
+ else
+ {
+ throw new ErrorResultIOException(ErrorResultException.wrap(result));
+ }
+ }
+ else
+ {
+ throw new RuntimeException("Unexpected response type: "
+ + r.getClass().toString());
+ }
+ }
+}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/requests/CRAMMD5SASLBindRequestImpl.java b/opendj-sdk/sdk/src/org/opends/sdk/requests/CRAMMD5SASLBindRequestImpl.java
index 9b925ac..b959191 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/requests/CRAMMD5SASLBindRequestImpl.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/requests/CRAMMD5SASLBindRequestImpl.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk.requests;
@@ -111,27 +111,22 @@
public boolean evaluateResult(final BindResult result)
throws ErrorResultException
{
- if (result.getResultCode() == ResultCode.SASL_BIND_IN_PROGRESS
- && result.getServerSASLCredentials() != null)
+ try
{
- try
- {
- setNextSASLCredentials(saslClient.evaluateChallenge(result
- .getServerSASLCredentials().toByteArray()));
- return false;
- }
- catch (final SaslException e)
- {
- // FIXME: I18N need to have a better error message.
- // FIXME: Is this the best result code?
- throw ErrorResultException.wrap(Responses.newResult(
- ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
- "An error occurred during multi-stage authentication")
- .setCause(e));
- }
+ setNextSASLCredentials(saslClient.evaluateChallenge(result
+ .getServerSASLCredentials() == null ? new byte[0] :
+ result.getServerSASLCredentials().toByteArray()));
+ return saslClient.isComplete();
}
-
- return true;
+ catch (final SaslException e)
+ {
+ // FIXME: I18N need to have a better error message.
+ // FIXME: Is this the best result code?
+ throw ErrorResultException.wrap(Responses.newResult(
+ ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
+ "An error occurred during multi-stage authentication")
+ .setCause(e));
+ }
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/requests/DigestMD5SASLBindRequestImpl.java b/opendj-sdk/sdk/src/org/opends/sdk/requests/DigestMD5SASLBindRequestImpl.java
index 3917be4..c81e762 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/requests/DigestMD5SASLBindRequestImpl.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/requests/DigestMD5SASLBindRequestImpl.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk.requests;
@@ -122,26 +122,22 @@
public boolean evaluateResult(final BindResult result)
throws ErrorResultException
{
- if (result.getResultCode() == ResultCode.SASL_BIND_IN_PROGRESS
- && result.getServerSASLCredentials() != null)
+ try
{
- try
- {
- setNextSASLCredentials(saslClient.evaluateChallenge(result
- .getServerSASLCredentials().toByteArray()));
- return false;
- }
- catch (final SaslException e)
- {
- // FIXME: I18N need to have a better error message.
- // FIXME: Is this the best result code?
- throw ErrorResultException.wrap(Responses.newResult(
- ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
- "An error occurred during multi-stage authentication")
- .setCause(e));
- }
+ setNextSASLCredentials(saslClient.evaluateChallenge(result
+ .getServerSASLCredentials() == null ? new byte[0] :
+ result.getServerSASLCredentials().toByteArray()));
+ return saslClient.isComplete();
}
- return true;
+ catch (final SaslException e)
+ {
+ // FIXME: I18N need to have a better error message.
+ // FIXME: Is this the best result code?
+ throw ErrorResultException.wrap(Responses.newResult(
+ ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
+ "An error occurred during multi-stage authentication")
+ .setCause(e));
+ }
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/requests/ExternalSASLBindRequestImpl.java b/opendj-sdk/sdk/src/org/opends/sdk/requests/ExternalSASLBindRequestImpl.java
index 80acd82..b6afa0d 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/requests/ExternalSASLBindRequestImpl.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/requests/ExternalSASLBindRequestImpl.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk.requests;
@@ -102,26 +102,22 @@
public boolean evaluateResult(final BindResult result)
throws ErrorResultException
{
- if (result.getResultCode() == ResultCode.SASL_BIND_IN_PROGRESS
- && result.getServerSASLCredentials() != null)
+ try
{
- try
- {
- setNextSASLCredentials(saslClient.evaluateChallenge(result
- .getServerSASLCredentials().toByteArray()));
- return false;
- }
- catch (final SaslException e)
- {
- // FIXME: I18N need to have a better error message.
- // FIXME: Is this the best result code?
- throw ErrorResultException.wrap(Responses.newResult(
- ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
- "An error occurred during multi-stage authentication")
- .setCause(e));
- }
+ setNextSASLCredentials(saslClient.evaluateChallenge(result
+ .getServerSASLCredentials() == null ? new byte[0] :
+ result.getServerSASLCredentials().toByteArray()));
+ return saslClient.isComplete();
}
- return true;
+ catch (final SaslException e)
+ {
+ // FIXME: I18N need to have a better error message.
+ // FIXME: Is this the best result code?
+ throw ErrorResultException.wrap(Responses.newResult(
+ ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
+ "An error occurred during multi-stage authentication")
+ .setCause(e));
+ }
}
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/requests/StartTLSExtendedRequest.java b/opendj-sdk/sdk/src/org/opends/sdk/requests/StartTLSExtendedRequest.java
index 33d8249..012e294 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/requests/StartTLSExtendedRequest.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/requests/StartTLSExtendedRequest.java
@@ -117,6 +117,62 @@
/**
+ * Set the protocol versions enabled for secure connections with the
+ * Directory Server.
+ *
+ * The protocols must be supported by the SSLContext specified in
+ * {@link #setSSLContext(SSLContext)}. Following a successful call to
+ * this method, only the protocols listed in the protocols parameter are
+ * enabled for use.
+ *
+ * @param protocols Names of all the protocols to enable or {@code null} to
+ * use the default protocols.
+ * @return A reference to this LDAP connection options.
+ */
+ StartTLSExtendedRequest setEnabledProtocols(String[] protocols);
+
+
+
+ /**
+ * Set the cipher suites enabled for secure connections with the
+ * Directory Server.
+ *
+ * The suites must be supported by the SSLContext specified in
+ * {@link #setSSLContext(SSLContext)}. Following a successful call to
+ * this method, only the suites listed in the protocols parameter are
+ * enabled for use.
+ *
+ * @param suites Names of all the suites to enable or {@code null} to
+ * use the default cipher suites.
+ * @return A reference to this LDAP connection options.
+ */
+ StartTLSExtendedRequest setEnabledCipherSuites(String[] suites);
+
+
+
+ /**
+ * Returns the names of the protocol versions which are currently enabled
+ * for secure connections with the Directory Server.
+ *
+ * @return an array of protocols or {@code null} if the default protocols
+ * are to be used.
+ */
+ String[] getEnabledProtocols();
+
+
+
+ /**
+ * Returns the names of the protocol versions which are currently enabled
+ * for secure connections with the Directory Server.
+ *
+ * @return an array of protocols or {@code null} if the default protocols
+ * are to be used.
+ */
+ String[] getEnabledCipherSuites();
+
+
+
+ /**
* {@inheritDoc}
*/
ByteString getValue();
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/requests/StartTLSExtendedRequestImpl.java b/opendj-sdk/sdk/src/org/opends/sdk/requests/StartTLSExtendedRequestImpl.java
index 49dd4f6..9032e55 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/requests/StartTLSExtendedRequestImpl.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/requests/StartTLSExtendedRequestImpl.java
@@ -98,6 +98,16 @@
private SSLContext sslContext;
+ /**
+ * The list of cipher suite
+ */
+ private String[] enabledCipherSuites = null;
+
+ /**
+ * the list of protocols
+ */
+ private String[] enabledProtocols = null;
+
// No need to expose this.
private static final ExtendedResultDecoder<ExtendedResult> RESULT_DECODER = new ResultDecoder();
@@ -152,6 +162,48 @@
/**
+ * {@inheritDoc}}
+ */
+ public StartTLSExtendedRequest setEnabledProtocols(String[] protocols)
+ {
+ this.enabledProtocols = protocols;
+ return this;
+ }
+
+
+
+ /**
+ * {@inheritDoc}}
+ */
+ public StartTLSExtendedRequest setEnabledCipherSuites(String[] suites)
+ {
+ this.enabledCipherSuites = suites;
+ return this;
+ }
+
+
+
+ /**
+ * {@inheritDoc}}
+ */
+ public String[] getEnabledProtocols()
+ {
+ return this.enabledProtocols;
+ }
+
+
+
+ /**
+ * {@inheritDoc}}
+ */
+ public String[] getEnabledCipherSuites()
+ {
+ return this.enabledCipherSuites;
+ }
+
+
+
+ /**
* {@inheritDoc}
*/
@Override
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/schema/Schema.java b/opendj-sdk/sdk/src/org/opends/sdk/schema/Schema.java
index bcd2ea6..d984613 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/schema/Schema.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/schema/Schema.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2009 Sun Microsystems, Inc.
+ * Copyright 2009-2010 Sun Microsystems, Inc.
*/
package org.opends.sdk.schema;
@@ -1462,21 +1462,21 @@
private static volatile Schema defaultSchema = CoreSchemaImpl.getInstance();
- private static final String ATTR_ATTRIBUTE_TYPES = "attributeTypes";
+ static final String ATTR_ATTRIBUTE_TYPES = "attributeTypes";
- private static final String ATTR_DIT_CONTENT_RULES = "dITContentRules";
+ static final String ATTR_DIT_CONTENT_RULES = "dITContentRules";
- private static final String ATTR_DIT_STRUCTURE_RULES = "dITStructureRules";
+ static final String ATTR_DIT_STRUCTURE_RULES = "dITStructureRules";
- private static final String ATTR_LDAP_SYNTAXES = "ldapSyntaxes";
+ static final String ATTR_LDAP_SYNTAXES = "ldapSyntaxes";
- private static final String ATTR_MATCHING_RULE_USE = "matchingRuleUse";
+ static final String ATTR_MATCHING_RULE_USE = "matchingRuleUse";
- private static final String ATTR_MATCHING_RULES = "matchingRules";
+ static final String ATTR_MATCHING_RULES = "matchingRules";
- private static final String ATTR_NAME_FORMS = "nameForms";
+ static final String ATTR_NAME_FORMS = "nameForms";
- private static final String ATTR_OBJECT_CLASSES = "objectClasses";
+ static final String ATTR_OBJECT_CLASSES = "objectClasses";
private static final String ATTR_SUBSCHEMA_SUBENTRY = "subschemaSubentry";
@@ -1679,7 +1679,7 @@
*/
public static FutureResult<Schema> readSchemaForEntry(
final AsynchronousConnection connection, final DN name,
- final ResultHandler<Schema> handler)
+ final ResultHandler<? super Schema> handler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
@@ -1780,137 +1780,7 @@
*/
public static Schema valueOf(final Entry entry)
{
- final SchemaBuilder builder = new SchemaBuilder(entry.getName().toString());
-
- Attribute attr = entry.getAttribute(ATTR_LDAP_SYNTAXES);
- if (attr != null)
- {
- for (final ByteString def : attr)
- {
- try
- {
- builder.addSyntax(def.toString(), true);
- }
- catch (final LocalizedIllegalArgumentException e)
- {
- builder.addWarning(e.getMessageObject());
- }
- }
- }
-
- attr = entry.getAttribute(ATTR_ATTRIBUTE_TYPES);
- if (attr != null)
- {
- for (final ByteString def : attr)
- {
- try
- {
- builder.addAttributeType(def.toString(), true);
- }
- catch (final LocalizedIllegalArgumentException e)
- {
- builder.addWarning(e.getMessageObject());
- }
- }
- }
-
- attr = entry.getAttribute(ATTR_OBJECT_CLASSES);
- if (attr != null)
- {
- for (final ByteString def : attr)
- {
- try
- {
- builder.addObjectClass(def.toString(), true);
- }
- catch (final LocalizedIllegalArgumentException e)
- {
- builder.addWarning(e.getMessageObject());
- }
- }
- }
-
- attr = entry.getAttribute(ATTR_MATCHING_RULE_USE);
- if (attr != null)
- {
- for (final ByteString def : attr)
- {
- try
- {
- builder.addMatchingRuleUse(def.toString(), true);
- }
- catch (final LocalizedIllegalArgumentException e)
- {
- builder.addWarning(e.getMessageObject());
- }
- }
- }
-
- attr = entry.getAttribute(ATTR_MATCHING_RULES);
- if (attr != null)
- {
- for (final ByteString def : attr)
- {
- try
- {
- builder.addMatchingRule(def.toString(), true);
- }
- catch (final LocalizedIllegalArgumentException e)
- {
- builder.addWarning(e.getMessageObject());
- }
- }
- }
-
- attr = entry.getAttribute(ATTR_DIT_CONTENT_RULES);
- if (attr != null)
- {
- for (final ByteString def : attr)
- {
- try
- {
- builder.addDITContentRule(def.toString(), true);
- }
- catch (final LocalizedIllegalArgumentException e)
- {
- builder.addWarning(e.getMessageObject());
- }
- }
- }
-
- attr = entry.getAttribute(ATTR_DIT_STRUCTURE_RULES);
- if (attr != null)
- {
- for (final ByteString def : attr)
- {
- try
- {
- builder.addDITStructureRule(def.toString(), true);
- }
- catch (final LocalizedIllegalArgumentException e)
- {
- builder.addWarning(e.getMessageObject());
- }
- }
- }
-
- attr = entry.getAttribute(ATTR_NAME_FORMS);
- if (attr != null)
- {
- for (final ByteString def : attr)
- {
- try
- {
- builder.addNameForm(def.toString(), true);
- }
- catch (final LocalizedIllegalArgumentException e)
- {
- builder.addWarning(e.getMessageObject());
- }
- }
- }
-
- return builder.toSchema();
+ return new SchemaBuilder(entry).toSchema();
}
@@ -2641,6 +2511,105 @@
+ /**
+ * Adds the definitions of all the schema elements contained in this schema to
+ * the provided subschema subentry. Any existing attributes (including schema
+ * definitions) contained in the provided entry will be preserved.
+ *
+ * @param entry
+ * The subschema subentry to which all schema definitions should be
+ * added.
+ * @return The updated subschema subentry.
+ * @throws NullPointerException
+ * If {@code entry} was {@code null}.
+ */
+ public Entry toEntry(Entry entry) throws NullPointerException
+ {
+ Attribute attr = new LinkedAttribute(Schema.ATTR_LDAP_SYNTAXES);
+ for (Syntax syntax : getSyntaxes())
+ {
+ attr.add(syntax.toString());
+ }
+ if (!attr.isEmpty())
+ {
+ entry.addAttribute(attr);
+ }
+
+ attr = new LinkedAttribute(Schema.ATTR_ATTRIBUTE_TYPES);
+ for (AttributeType attributeType : getAttributeTypes())
+ {
+ attr.add(attributeType.toString());
+ }
+ if (!attr.isEmpty())
+ {
+ entry.addAttribute(attr);
+ }
+
+ attr = new LinkedAttribute(Schema.ATTR_OBJECT_CLASSES);
+ for (ObjectClass objectClass : getObjectClasses())
+ {
+ attr.add(objectClass.toString());
+ }
+ if (!attr.isEmpty())
+ {
+ entry.addAttribute(attr);
+ }
+
+ attr = new LinkedAttribute(Schema.ATTR_MATCHING_RULE_USE);
+ for (MatchingRuleUse matchingRuleUse : getMatchingRuleUses())
+ {
+ attr.add(matchingRuleUse.toString());
+ }
+ if (!attr.isEmpty())
+ {
+ entry.addAttribute(attr);
+ }
+
+ attr = new LinkedAttribute(Schema.ATTR_MATCHING_RULES);
+ for (MatchingRule matchingRule : getMatchingRules())
+ {
+ attr.add(matchingRule.toString());
+ }
+ if (!attr.isEmpty())
+ {
+ entry.addAttribute(attr);
+ }
+
+ attr = new LinkedAttribute(Schema.ATTR_DIT_CONTENT_RULES);
+ for (DITContentRule ditContentRule : getDITContentRules())
+ {
+ attr.add(ditContentRule.toString());
+ }
+ if (!attr.isEmpty())
+ {
+ entry.addAttribute(attr);
+ }
+
+ attr = new LinkedAttribute(Schema.ATTR_DIT_STRUCTURE_RULES);
+ for (DITStructureRule ditStructureRule : getDITStuctureRules())
+ {
+ attr.add(ditStructureRule.toString());
+ }
+ if (!attr.isEmpty())
+ {
+ entry.addAttribute(attr);
+ }
+
+ attr = new LinkedAttribute(Schema.ATTR_NAME_FORMS);
+ for (NameForm nameForm : getNameForms())
+ {
+ attr.add(nameForm.toString());
+ }
+ if (!attr.isEmpty())
+ {
+ entry.addAttribute(attr);
+ }
+
+ return entry;
+ }
+
+
+
SchemaCompatOptions getSchemaCompatOptions()
{
return impl.getSchemaCompatOptions();
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/schema/SchemaBuilder.java b/opendj-sdk/sdk/src/org/opends/sdk/schema/SchemaBuilder.java
index 2dcd5ce..3509ec4 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/schema/SchemaBuilder.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/schema/SchemaBuilder.java
@@ -42,9 +42,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
-import org.opends.sdk.DecodeException;
-import org.opends.sdk.LocalizableMessage;
-import org.opends.sdk.LocalizedIllegalArgumentException;
+import org.opends.sdk.*;
import com.sun.opends.sdk.util.StaticUtils;
import com.sun.opends.sdk.util.SubstringReader;
@@ -116,6 +114,152 @@
/**
+ * Creates a new schema builder containing all of the schema elements
+ * contained in the provided a subschema subentry. Any problems encountered
+ * while parsing the entry can be retrieved using the returned schema's
+ * {@link Schema#getWarnings()} method.
+ *
+ * @param entry
+ * The subschema subentry to be parsed.
+ * @throws NullPointerException
+ * If {@code entry} was {@code null}.
+ */
+ public SchemaBuilder(final Entry entry) throws NullPointerException
+ {
+ initBuilder(entry.getName().toString());
+
+ Attribute attr = entry.getAttribute(Schema.ATTR_LDAP_SYNTAXES);
+ if (attr != null)
+ {
+ for (final ByteString def : attr)
+ {
+ try
+ {
+ addSyntax(def.toString(), true);
+ }
+ catch (final LocalizedIllegalArgumentException e)
+ {
+ addWarning(e.getMessageObject());
+ }
+ }
+ }
+
+ attr = entry.getAttribute(Schema.ATTR_ATTRIBUTE_TYPES);
+ if (attr != null)
+ {
+ for (final ByteString def : attr)
+ {
+ try
+ {
+ addAttributeType(def.toString(), true);
+ }
+ catch (final LocalizedIllegalArgumentException e)
+ {
+ addWarning(e.getMessageObject());
+ }
+ }
+ }
+
+ attr = entry.getAttribute(Schema.ATTR_OBJECT_CLASSES);
+ if (attr != null)
+ {
+ for (final ByteString def : attr)
+ {
+ try
+ {
+ addObjectClass(def.toString(), true);
+ }
+ catch (final LocalizedIllegalArgumentException e)
+ {
+ addWarning(e.getMessageObject());
+ }
+ }
+ }
+
+ attr = entry.getAttribute(Schema.ATTR_MATCHING_RULE_USE);
+ if (attr != null)
+ {
+ for (final ByteString def : attr)
+ {
+ try
+ {
+ addMatchingRuleUse(def.toString(), true);
+ }
+ catch (final LocalizedIllegalArgumentException e)
+ {
+ addWarning(e.getMessageObject());
+ }
+ }
+ }
+
+ attr = entry.getAttribute(Schema.ATTR_MATCHING_RULES);
+ if (attr != null)
+ {
+ for (final ByteString def : attr)
+ {
+ try
+ {
+ addMatchingRule(def.toString(), true);
+ }
+ catch (final LocalizedIllegalArgumentException e)
+ {
+ addWarning(e.getMessageObject());
+ }
+ }
+ }
+
+ attr = entry.getAttribute(Schema.ATTR_DIT_CONTENT_RULES);
+ if (attr != null)
+ {
+ for (final ByteString def : attr)
+ {
+ try
+ {
+ addDITContentRule(def.toString(), true);
+ }
+ catch (final LocalizedIllegalArgumentException e)
+ {
+ addWarning(e.getMessageObject());
+ }
+ }
+ }
+
+ attr = entry.getAttribute(Schema.ATTR_DIT_STRUCTURE_RULES);
+ if (attr != null)
+ {
+ for (final ByteString def : attr)
+ {
+ try
+ {
+ addDITStructureRule(def.toString(), true);
+ }
+ catch (final LocalizedIllegalArgumentException e)
+ {
+ addWarning(e.getMessageObject());
+ }
+ }
+ }
+
+ attr = entry.getAttribute(Schema.ATTR_NAME_FORMS);
+ if (attr != null)
+ {
+ for (final ByteString def : attr)
+ {
+ try
+ {
+ addNameForm(def.toString(), true);
+ }
+ catch (final LocalizedIllegalArgumentException e)
+ {
+ addWarning(e.getMessageObject());
+ }
+ }
+ }
+ }
+
+
+
+ /**
* Creates a new schema builder containing all of the schema elements from the
* provided schema and its compatibility options.
*
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/AuthenticatedConnectionFactoryTestCase.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/AuthenticatedConnectionFactoryTestCase.java
deleted file mode 100644
index 9ff1cd1..0000000
--- a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/AuthenticatedConnectionFactoryTestCase.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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 2010 Sun Microsystems, Inc.
- */
-
-package org.opends.sdk;
-
-
-
-import org.opends.sdk.requests.Requests;
-
-
-
-/**
- * Tests the authenticated connection factory.
- */
-public class AuthenticatedConnectionFactoryTestCase extends
- ConnectionFactoryTestCase
-{
- private final AuthenticatedConnectionFactory authFactory = new AuthenticatedConnectionFactory(
- new LDAPConnectionFactory("localhost", TestCaseUtils.getLdapPort()),
- Requests.newSimpleBindRequest("", ""));
-
-
-
- @Override
- protected FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> handler)
- {
- return authFactory.getAsynchronousConnection(handler);
- }
-
-
-
- @Override
- protected Connection getConnection() throws Exception
- {
- return authFactory.getConnection();
- }
-}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/ConnectionFactoryTestCase.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/ConnectionFactoryTestCase.java
index 4d85d2e..1bde983 100644
--- a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/ConnectionFactoryTestCase.java
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/ConnectionFactoryTestCase.java
@@ -33,16 +33,21 @@
import static org.testng.Assert.assertTrue;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import org.opends.sdk.requests.Requests;
+import org.opends.sdk.requests.SearchRequest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import javax.net.ssl.SSLContext;
/**
* Tests the connectionfactory classes.
*/
-public abstract class ConnectionFactoryTestCase extends SdkTestCase
+public class ConnectionFactoryTestCase extends SdkTestCase
{
class MyResultHandler implements ResultHandler<AsynchronousConnection>
{
@@ -90,7 +95,63 @@
TestCaseUtils.startServer();
}
+ @DataProvider(name = "connectionFactories")
+ public Object[][] getModifyDNRequests() throws Exception
+ {
+ Object[][] factories = new Object[7][1];
+ // HeartBeatConnectionFactory
+ // Use custom search request.
+ SearchRequest request = Requests.newSearchRequest(
+ "uid=user.0,ou=people,o=test", SearchScope.BASE_OBJECT, "objectclass=*",
+ "cn");
+
+ factories[0][0] = new HeartBeatConnectionFactory(
+ new LDAPConnectionFactory("localhost", TestCaseUtils.getLdapPort()),
+ 1000, TimeUnit.MILLISECONDS, request);
+
+ // InternalConnectionFactory
+ factories[1][0] = Connections
+ .newInternalConnectionFactory(LDAPServer.getInstance(), null);
+
+ // AuthenticatedConnectionFactory
+ factories[2][0] = new AuthenticatedConnectionFactory(
+ new LDAPConnectionFactory("localhost", TestCaseUtils.getLdapPort()),
+ Requests.newSimpleBindRequest("", ""));
+
+ // AuthenticatedConnectionFactory with multi-stage SASL
+ factories[3][0] = new AuthenticatedConnectionFactory(
+ new LDAPConnectionFactory("localhost", TestCaseUtils.getLdapPort()),
+ Requests.newCRAMMD5SASLBindRequest("id:user",
+ ByteString.valueOf("password")));
+
+ // LDAPConnectionFactory with default options
+ factories[4][0] = new LDAPConnectionFactory(
+ "localhost", TestCaseUtils.getLdapPort());
+
+ // LDAPConnectionFactory with startTLS
+ SSLContext sslContext = new SSLContextBuilder().
+ setTrustManager(TrustManagers.trustAll()).getSSLContext();
+ LDAPOptions options = new LDAPOptions().setSSLContext(sslContext).
+ setUseStartTLS(true).setEnabledCipherSuites(
+ new String[]{"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
+ "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",
+ "SSL_DH_anon_WITH_DES_CBC_SHA",
+ "SSL_DH_anon_WITH_RC4_128_MD5",
+ "TLS_DH_anon_WITH_AES_128_CBC_SHA",
+ "TLS_DH_anon_WITH_AES_256_CBC_SHA"});
+ factories[5][0] = new LDAPConnectionFactory(
+ "localhost", TestCaseUtils.getLdapPort(), options);
+
+ // startTLS + SASL confidentiality
+ factories[6][0] = new AuthenticatedConnectionFactory(
+ new LDAPConnectionFactory("localhost", TestCaseUtils.getLdapPort(),
+ options), Requests.newDigestMD5SASLBindRequest("id:user",
+ ByteString.valueOf("password")));
+
+ return factories;
+ }
/**
* Tests the async connection in the blocking mode. This is not fully async as
@@ -98,10 +159,12 @@
*
* @throws Exception
*/
- @Test()
- public void testBlockingFutureNoHandler() throws Exception
+ @Test(dataProvider = "connectionFactories")
+ public void testBlockingFutureNoHandler(ConnectionFactory factory)
+ throws Exception
{
- final FutureResult<AsynchronousConnection> future = getAsynchronousConnection(null);
+ final FutureResult<AsynchronousConnection> future =
+ factory.getAsynchronousConnection(null);
final AsynchronousConnection con = future.get();
// quickly check if iit is a valid connection.
// Don't use a result handler.
@@ -116,13 +179,15 @@
*
* @throws Exception
*/
- @Test()
- public void testNonBlockingFutureWithHandler() throws Exception
+ @Test(dataProvider = "connectionFactories")
+ public void testNonBlockingFutureWithHandler(ConnectionFactory factory)
+ throws Exception
{
// Use the handler to get the result asynchronously.
final CountDownLatch latch = new CountDownLatch(1);
final MyResultHandler handler = new MyResultHandler(latch);
- final FutureResult<AsynchronousConnection> future = getAsynchronousConnection(handler);
+ final FutureResult<AsynchronousConnection> future =
+ factory.getAsynchronousConnection(handler);
// Since we don't have anything to do, we would rather
// be notified by the latch when the other thread calls our handler.
latch.await(); // should do a timed wait rather?
@@ -140,32 +205,14 @@
*
* @throws Exception
*/
- @Test()
- public void testSynchronousConnection() throws Exception
+ @Test(dataProvider = "connectionFactories")
+ public void testSynchronousConnection(ConnectionFactory factory)
+ throws Exception
{
- final Connection con = getConnection();
+ final Connection con = factory.getConnection();
assertNotNull(con);
// quickly check if iit is a valid connection.
assertTrue(con.readRootDSE().getEntry().getName().isRootDN());
con.close();
}
-
-
-
- /**
- * Gets the future result from the implementations.
- *
- * @return FutureResult.
- */
- protected abstract FutureResult<AsynchronousConnection> getAsynchronousConnection(
- ResultHandler<AsynchronousConnection> handler) throws Exception;
-
-
-
- /**
- * Gets the connection from the implementations.
- *
- * @return Connection
- */
- protected abstract Connection getConnection() throws Exception;
}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/HeartBeatConnectionFactoryTestCase.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/HeartBeatConnectionFactoryTestCase.java
deleted file mode 100644
index d1adf26..0000000
--- a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/HeartBeatConnectionFactoryTestCase.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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 2010 Sun Microsystems, Inc.
- */
-
-package org.opends.sdk;
-
-
-
-import java.util.concurrent.TimeUnit;
-
-import org.opends.sdk.requests.Requests;
-import org.opends.sdk.requests.SearchRequest;
-
-
-
-/**
- * Tests the Heart beat connection factory.
- */
-public class HeartBeatConnectionFactoryTestCase extends
- ConnectionFactoryTestCase
-{
- // Use custom search request.
- SearchRequest request = Requests.newSearchRequest(
- "uid=user.0,ou=people,o=test", SearchScope.BASE_OBJECT, "objectclass=*",
- "cn");
-
- // The factory.
- private final HeartBeatConnectionFactory factory = new HeartBeatConnectionFactory(
- new LDAPConnectionFactory("localhost", TestCaseUtils.getLdapPort()),
- 1000, TimeUnit.MILLISECONDS, request);
-
-
-
- @Override
- protected FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> handler) throws Exception
- {
- return factory.getAsynchronousConnection(handler);
- }
-
-
-
- @Override
- protected Connection getConnection() throws Exception
- {
- return factory.getConnection();
- }
-}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/InternalConnectionFactoryTestCase.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/InternalConnectionFactoryTestCase.java
deleted file mode 100644
index c462aac..0000000
--- a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/InternalConnectionFactoryTestCase.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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 2010 Sun Microsystems, Inc.
- */
-
-package org.opends.sdk;
-
-
-
-/**
- * Tests the internal connection factory.
- */
-public class InternalConnectionFactoryTestCase extends
- ConnectionFactoryTestCase
-{
- private final ConnectionFactory factory = Connections
- .newInternalConnectionFactory(LDAPServer.getInstance(), null);
-
-
-
- @Override
- protected FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> handler) throws Exception
- {
- return factory.getAsynchronousConnection(handler);
- }
-
-
-
- @Override
- protected Connection getConnection() throws Exception
- {
- return factory.getConnection();
- }
-}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LDAPConnectionFactoryTestCase.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LDAPConnectionFactoryTestCase.java
deleted file mode 100644
index 1ff4b85..0000000
--- a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LDAPConnectionFactoryTestCase.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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 2010 Sun Microsystems, Inc.
- */
-
-package org.opends.sdk;
-
-
-
-/**
- * Tests the LDAP connection factory.
- */
-public class LDAPConnectionFactoryTestCase extends ConnectionFactoryTestCase
-{
- private final LDAPConnectionFactory factory = new LDAPConnectionFactory(
- "localhost", TestCaseUtils.getLdapPort());
-
-
-
- @Override
- protected FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> handler) throws Exception
- {
- return factory.getAsynchronousConnection(handler);
- }
-
-
-
- @Override
- protected Connection getConnection() throws Exception
- {
- return factory.getConnection();
- }
-}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LDAPServer.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LDAPServer.java
index 08cf276..c6695cc 100644
--- a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LDAPServer.java
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LDAPServer.java
@@ -29,13 +29,19 @@
+import static com.sun.opends.sdk.ldap.LDAPConstants.TYPE_AUTHENTICATION_SASL;
+
import java.io.IOException;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
+import javax.net.ssl.SSLContext;
+import javax.security.auth.callback.*;
+import javax.security.sasl.*;
+
+import org.opends.sdk.asn1.ASN1;
+import org.opends.sdk.asn1.ASN1Reader;
import org.opends.sdk.controls.Control;
import org.opends.sdk.controls.ControlDecoder;
import org.opends.sdk.requests.*;
@@ -53,7 +59,7 @@
* A simple ldap server that manages 1000 entries and used for running
* testcases. //FIXME: make it MT-safe.
*/
-public class LDAPServer implements ServerConnection<Integer>,
+public class LDAPServer implements
ServerConnectionFactory<LDAPClientContext, Integer>
{
// Creates an abandonable request from the ordinary requests.
@@ -132,6 +138,525 @@
+ private class LDAPServerConnection implements ServerConnection<Integer>
+ {
+
+ private final LDAPClientContext clientContext;
+ private SaslServer saslServer;
+
+
+
+ private LDAPServerConnection(LDAPClientContext clientContext)
+ {
+ this.clientContext = clientContext;
+ }
+
+
+
+ /**
+ * Abandons the request sent by the client.
+ *
+ * @param context
+ * @param request
+ * @throws UnsupportedOperationException
+ */
+ public void handleAbandon(final Integer context,
+ final AbandonRequest request) throws UnsupportedOperationException
+ {
+ // Check if we have any concurrent operation with this message id.
+ final AbandonableRequest req = requestsInProgress.get(context);
+ if (req == null)
+ {
+ // Nothing to do here.
+ return;
+ }
+ // Cancel the request
+ req.cancel();
+ // No response is needed.
+ }
+
+
+
+ /**
+ * Adds the request sent by the client.
+ *
+ * @param context
+ * @param request
+ * @param handler
+ * @param intermediateResponseHandler
+ * @throws UnsupportedOperationException
+ */
+ public void handleAdd(final Integer context, final AddRequest request,
+ final ResultHandler<? super Result> handler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ Result result = null;
+ final AbandonableRequest abReq = new AbandonableRequest(request);
+ requestsInProgress.put(context, abReq);
+ // Get the DN.
+ final DN dn = request.getName();
+ if (entryMap.containsKey(dn))
+ {
+ // duplicate entry.
+ result = Responses.newResult(ResultCode.ENTRY_ALREADY_EXISTS);
+ final ErrorResultException ere = ErrorResultException.wrap(result);
+ handler.handleErrorResult(ere);
+ // doesn't matter if it was canceled.
+ requestsInProgress.remove(context);
+ return;
+ }
+
+ // Create an entry out of this request.
+ final SearchResultEntry entry = Responses.newSearchResultEntry(dn);
+ for (final Control control : request.getControls())
+ {
+ entry.addControl(control);
+ }
+
+ for (final Attribute attr : request.getAllAttributes())
+ {
+ entry.addAttribute(attr);
+ }
+
+ if (abReq.isCanceled())
+ {
+ result = Responses.newResult(ResultCode.CANCELLED);
+ final ErrorResultException ere = ErrorResultException.wrap(result);
+ handler.handleErrorResult(ere);
+ requestsInProgress.remove(context);
+ return;
+ }
+ // Add this to the map.
+ entryMap.put(dn, entry);
+ requestsInProgress.remove(context);
+ result = Responses.newResult(ResultCode.SUCCESS);
+ handler.handleResult(result);
+ }
+
+
+
+ /**
+ * @param context
+ * @param version
+ * @param request
+ * @param resultHandler
+ * @param intermediateResponseHandler
+ * @throws UnsupportedOperationException
+ */
+ public void handleBind(final Integer context, final int version,
+ final BindRequest request,
+ final ResultHandler<? super BindResult> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ // TODO: all bind types.
+ final AbandonableRequest abReq = new AbandonableRequest(request);
+ requestsInProgress.put(context, abReq);
+ if (request.getAuthenticationType() == TYPE_AUTHENTICATION_SASL
+ && request instanceof GenericBindRequest)
+ {
+ ASN1Reader reader = ASN1.getReader(((GenericBindRequest) request)
+ .getAuthenticationValue());
+ try
+ {
+ String saslMech = reader.readOctetStringAsString();
+ ByteString saslCred;
+ if (reader.hasNextElement())
+ {
+ saslCred = reader.readOctetString();
+ }
+ else
+ {
+ saslCred = ByteString.empty();
+ }
+
+ if (saslServer == null
+ || !saslServer.getMechanismName().equalsIgnoreCase(saslMech))
+ {
+ final Map<String, String> props = new HashMap<String, String>();
+ props.put(Sasl.QOP, "auth-conf,auth-int,auth");
+ saslServer = Sasl.createSaslServer(saslMech, "ldap", clientContext
+ .getLocalAddress().getHostName(), props, new CallbackHandler()
+ {
+ public void handle(Callback[] callbacks) throws IOException,
+ UnsupportedCallbackException
+ {
+ for (final Callback callback : callbacks)
+ {
+ if (callback instanceof NameCallback)
+ {
+ // Do nothing
+ }
+ else if (callback instanceof PasswordCallback)
+ {
+ ((PasswordCallback) callback).setPassword("password"
+ .toCharArray());
+ }
+ else if (callback instanceof AuthorizeCallback)
+ {
+ ((AuthorizeCallback) callback).setAuthorized(true);
+ }
+ else if (callback instanceof RealmCallback)
+ {
+ // Do nothing
+ }
+ else
+ {
+ throw new UnsupportedCallbackException(callback);
+
+ }
+ }
+ }
+ });
+ }
+
+ byte[] challenge = saslServer
+ .evaluateResponse(saslCred.toByteArray());
+ if (saslServer.isComplete())
+ {
+ resultHandler.handleResult(Responses.newBindResult(
+ ResultCode.SUCCESS).setServerSASLCredentials(
+ ByteString.wrap(challenge)));
+
+ String qop = (String) saslServer.getNegotiatedProperty(Sasl.QOP);
+ if (qop != null
+ && (qop.equalsIgnoreCase("auth-int") || qop
+ .equalsIgnoreCase("auth-conf")))
+ {
+ ConnectionSecurityLayer csl = new ConnectionSecurityLayer()
+ {
+ public void dispose()
+ {
+ try
+ {
+ saslServer.dispose();
+ }
+ catch (SaslException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+
+
+ public byte[] unwrap(byte[] incoming, int offset, int len)
+ throws ErrorResultException
+ {
+ try
+ {
+ return saslServer.unwrap(incoming, offset, len);
+ }
+ catch (SaslException e)
+ {
+ throw ErrorResultException.wrap(Responses.newResult(
+ ResultCode.OPERATIONS_ERROR).setCause(e));
+ }
+ }
+
+
+
+ public byte[] wrap(byte[] outgoing, int offset, int len)
+ throws ErrorResultException
+ {
+ try
+ {
+ return saslServer.wrap(outgoing, offset, len);
+ }
+ catch (SaslException e)
+ {
+ throw ErrorResultException.wrap(Responses.newResult(
+ ResultCode.OPERATIONS_ERROR).setCause(e));
+ }
+ }
+ };
+
+ clientContext.startSASL(csl);
+ }
+
+ }
+ else
+ {
+ resultHandler.handleResult(Responses.newBindResult(
+ ResultCode.SASL_BIND_IN_PROGRESS).setServerSASLCredentials(
+ ByteString.wrap(challenge)));
+ }
+ }
+ catch (Exception e)
+ {
+ resultHandler.handleErrorResult(ErrorResultException.wrap(Responses
+ .newBindResult(ResultCode.OPERATIONS_ERROR).setCause(e)
+ .setDiagnosticMessage(e.toString())));
+ }
+ }
+ else
+ {
+ resultHandler.handleResult(Responses.newBindResult(ResultCode.SUCCESS));
+ }
+ requestsInProgress.remove(context);
+ }
+
+
+
+ /**
+ * @param context
+ * @param request
+ */
+ public void handleConnectionClosed(final Integer context,
+ final UnbindRequest request)
+ {
+ if (saslServer != null)
+ {
+ try
+ {
+ saslServer.dispose();
+ }
+ catch (SaslException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+
+
+ /**
+ * @param error
+ */
+ public void handleConnectionException(final Throwable error)
+ {
+
+ }
+
+
+
+ /**
+ * @param context
+ * @param request
+ * @param resultHandler
+ * @param intermediateResponseHandler
+ * @throws UnsupportedOperationException
+ */
+ public void handleCompare(final Integer context,
+ final CompareRequest request,
+ final ResultHandler<? super CompareResult> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ CompareResult result = null;
+ final AbandonableRequest abReq = new AbandonableRequest(request);
+ requestsInProgress.put(context, abReq);
+ // Get the DN.
+ final DN dn = request.getName();
+ if (!entryMap.containsKey(dn))
+ {
+ // entry not found.
+ result = Responses.newCompareResult(ResultCode.NO_SUCH_ATTRIBUTE);
+ final ErrorResultException ere = ErrorResultException.wrap(result);
+ resultHandler.handleErrorResult(ere);
+ // doesn't matter if it was canceled.
+ requestsInProgress.remove(context);
+ return;
+ }
+
+ // Get the entry.
+ final Entry entry = entryMap.get(dn);
+ final AttributeDescription attrDesc = request.getAttributeDescription();
+ for (final Attribute attr : entry.getAllAttributes(attrDesc))
+ {
+ final Iterator<ByteString> it = attr.iterator();
+ while (it.hasNext())
+ {
+ final ByteString s = it.next();
+ if (abReq.isCanceled())
+ {
+ final Result r = Responses.newResult(ResultCode.CANCELLED);
+ final ErrorResultException ere = ErrorResultException.wrap(r);
+ resultHandler.handleErrorResult(ere);
+ requestsInProgress.remove(context);
+ return;
+ }
+ if (s.equals(request.getAssertionValue()))
+ {
+ result = Responses.newCompareResult(ResultCode.COMPARE_TRUE);
+ resultHandler.handleResult(result);
+ }
+ }
+ }
+ result = Responses.newCompareResult(ResultCode.COMPARE_FALSE);
+ resultHandler.handleResult(result);
+ requestsInProgress.remove(context);
+ }
+
+
+
+ /**
+ * @param context
+ * @param request
+ * @param handler
+ * @param intermediateResponseHandler
+ * @throws UnsupportedOperationException
+ */
+ public void handleDelete(final Integer context,
+ final DeleteRequest request,
+ final ResultHandler<? super Result> handler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ Result result = null;
+ final AbandonableRequest abReq = new AbandonableRequest(request);
+ requestsInProgress.put(context, abReq);
+ // Get the DN.
+ final DN dn = request.getName();
+ if (!entryMap.containsKey(dn))
+ {
+ // entry is not found.
+ result = Responses.newResult(ResultCode.NO_SUCH_OBJECT);
+ final ErrorResultException ere = ErrorResultException.wrap(result);
+ handler.handleErrorResult(ere);
+ // doesn't matter if it was canceled.
+ requestsInProgress.remove(context);
+ return;
+ }
+
+ if (abReq.isCanceled())
+ {
+ result = Responses.newResult(ResultCode.CANCELLED);
+ final ErrorResultException ere = ErrorResultException.wrap(result);
+ handler.handleErrorResult(ere);
+ requestsInProgress.remove(context);
+ return;
+ }
+ // Remove this from the map.
+ entryMap.remove(dn);
+ requestsInProgress.remove(context);
+ }
+
+
+
+ /**
+ * @param context
+ * @param request
+ * @param resultHandler
+ * @param intermediateResponseHandler
+ * @throws UnsupportedOperationException
+ */
+ public <R extends ExtendedResult> void handleExtendedRequest(
+ final Integer context, final ExtendedRequest<R> request,
+ final ResultHandler<? super R> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ if (request.getOID().equals(StartTLSExtendedRequest.OID))
+ {
+ final R result = request.getResultDecoder().adaptExtendedErrorResult(
+ ResultCode.SUCCESS, "", "");
+ resultHandler.handleResult(result);
+ clientContext.startTLS(sslContext, null, sslContext.getSocketFactory()
+ .getSupportedCipherSuites(), false, false);
+ }
+ }
+
+
+
+ /**
+ * @param context
+ * @param request
+ * @param resultHandler
+ * @param intermediateResponseHandler
+ * @throws UnsupportedOperationException
+ */
+ public void handleModify(final Integer context,
+ final ModifyRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ // TODO:
+ }
+
+
+
+ /**
+ * @param context
+ * @param request
+ * @param resultHandler
+ * @param intermediateResponseHandler
+ * @throws UnsupportedOperationException
+ */
+ public void handleModifyDN(final Integer context,
+ final ModifyDNRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ // TODO
+ }
+
+
+
+ /**
+ * @param context
+ * @param request
+ * @param resultHandler
+ * @param searchResulthandler
+ * @param intermediateResponseHandler
+ * @throws UnsupportedOperationException
+ */
+ public void handleSearch(final Integer context,
+ final SearchRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final SearchResultHandler searchResulthandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ Result result = null;
+ final AbandonableRequest abReq = new AbandonableRequest(request);
+ requestsInProgress.put(context, abReq);
+ // Get the DN.
+ final DN dn = request.getName();
+ if (!entryMap.containsKey(dn))
+ {
+ // Entry not found.
+ result = Responses.newResult(ResultCode.NO_SUCH_OBJECT);
+ final ErrorResultException ere = ErrorResultException.wrap(result);
+ resultHandler.handleErrorResult(ere);
+ // Should searchResultHandler handle anything?
+
+ // doesn't matter if it was canceled.
+ requestsInProgress.remove(context);
+ return;
+ }
+
+ if (abReq.isCanceled())
+ {
+ result = Responses.newResult(ResultCode.CANCELLED);
+ final ErrorResultException ere = ErrorResultException.wrap(result);
+ resultHandler.handleErrorResult(ere);
+ requestsInProgress.remove(context);
+ return;
+ }
+
+ final SearchResultEntry e = Responses
+ .newSearchResultEntry(new LinkedHashMapEntry(entryMap.get(dn)));
+ // Check we have had any controls in the request.
+ for (final Control control : request.getControls())
+ {
+ if (control.getOID().equals(AccountUsabilityRequestControl.OID))
+ {
+ e.addControl(AccountUsabilityResponseControl.newControl(false, false,
+ false, 10, false, 0));
+ }
+ }
+ searchResulthandler.handleEntry(e);
+ result = Responses.newResult(ResultCode.SUCCESS);
+ resultHandler.handleResult(result);
+ requestsInProgress.remove(context);
+ }
+ }
+
+
+
// The mapping between entry DNs and the corresponding entries.
private final ConcurrentHashMap<DN, Entry> entryMap = new ConcurrentHashMap<DN, Entry>();
@@ -152,6 +677,8 @@
// The Set used for locking dns.
private final HashSet<DN> lockedDNs = new HashSet<DN>();
+ private SSLContext sslContext;
+
private LDAPServer()
@@ -177,258 +704,12 @@
/**
- * Abandons the request sent by the client.
- *
- * @param context
- * @param request
- * @throws UnsupportedOperationException
- */
- public void abandon(final Integer context, final AbandonRequest request)
- throws UnsupportedOperationException
- {
- // Check if we have any concurrent operation with this message id.
- final AbandonableRequest req = requestsInProgress.get(context);
- if (req == null)
- {
- // Nothing to do here.
- return;
- }
- // Cancel the request
- req.cancel();
- // No response is needed.
- }
-
-
-
- /**
* @param context
* @return
*/
public ServerConnection<Integer> accept(final LDAPClientContext context)
{
- return this;
- }
-
-
-
- /**
- * Adds the request sent by the client.
- *
- * @param context
- * @param request
- * @param handler
- * @param intermediateResponseHandler
- * @throws UnsupportedOperationException
- */
- public void add(final Integer context, final AddRequest request,
- final ResultHandler<Result> handler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- Result result = null;
- final AbandonableRequest abReq = new AbandonableRequest(request);
- requestsInProgress.put(context, abReq);
- // Get the DN.
- final DN dn = request.getName();
- if (entryMap.containsKey(dn))
- {
- // duplicate entry.
- result = Responses.newResult(ResultCode.ENTRY_ALREADY_EXISTS);
- final ErrorResultException ere = ErrorResultException.wrap(result);
- handler.handleErrorResult(ere);
- // doesn't matter if it was canceled.
- requestsInProgress.remove(context);
- return;
- }
-
- // Create an entry out of this request.
- final SearchResultEntry entry = Responses.newSearchResultEntry(dn);
- for (final Control control : request.getControls())
- {
- entry.addControl(control);
- }
-
- for (final Attribute attr : request.getAllAttributes())
- {
- entry.addAttribute(attr);
- }
-
- if (abReq.isCanceled())
- {
- result = Responses.newResult(ResultCode.CANCELLED);
- final ErrorResultException ere = ErrorResultException.wrap(result);
- handler.handleErrorResult(ere);
- requestsInProgress.remove(context);
- return;
- }
- // Add this to the map.
- entryMap.put(dn, entry);
- requestsInProgress.remove(context);
- result = Responses.newResult(ResultCode.SUCCESS);
- handler.handleResult(result);
- }
-
-
-
- /**
- * @param context
- * @param version
- * @param request
- * @param resultHandler
- * @param intermediateResponseHandler
- * @throws UnsupportedOperationException
- */
- public void bind(final Integer context, final int version,
- final BindRequest request,
- final ResultHandler<? super BindResult> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- // TODO: all bind types.
- final AbandonableRequest abReq = new AbandonableRequest(request);
- requestsInProgress.put(context, abReq);
- resultHandler.handleResult(Responses.newBindResult(ResultCode.SUCCESS));
- requestsInProgress.remove(context);
- }
-
-
-
- /**
- * @param context
- * @param request
- */
- public void closed(final Integer context, final UnbindRequest request)
- {
-
- }
-
-
-
- /**
- * @param error
- */
- public void closed(final Throwable error)
- {
-
- }
-
-
-
- /**
- * @param context
- * @param request
- * @param resultHandler
- * @param intermediateResponseHandler
- * @throws UnsupportedOperationException
- */
- public void compare(final Integer context, final CompareRequest request,
- final ResultHandler<? super CompareResult> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- CompareResult result = null;
- final AbandonableRequest abReq = new AbandonableRequest(request);
- requestsInProgress.put(context, abReq);
- // Get the DN.
- final DN dn = request.getName();
- if (!entryMap.containsKey(dn))
- {
- // entry not found.
- result = Responses.newCompareResult(ResultCode.NO_SUCH_ATTRIBUTE);
- final ErrorResultException ere = ErrorResultException.wrap(result);
- resultHandler.handleErrorResult(ere);
- // doesn't matter if it was canceled.
- requestsInProgress.remove(context);
- return;
- }
-
- // Get the entry.
- final Entry entry = entryMap.get(dn);
- final AttributeDescription attrDesc = request.getAttributeDescription();
- for (final Attribute attr : entry.getAllAttributes(attrDesc))
- {
- final Iterator<ByteString> it = attr.iterator();
- while (it.hasNext())
- {
- final ByteString s = it.next();
- if (abReq.isCanceled())
- {
- final Result r = Responses.newResult(ResultCode.CANCELLED);
- final ErrorResultException ere = ErrorResultException.wrap(r);
- resultHandler.handleErrorResult(ere);
- requestsInProgress.remove(context);
- return;
- }
- if (s.equals(request.getAssertionValue()))
- {
- result = Responses.newCompareResult(ResultCode.COMPARE_TRUE);
- resultHandler.handleResult(result);
- }
- }
- }
- result = Responses.newCompareResult(ResultCode.COMPARE_FALSE);
- resultHandler.handleResult(result);
- requestsInProgress.remove(context);
- }
-
-
-
- /**
- * @param context
- * @param request
- * @param handler
- * @param intermediateResponseHandler
- * @throws UnsupportedOperationException
- */
- public void delete(final Integer context, final DeleteRequest request,
- final ResultHandler<Result> handler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- Result result = null;
- final AbandonableRequest abReq = new AbandonableRequest(request);
- requestsInProgress.put(context, abReq);
- // Get the DN.
- final DN dn = request.getName();
- if (!entryMap.containsKey(dn))
- {
- // entry is not found.
- result = Responses.newResult(ResultCode.NO_SUCH_OBJECT);
- final ErrorResultException ere = ErrorResultException.wrap(result);
- handler.handleErrorResult(ere);
- // doesn't matter if it was canceled.
- requestsInProgress.remove(context);
- return;
- }
-
- if (abReq.isCanceled())
- {
- result = Responses.newResult(ResultCode.CANCELLED);
- final ErrorResultException ere = ErrorResultException.wrap(result);
- handler.handleErrorResult(ere);
- requestsInProgress.remove(context);
- return;
- }
- // Remove this from the map.
- entryMap.remove(dn);
- requestsInProgress.remove(context);
- }
-
-
-
- /**
- * @param context
- * @param request
- * @param resultHandler
- * @param intermediateResponseHandler
- * @throws UnsupportedOperationException
- */
- public <R extends ExtendedResult> void extendedRequest(final Integer context,
- final ExtendedRequest<R> request, final ResultHandler<R> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- // TODO:
+ return new LDAPServerConnection(context);
}
@@ -446,113 +727,21 @@
/**
- * @param context
- * @param request
- * @param resultHandler
- * @param intermediateResponseHandler
- * @throws UnsupportedOperationException
- */
- public void modify(final Integer context, final ModifyRequest request,
- final ResultHandler<Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- // TODO:
- }
-
-
-
- /**
- * @param context
- * @param request
- * @param resultHandler
- * @param intermediateResponseHandler
- * @throws UnsupportedOperationException
- */
- public void modifyDN(final Integer context, final ModifyDNRequest request,
- final ResultHandler<Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- // TODO
- }
-
-
-
- /**
- * @param context
- * @param request
- * @param resultHandler
- * @param searchResulthandler
- * @param intermediateResponseHandler
- * @throws UnsupportedOperationException
- */
- public void search(final Integer context, final SearchRequest request,
- final ResultHandler<Result> resultHandler,
- final SearchResultHandler searchResulthandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- Result result = null;
- final AbandonableRequest abReq = new AbandonableRequest(request);
- requestsInProgress.put(context, abReq);
- // Get the DN.
- final DN dn = request.getName();
- if (!entryMap.containsKey(dn))
- {
- // Entry not found.
- result = Responses.newResult(ResultCode.NO_SUCH_OBJECT);
- final ErrorResultException ere = ErrorResultException.wrap(result);
- resultHandler.handleErrorResult(ere);
- // Should searchResultHandler handle anything?
-
- // doesn't matter if it was canceled.
- requestsInProgress.remove(context);
- return;
- }
-
- if (abReq.isCanceled())
- {
- result = Responses.newResult(ResultCode.CANCELLED);
- final ErrorResultException ere = ErrorResultException.wrap(result);
- resultHandler.handleErrorResult(ere);
- requestsInProgress.remove(context);
- return;
- }
-
- final SearchResultEntry e = Responses.newSearchResultEntry(
- new LinkedHashMapEntry(entryMap.get(dn)));
- // Check we have had any controls in the request.
- for (final Control control : request.getControls())
- {
- if (control.getOID().equals(AccountUsabilityRequestControl.OID))
- {
- e.addControl(AccountUsabilityResponseControl.newControl(false, false,
- false, 10, false, 0));
- }
- }
- searchResulthandler.handleEntry(e);
- result = Responses.newResult(ResultCode.SUCCESS);
- resultHandler.handleResult(result);
- requestsInProgress.remove(context);
- }
-
-
-
- /**
* Starts the server.
*
* @param port
* @exception IOException
*/
- public synchronized void start(final int port) throws IOException
+ public synchronized void start(final int port) throws Exception
{
if (isRunning)
{
return;
}
+ sslContext = new SSLContextBuilder().getSSLContext();
+
transport.setSelectorRunnersCount(2);
- listener = new LDAPListener(port, new LDAPServer(),
+ listener = new LDAPListener(port, getInstance(),
new GrizzlyLDAPListenerOptions().setTCPNIOTransport(transport)
.setBacklog(4096));
transport.start();
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/SynchronousConnectionTestCase.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/SynchronousConnectionTestCase.java
index aa38494..8e2e26f 100644
--- a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/SynchronousConnectionTestCase.java
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/SynchronousConnectionTestCase.java
@@ -29,17 +29,17 @@
-import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.util.List;
+import org.opends.sdk.ldif.EntryReader;
import org.opends.sdk.requests.Requests;
import org.opends.sdk.responses.BindResult;
import org.opends.sdk.responses.CompareResult;
import org.opends.sdk.responses.Result;
-import org.opends.sdk.responses.SearchResultEntry;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -155,10 +155,11 @@
public void testSearchRequest() throws Exception
{
final SynchronousConnection con = new SynchronousConnection(asyncCon);
- final List<SearchResultEntry> entries = con.search(
+ final EntryReader reader = con.search(
"uid=user.0,ou=people,o=test", SearchScope.BASE_OBJECT,
"objectclass=*", "cn");
- assertEquals(entries.size(), 1);
+ reader.readEntry();
+ assertNull(reader.readEntry());
}
// TODO: add more tests.
}
--
Gitblit v1.10.0