From cc5a87f6db56c4dc534636abb5a35efc1d15dee7 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 02 Jun 2011 01:01:18 +0000
Subject: [PATCH] Fix OPENDJ-183: Add support for RequestContext and RequestHandlers
---
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnection.java | 26
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java | 28
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java | 20
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryReader.java | 5
opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java | 7
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/CRAMMD5SASLBindRequestImpl.java | 7
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/resources/org/forgerock/opendj/ldap/core.properties | 16
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactoryAdapter.java | 983 ++++++++++++++++
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/PlainSASLBindRequestImpl.java | 6
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestContext.java | 118 +
opendj-sdk/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/server/Main.java | 864 ++++++-------
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/DigestMD5SASLBindRequestImpl.java | 22
opendj-sdk/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java | 22
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/AbstractLDAPFutureResultImpl.java | 2
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/AsynchronousFutureResult.java | 8
opendj-sdk/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/proxy/Main.java | 993 +++++++--------
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/ExternalSASLBindRequestImpl.java | 7
opendj-sdk/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java | 2
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/GSSAPISASLBindRequestImpl.java | 37
opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPPasswordModify.java | 8
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/CancelRequestListener.java | 64 +
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java | 9
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java | 25
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactory.java | 61 +
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ErrorResultException.java | 84 +
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java | 77 +
opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPModify.java | 23
opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPSearch.java | 7
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java | 14
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/responses/AbstractExtendedResultDecoder.java | 8
30 files changed, 2,378 insertions(+), 1,175 deletions(-)
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/proxy/Main.java b/opendj-sdk/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/proxy/Main.java
index dd99485..2d35f6f 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/proxy/Main.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/proxy/Main.java
@@ -62,540 +62,15 @@
*/
public final class Main
{
- /**
- * Proxy server connection factory implementation.
- */
- private static final class Proxy implements
- ServerConnectionFactory<LDAPClientContext, Integer>
+ private static final class ProxyBackend implements
+ RequestHandler<RequestContext>
{
- private final class ServerConnectionImpl implements
- ServerConnection<Integer>
- {
-
- private abstract class AbstractRequestCompletionHandler<R extends Result,
- H extends ResultHandler<? super R>>
- implements ResultHandler<R>
- {
- final H resultHandler;
- final AsynchronousConnection connection;
-
-
-
- AbstractRequestCompletionHandler(
- final AsynchronousConnection connection,
- final H resultHandler)
- {
- this.connection = connection;
- this.resultHandler = resultHandler;
- }
-
-
-
- @Override
- public final void handleErrorResult(
- final ErrorResultException error)
- {
- connection.close();
- resultHandler.handleErrorResult(error);
- }
-
-
-
- @Override
- public final void handleResult(final R result)
- {
- connection.close();
- resultHandler.handleResult(result);
- }
-
- }
-
-
-
- private abstract class ConnectionCompletionHandler<R extends Result>
- implements ResultHandler<AsynchronousConnection>
- {
- private final ResultHandler<? super R> resultHandler;
-
-
-
- ConnectionCompletionHandler(
- final ResultHandler<? super R> resultHandler)
- {
- this.resultHandler = resultHandler;
- }
-
-
-
- @Override
- public final void handleErrorResult(
- final ErrorResultException error)
- {
- resultHandler.handleErrorResult(error);
- }
-
-
-
- @Override
- public abstract void handleResult(
- AsynchronousConnection connection);
-
- }
-
-
-
- private final class RequestCompletionHandler<R extends Result>
- extends
- AbstractRequestCompletionHandler<R, ResultHandler<? super R>>
- {
- RequestCompletionHandler(
- final AsynchronousConnection connection,
- final ResultHandler<? super R> resultHandler)
- {
- super(connection, resultHandler);
- }
- }
-
-
-
- private final class SearchRequestCompletionHandler
- extends
- AbstractRequestCompletionHandler<Result, SearchResultHandler>
- implements SearchResultHandler
- {
-
- SearchRequestCompletionHandler(
- final AsynchronousConnection connection,
- final SearchResultHandler resultHandler)
- {
- super(connection, resultHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public final boolean handleEntry(final SearchResultEntry entry)
- {
- return resultHandler.handleEntry(entry);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public final boolean handleReference(
- final SearchResultReference reference)
- {
- return resultHandler.handleReference(reference);
- }
-
- }
-
-
-
- private volatile ProxiedAuthV2RequestControl proxiedAuthControl = null;
-
-
-
- private ServerConnectionImpl(
- final LDAPClientContext clientContext)
- {
- // Nothing to do.
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleAbandon(final Integer requestContext,
- final AbandonRequest request)
- throws UnsupportedOperationException
- {
- // Not implemented.
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleAdd(
- final Integer requestContext,
- final AddRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- addProxiedAuthControl(request);
- final ConnectionCompletionHandler<Result> outerHandler =
- new ConnectionCompletionHandler<Result>(resultHandler)
- {
-
- @Override
- public void handleResult(
- final AsynchronousConnection connection)
- {
- final RequestCompletionHandler<Result> innerHandler =
- new RequestCompletionHandler<Result>(connection, resultHandler);
- connection.add(request, innerHandler,
- intermediateResponseHandler);
- }
-
- };
-
- factory.getAsynchronousConnection(outerHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleBind(
- final Integer requestContext,
- final int version,
- final BindRequest request,
- final ResultHandler<? super BindResult> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
-
- if (request.getAuthenticationType() != ((byte) 0x80))
- {
- // TODO: SASL authentication not implemented.
- resultHandler.handleErrorResult(newErrorResult(
- ResultCode.PROTOCOL_ERROR,
- "non-SIMPLE authentication not supported: "
- + request.getAuthenticationType()));
- }
- else
- {
- // Authenticate using a separate bind connection pool, because we
- // don't want to change the state of the pooled connection.
- final ConnectionCompletionHandler<BindResult> outerHandler =
- new ConnectionCompletionHandler<BindResult>(resultHandler)
- {
-
- @Override
- public void handleResult(
- final AsynchronousConnection connection)
- {
- final ResultHandler<BindResult> innerHandler =
- new ResultHandler<BindResult>()
- {
-
- @Override
- public final void handleErrorResult(
- final ErrorResultException error)
- {
- connection.close();
- resultHandler.handleErrorResult(error);
- }
-
-
-
- @Override
- public final void handleResult(final BindResult result)
- {
- connection.close();
- proxiedAuthControl = ProxiedAuthV2RequestControl
- .newControl("dn:" + request.getName());
- resultHandler.handleResult(result);
- }
- };
- connection.bind(request, innerHandler,
- intermediateResponseHandler);
- }
-
- };
-
- proxiedAuthControl = null;
- bindFactory.getAsynchronousConnection(outerHandler);
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleCompare(
- final Integer requestContext,
- final CompareRequest request,
- final ResultHandler<? super CompareResult> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- addProxiedAuthControl(request);
- final ConnectionCompletionHandler<CompareResult> outerHandler =
- new ConnectionCompletionHandler<CompareResult>(resultHandler)
- {
-
- @Override
- public void handleResult(
- final AsynchronousConnection connection)
- {
- final RequestCompletionHandler<CompareResult> innerHandler =
- new RequestCompletionHandler<CompareResult>(connection, resultHandler);
- connection.compare(request, innerHandler,
- intermediateResponseHandler);
- }
-
- };
-
- factory.getAsynchronousConnection(outerHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleConnectionClosed(
- final Integer requestContext, final UnbindRequest request)
- {
- // Client connection closed.
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleConnectionDisconnected(
- final ResultCode resultCode, final String message)
- {
- // Client disconnected by server.
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleConnectionError(final Throwable error)
- {
- // Client connection failed.
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleDelete(
- final Integer requestContext,
- final DeleteRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- addProxiedAuthControl(request);
- final ConnectionCompletionHandler<Result> outerHandler =
- new ConnectionCompletionHandler<Result>(resultHandler)
- {
-
- @Override
- public void handleResult(
- final AsynchronousConnection connection)
- {
- final RequestCompletionHandler<Result> innerHandler =
- new RequestCompletionHandler<Result>(connection, resultHandler);
- connection.delete(request, innerHandler,
- intermediateResponseHandler);
- }
-
- };
-
- factory.getAsynchronousConnection(outerHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public <R extends ExtendedResult> void handleExtendedRequest(
- final Integer requestContext,
- final ExtendedRequest<R> request,
- final ResultHandler<? super R> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- if (request.getOID().equals(CancelExtendedRequest.OID))
- {
- // TODO: not implemented.
- resultHandler.handleErrorResult(newErrorResult(
- ResultCode.PROTOCOL_ERROR,
- "Cancel extended request operation not supported"));
- }
- else if (request.getOID().equals(StartTLSExtendedRequest.OID))
- {
- // TODO: not implemented.
- resultHandler.handleErrorResult(newErrorResult(
- ResultCode.PROTOCOL_ERROR,
- "StartTLS extended request operation not supported"));
- }
- else
- {
- // Forward all other extended operations.
- addProxiedAuthControl(request);
-
- final ConnectionCompletionHandler<R> outerHandler =
- new ConnectionCompletionHandler<R>(resultHandler)
- {
-
- @Override
- public void handleResult(
- final AsynchronousConnection connection)
- {
- final RequestCompletionHandler<R> innerHandler =
- new RequestCompletionHandler<R>(connection, resultHandler);
- connection.extendedRequest(request, innerHandler,
- intermediateResponseHandler);
- }
-
- };
-
- factory.getAsynchronousConnection(outerHandler);
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleModify(
- final Integer requestContext,
- final ModifyRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- addProxiedAuthControl(request);
- final ConnectionCompletionHandler<Result> outerHandler =
- new ConnectionCompletionHandler<Result>(resultHandler)
- {
-
- @Override
- public void handleResult(
- final AsynchronousConnection connection)
- {
- final RequestCompletionHandler<Result> innerHandler =
- new RequestCompletionHandler<Result>(connection, resultHandler);
- connection.modify(request, innerHandler,
- intermediateResponseHandler);
- }
-
- };
-
- factory.getAsynchronousConnection(outerHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleModifyDN(
- final Integer requestContext,
- final ModifyDNRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- addProxiedAuthControl(request);
- final ConnectionCompletionHandler<Result> outerHandler =
- new ConnectionCompletionHandler<Result>(resultHandler)
- {
-
- @Override
- public void handleResult(
- final AsynchronousConnection connection)
- {
- final RequestCompletionHandler<Result> innerHandler =
- new RequestCompletionHandler<Result>(connection, resultHandler);
- connection.modifyDN(request, innerHandler,
- intermediateResponseHandler);
- }
-
- };
-
- factory.getAsynchronousConnection(outerHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleSearch(
- final Integer requestContext,
- final SearchRequest request,
- final SearchResultHandler resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- addProxiedAuthControl(request);
- final ConnectionCompletionHandler<Result> outerHandler =
- new ConnectionCompletionHandler<Result>(resultHandler)
- {
-
- @Override
- public void handleResult(
- final AsynchronousConnection connection)
- {
- final SearchRequestCompletionHandler innerHandler =
- new SearchRequestCompletionHandler(connection, resultHandler);
- connection.search(request, innerHandler,
- intermediateResponseHandler);
- }
-
- };
-
- factory.getAsynchronousConnection(outerHandler);
- }
-
-
-
- private void addProxiedAuthControl(final Request request)
- {
- final ProxiedAuthV2RequestControl control = proxiedAuthControl;
- if (control != null)
- {
- request.addControl(control);
- }
- }
-
- }
-
-
-
private final ConnectionFactory factory;
private final ConnectionFactory bindFactory;
- private Proxy(final ConnectionFactory factory,
+ private ProxyBackend(final ConnectionFactory factory,
final ConnectionFactory bindFactory)
{
this.factory = factory;
@@ -604,15 +79,452 @@
+ private abstract class AbstractRequestCompletionHandler
+ <R extends Result, H extends ResultHandler<? super R>>
+ implements ResultHandler<R>
+ {
+ final H resultHandler;
+ final AsynchronousConnection connection;
+
+
+
+ AbstractRequestCompletionHandler(
+ final AsynchronousConnection connection,
+ final H resultHandler)
+ {
+ this.connection = connection;
+ this.resultHandler = resultHandler;
+ }
+
+
+
+ @Override
+ public final void handleErrorResult(
+ final ErrorResultException error)
+ {
+ connection.close();
+ resultHandler.handleErrorResult(error);
+ }
+
+
+
+ @Override
+ public final void handleResult(final R result)
+ {
+ connection.close();
+ resultHandler.handleResult(result);
+ }
+
+ }
+
+
+
+ private abstract class ConnectionCompletionHandler<R extends Result>
+ implements ResultHandler<AsynchronousConnection>
+ {
+ private final ResultHandler<? super R> resultHandler;
+
+
+
+ ConnectionCompletionHandler(
+ final ResultHandler<? super R> resultHandler)
+ {
+ this.resultHandler = resultHandler;
+ }
+
+
+
+ @Override
+ public final void handleErrorResult(
+ final ErrorResultException error)
+ {
+ resultHandler.handleErrorResult(error);
+ }
+
+
+
+ @Override
+ public abstract void handleResult(
+ AsynchronousConnection connection);
+
+ }
+
+
+
+ private final class RequestCompletionHandler<R extends Result>
+ extends
+ AbstractRequestCompletionHandler<R, ResultHandler<? super R>>
+ {
+ RequestCompletionHandler(
+ final AsynchronousConnection connection,
+ final ResultHandler<? super R> resultHandler)
+ {
+ super(connection, resultHandler);
+ }
+ }
+
+
+
+ private final class SearchRequestCompletionHandler extends
+ AbstractRequestCompletionHandler<Result, SearchResultHandler>
+ implements SearchResultHandler
+ {
+
+ SearchRequestCompletionHandler(
+ final AsynchronousConnection connection,
+ final SearchResultHandler resultHandler)
+ {
+ super(connection, resultHandler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final boolean handleEntry(final SearchResultEntry entry)
+ {
+ return resultHandler.handleEntry(entry);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final boolean handleReference(
+ final SearchResultReference reference)
+ {
+ return resultHandler.handleReference(reference);
+ }
+
+ }
+
+
+
+ private volatile ProxiedAuthV2RequestControl proxiedAuthControl = null;
+
+
+
/**
* {@inheritDoc}
*/
@Override
- public ServerConnection<Integer> handleAccept(
- final LDAPClientContext clientContext)
- throws ErrorResultException
+ public void handleAdd(final RequestContext requestContext,
+ final AddRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
{
- return new ServerConnectionImpl(clientContext);
+ addProxiedAuthControl(request);
+ final ConnectionCompletionHandler<Result> outerHandler =
+ new ConnectionCompletionHandler<Result>(resultHandler)
+ {
+
+ @Override
+ public void handleResult(
+ final AsynchronousConnection connection)
+ {
+ final RequestCompletionHandler<Result> innerHandler =
+ new RequestCompletionHandler<Result>(connection, resultHandler);
+ connection.add(request, innerHandler,
+ intermediateResponseHandler);
+ }
+
+ };
+
+ factory.getAsynchronousConnection(outerHandler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleBind(final RequestContext requestContext,
+ final int version, final BindRequest request,
+ final ResultHandler<? super BindResult> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+
+ if (request.getAuthenticationType() != ((byte) 0x80))
+ {
+ // TODO: SASL authentication not implemented.
+ resultHandler.handleErrorResult(newErrorResult(
+ ResultCode.PROTOCOL_ERROR,
+ "non-SIMPLE authentication not supported: "
+ + request.getAuthenticationType()));
+ }
+ else
+ {
+ // Authenticate using a separate bind connection pool, because we
+ // don't want to change the state of the pooled connection.
+ final ConnectionCompletionHandler<BindResult> outerHandler =
+ new ConnectionCompletionHandler<BindResult>(resultHandler)
+ {
+
+ @Override
+ public void handleResult(
+ final AsynchronousConnection connection)
+ {
+ final ResultHandler<BindResult> innerHandler = new ResultHandler<BindResult>()
+ {
+
+ @Override
+ public final void handleErrorResult(
+ final ErrorResultException error)
+ {
+ connection.close();
+ resultHandler.handleErrorResult(error);
+ }
+
+
+
+ @Override
+ public final void handleResult(final BindResult result)
+ {
+ connection.close();
+ proxiedAuthControl = ProxiedAuthV2RequestControl
+ .newControl("dn:" + request.getName());
+ resultHandler.handleResult(result);
+ }
+ };
+ connection.bind(request, innerHandler,
+ intermediateResponseHandler);
+ }
+
+ };
+
+ proxiedAuthControl = null;
+ bindFactory.getAsynchronousConnection(outerHandler);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleCompare(final RequestContext requestContext,
+ final CompareRequest request,
+ final ResultHandler<? super CompareResult> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ addProxiedAuthControl(request);
+ final ConnectionCompletionHandler<CompareResult> outerHandler =
+ new ConnectionCompletionHandler<CompareResult>(resultHandler)
+ {
+
+ @Override
+ public void handleResult(
+ final AsynchronousConnection connection)
+ {
+ final RequestCompletionHandler<CompareResult> innerHandler =
+ new RequestCompletionHandler<CompareResult>(connection, resultHandler);
+ connection.compare(request, innerHandler,
+ intermediateResponseHandler);
+ }
+
+ };
+
+ factory.getAsynchronousConnection(outerHandler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleDelete(final RequestContext requestContext,
+ final DeleteRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ addProxiedAuthControl(request);
+ final ConnectionCompletionHandler<Result> outerHandler =
+ new ConnectionCompletionHandler<Result>(resultHandler)
+ {
+
+ @Override
+ public void handleResult(
+ final AsynchronousConnection connection)
+ {
+ final RequestCompletionHandler<Result> innerHandler =
+ new RequestCompletionHandler<Result>(connection, resultHandler);
+ connection.delete(request, innerHandler,
+ intermediateResponseHandler);
+ }
+
+ };
+
+ factory.getAsynchronousConnection(outerHandler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <R extends ExtendedResult> void handleExtendedRequest(
+ final RequestContext requestContext,
+ final ExtendedRequest<R> request,
+ final ResultHandler<? super R> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ if (request.getOID().equals(CancelExtendedRequest.OID))
+ {
+ // TODO: not implemented.
+ resultHandler.handleErrorResult(newErrorResult(
+ ResultCode.PROTOCOL_ERROR,
+ "Cancel extended request operation not supported"));
+ }
+ else if (request.getOID().equals(StartTLSExtendedRequest.OID))
+ {
+ // TODO: not implemented.
+ resultHandler.handleErrorResult(newErrorResult(
+ ResultCode.PROTOCOL_ERROR,
+ "StartTLS extended request operation not supported"));
+ }
+ else
+ {
+ // Forward all other extended operations.
+ addProxiedAuthControl(request);
+
+ final ConnectionCompletionHandler<R> outerHandler =
+ new ConnectionCompletionHandler<R>(resultHandler)
+ {
+
+ @Override
+ public void handleResult(
+ final AsynchronousConnection connection)
+ {
+ final RequestCompletionHandler<R> innerHandler =
+ new RequestCompletionHandler<R>(connection, resultHandler);
+ connection.extendedRequest(request, innerHandler,
+ intermediateResponseHandler);
+ }
+
+ };
+
+ factory.getAsynchronousConnection(outerHandler);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleModify(final RequestContext requestContext,
+ final ModifyRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ addProxiedAuthControl(request);
+ final ConnectionCompletionHandler<Result> outerHandler =
+ new ConnectionCompletionHandler<Result>(resultHandler)
+ {
+
+ @Override
+ public void handleResult(
+ final AsynchronousConnection connection)
+ {
+ final RequestCompletionHandler<Result> innerHandler =
+ new RequestCompletionHandler<Result>(connection, resultHandler);
+ connection.modify(request, innerHandler,
+ intermediateResponseHandler);
+ }
+
+ };
+
+ factory.getAsynchronousConnection(outerHandler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleModifyDN(final RequestContext requestContext,
+ final ModifyDNRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ addProxiedAuthControl(request);
+ final ConnectionCompletionHandler<Result> outerHandler =
+ new ConnectionCompletionHandler<Result>(resultHandler)
+ {
+
+ @Override
+ public void handleResult(
+ final AsynchronousConnection connection)
+ {
+ final RequestCompletionHandler<Result> innerHandler =
+ new RequestCompletionHandler<Result>(connection, resultHandler);
+ connection.modifyDN(request, innerHandler,
+ intermediateResponseHandler);
+ }
+
+ };
+
+ factory.getAsynchronousConnection(outerHandler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleSearch(final RequestContext requestContext,
+ final SearchRequest request,
+ final SearchResultHandler resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ addProxiedAuthControl(request);
+ final ConnectionCompletionHandler<Result> outerHandler =
+ new ConnectionCompletionHandler<Result>(resultHandler)
+ {
+
+ @Override
+ public void handleResult(
+ final AsynchronousConnection connection)
+ {
+ final SearchRequestCompletionHandler innerHandler =
+ new SearchRequestCompletionHandler(connection, resultHandler);
+ connection.search(request, innerHandler,
+ intermediateResponseHandler);
+ }
+
+ };
+
+ factory.getAsynchronousConnection(outerHandler);
+ }
+
+
+
+ private void addProxiedAuthControl(final Request request)
+ {
+ final ProxiedAuthV2RequestControl control = proxiedAuthControl;
+ if (control != null)
+ {
+ request.addControl(control);
+ }
}
}
@@ -654,23 +566,28 @@
new LDAPConnectionFactory(remoteAddress, remotePort),
Integer.MAX_VALUE));
}
- final RoundRobinLoadBalancingAlgorithm algorithm =
- new RoundRobinLoadBalancingAlgorithm(factories);
- final RoundRobinLoadBalancingAlgorithm bindAlgorithm =
- new RoundRobinLoadBalancingAlgorithm(bindFactories);
+ final RoundRobinLoadBalancingAlgorithm algorithm = new RoundRobinLoadBalancingAlgorithm(
+ factories);
+ final RoundRobinLoadBalancingAlgorithm bindAlgorithm = new RoundRobinLoadBalancingAlgorithm(
+ bindFactories);
final ConnectionFactory factory = Connections
.newLoadBalancer(algorithm);
final ConnectionFactory bindFactory = Connections
.newLoadBalancer(bindAlgorithm);
+ // Create a server connection adapter.
+ final ProxyBackend backend = new ProxyBackend(factory, bindFactory);
+ final ServerConnectionFactory<LDAPClientContext, Integer> connectionHandler =
+ Connections.newServerConnectionFactory(backend);
+
// Create listener.
final LDAPListenerOptions options = new LDAPListenerOptions()
.setBacklog(4096);
LDAPListener listener = null;
try
{
- listener = new LDAPListener(localAddress, localPort, new Proxy(
- factory, bindFactory), options);
+ listener = new LDAPListener(localAddress, localPort,
+ connectionHandler, options);
System.out.println("Press any key to stop the server...");
System.in.read();
}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/server/Main.java b/opendj-sdk/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/server/Main.java
index a00a1a8..98368d2 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/server/Main.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/server/Main.java
@@ -64,442 +64,17 @@
*/
public final class Main
{
- /**
- * Proxy server connection factory implementation.
- */
- private static final class Store implements
- ServerConnectionFactory<LDAPClientContext, Integer>
+ private static final class MemoryBackend implements
+ RequestHandler<RequestContext>
{
- private final class ServerConnectionImpl implements
- ServerConnection<Integer>
- {
-
- private ServerConnectionImpl(
- final LDAPClientContext clientContext)
- {
- // Nothing to do.
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleAbandon(final Integer requestContext,
- final AbandonRequest request)
- throws UnsupportedOperationException
- {
- // Not implemented.
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleAdd(
- final Integer requestContext,
- final AddRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- // TODO: controls.
- entryLock.writeLock().lock();
- try
- {
- DN dn = request.getName();
- if (entries.containsKey(dn))
- {
- resultHandler
- .handleErrorResult(ErrorResultException
- .newErrorResult(ResultCode.ENTRY_ALREADY_EXISTS,
- "The entry " + dn.toString()
- + " already exists"));
- }
-
- DN parent = dn.parent();
- if (!entries.containsKey(parent))
- {
- resultHandler.handleErrorResult(ErrorResultException
- .newErrorResult(ResultCode.NO_SUCH_OBJECT,
- "The parent entry " + parent.toString()
- + " does not exist"));
- }
- else
- {
- entries.put(dn, request);
- resultHandler.handleResult(Responses
- .newResult(ResultCode.SUCCESS));
- }
- }
- finally
- {
- entryLock.writeLock().unlock();
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleBind(
- final Integer requestContext,
- final int version,
- final BindRequest request,
- final ResultHandler<? super BindResult> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- if (request.getAuthenticationType() != ((byte) 0x80))
- {
- // TODO: SASL authentication not implemented.
- resultHandler.handleErrorResult(newErrorResult(
- ResultCode.PROTOCOL_ERROR,
- "non-SIMPLE authentication not supported: "
- + request.getAuthenticationType()));
- }
- else
- {
- // TODO: always succeed.
- resultHandler.handleResult(Responses
- .newBindResult(ResultCode.SUCCESS));
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleCompare(
- final Integer requestContext,
- final CompareRequest request,
- final ResultHandler<? super CompareResult> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- // TODO:
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleConnectionClosed(
- final Integer requestContext, final UnbindRequest request)
- {
- // Nothing to do.
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleConnectionDisconnected(
- final ResultCode resultCode, final String message)
- {
- // Nothing to do.
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleConnectionError(final Throwable error)
- {
- // Nothing to do.
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleDelete(
- final Integer requestContext,
- final DeleteRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- // TODO: controls.
- entryLock.writeLock().lock();
- try
- {
- // TODO: check for children.
- DN dn = request.getName();
- if (!entries.containsKey(dn))
- {
- resultHandler
- .handleErrorResult(ErrorResultException
- .newErrorResult(ResultCode.NO_SUCH_OBJECT,
- "The entry " + dn.toString()
- + " does not exist"));
- }
- else
- {
- entries.remove(dn);
- resultHandler.handleResult(Responses
- .newResult(ResultCode.SUCCESS));
- }
- }
- finally
- {
- entryLock.writeLock().unlock();
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public <R extends ExtendedResult> void handleExtendedRequest(
- final Integer requestContext,
- final ExtendedRequest<R> request,
- final ResultHandler<? super R> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- // TODO: not implemented.
- resultHandler.handleErrorResult(newErrorResult(
- ResultCode.PROTOCOL_ERROR,
- "Extended request operation not supported"));
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleModify(
- final Integer requestContext,
- final ModifyRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- // TODO: controls.
- // TODO: read lock is not really enough since concurrent updates may
- // still occur to the same entry.
- entryLock.readLock().lock();
- try
- {
- DN dn = request.getName();
- Entry entry = entries.get(dn);
- if (entry == null)
- {
- resultHandler
- .handleErrorResult(ErrorResultException
- .newErrorResult(ResultCode.NO_SUCH_OBJECT,
- "The entry " + dn.toString()
- + " does not exist"));
- }
-
- Entry newEntry = new LinkedHashMapEntry(entry);
- for (Modification mod : request.getModifications())
- {
- ModificationType modType = mod.getModificationType();
- if (modType.equals(ModificationType.ADD))
- {
- // TODO: Reject empty attribute and duplicate values.
- newEntry.addAttribute(mod.getAttribute(), null);
- }
- else if (modType.equals(ModificationType.DELETE))
- {
- // TODO: Reject missing values.
- newEntry.removeAttribute(mod.getAttribute(), null);
- }
- else if (modType.equals(ModificationType.REPLACE))
- {
- newEntry.replaceAttribute(mod.getAttribute());
- }
- else
- {
- resultHandler
- .handleErrorResult(newErrorResult(
- ResultCode.PROTOCOL_ERROR,
- "Modify request contains an unsupported modification type"));
- return;
- }
- }
-
- entries.put(dn, newEntry);
- resultHandler.handleResult(Responses
- .newResult(ResultCode.SUCCESS));
- }
- finally
- {
- entryLock.readLock().unlock();
- }
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleModifyDN(
- final Integer requestContext,
- final ModifyDNRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- // TODO: not implemented.
- resultHandler.handleErrorResult(newErrorResult(
- ResultCode.PROTOCOL_ERROR,
- "ModifyDN request operation not supported"));
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleSearch(
- final Integer requestContext,
- final SearchRequest request,
- final SearchResultHandler resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException
- {
- // TODO: controls, limits, etc.
- entryLock.readLock().lock();
- try
- {
- DN dn = request.getName();
- Entry baseEntry = entries.get(dn);
- if (baseEntry == null)
- {
- resultHandler
- .handleErrorResult(ErrorResultException
- .newErrorResult(ResultCode.NO_SUCH_OBJECT,
- "The entry " + dn.toString()
- + " does not exist"));
- }
-
- SearchScope scope = request.getScope();
- Filter filter = request.getFilter();
- Matcher matcher = filter.matcher();
-
- if (scope.equals(SearchScope.BASE_OBJECT))
- {
- if (matcher.matches(baseEntry).toBoolean())
- {
- sendEntry(request, resultHandler, baseEntry);
- }
- }
- else if (scope.equals(SearchScope.SINGLE_LEVEL))
- {
- sendEntry(request, resultHandler, baseEntry);
-
- NavigableMap<DN, Entry> subtree = entries.tailMap(dn,
- false);
- for (Entry entry : subtree.values())
- {
- DN childDN = entry.getName();
- if (childDN.isChildOf(dn))
- {
- if (!matcher.matches(entry).toBoolean())
- {
- continue;
- }
-
- if (!sendEntry(request, resultHandler, entry))
- {
- // Caller has asked to stop sending results.
- break;
- }
- }
- else if (!childDN.isSubordinateOrEqualTo(dn))
- {
- // The remaining entries will be out of scope.
- break;
- }
- }
- }
- else if (scope.equals(SearchScope.WHOLE_SUBTREE))
- {
- NavigableMap<DN, Entry> subtree = entries.tailMap(dn);
- for (Entry entry : subtree.values())
- {
- DN childDN = entry.getName();
- if (childDN.isSubordinateOrEqualTo(dn))
- {
- if (!matcher.matches(entry).toBoolean())
- {
- continue;
- }
-
- if (!sendEntry(request, resultHandler, entry))
- {
- // Caller has asked to stop sending results.
- break;
- }
- }
- else
- {
- // The remaining entries will be out of scope.
- break;
- }
- }
- }
- else
- {
- resultHandler
- .handleErrorResult(newErrorResult(
- ResultCode.PROTOCOL_ERROR,
- "Search request contains an unsupported search scope"));
- return;
- }
-
- resultHandler.handleResult(Responses
- .newResult(ResultCode.SUCCESS));
- }
- finally
- {
- entryLock.readLock().unlock();
- }
- }
-
-
-
- private boolean sendEntry(SearchRequest request,
- SearchResultHandler resultHandler, Entry entry)
- {
- // TODO: check filter, strip attributes.
- return resultHandler.handleEntry(Responses
- .newSearchResultEntry(entry));
- }
- }
-
-
-
private final ConcurrentSkipListMap<DN, Entry> entries;
private final ReentrantReadWriteLock entryLock = new ReentrantReadWriteLock();
- private Store(final ConcurrentSkipListMap<DN, Entry> entries)
+ private MemoryBackend(
+ final ConcurrentSkipListMap<DN, Entry> entries)
{
this.entries = entries;
}
@@ -510,13 +85,354 @@
* {@inheritDoc}
*/
@Override
- public ServerConnection<Integer> handleAccept(
- final LDAPClientContext clientContext)
- throws ErrorResultException
+ public void handleAdd(final RequestContext requestContext,
+ final AddRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
{
- return new ServerConnectionImpl(clientContext);
+ // TODO: controls.
+ entryLock.writeLock().lock();
+ try
+ {
+ DN dn = request.getName();
+ if (entries.containsKey(dn))
+ {
+ resultHandler.handleErrorResult(ErrorResultException
+ .newErrorResult(ResultCode.ENTRY_ALREADY_EXISTS,
+ "The entry " + dn.toString() + " already exists"));
+ }
+
+ DN parent = dn.parent();
+ if (!entries.containsKey(parent))
+ {
+ resultHandler.handleErrorResult(ErrorResultException
+ .newErrorResult(ResultCode.NO_SUCH_OBJECT,
+ "The parent entry " + parent.toString()
+ + " does not exist"));
+ }
+ else
+ {
+ entries.put(dn, request);
+ resultHandler.handleResult(Responses
+ .newResult(ResultCode.SUCCESS));
+ }
+ }
+ finally
+ {
+ entryLock.writeLock().unlock();
+ }
}
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleBind(final RequestContext requestContext,
+ final int version, final BindRequest request,
+ final ResultHandler<? super BindResult> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ if (request.getAuthenticationType() != ((byte) 0x80))
+ {
+ // TODO: SASL authentication not implemented.
+ resultHandler.handleErrorResult(newErrorResult(
+ ResultCode.PROTOCOL_ERROR,
+ "non-SIMPLE authentication not supported: "
+ + request.getAuthenticationType()));
+ }
+ else
+ {
+ // TODO: always succeed.
+ resultHandler.handleResult(Responses
+ .newBindResult(ResultCode.SUCCESS));
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleCompare(final RequestContext requestContext,
+ final CompareRequest request,
+ final ResultHandler<? super CompareResult> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ // TODO:
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleDelete(final RequestContext requestContext,
+ final DeleteRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ // TODO: controls.
+ entryLock.writeLock().lock();
+ try
+ {
+ // TODO: check for children.
+ DN dn = request.getName();
+ if (!entries.containsKey(dn))
+ {
+ resultHandler.handleErrorResult(ErrorResultException
+ .newErrorResult(ResultCode.NO_SUCH_OBJECT, "The entry "
+ + dn.toString() + " does not exist"));
+ }
+ else
+ {
+ entries.remove(dn);
+ resultHandler.handleResult(Responses
+ .newResult(ResultCode.SUCCESS));
+ }
+ }
+ finally
+ {
+ entryLock.writeLock().unlock();
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <R extends ExtendedResult> void handleExtendedRequest(
+ final RequestContext requestContext,
+ final ExtendedRequest<R> request,
+ final ResultHandler<? super R> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ // TODO: not implemented.
+ resultHandler.handleErrorResult(newErrorResult(
+ ResultCode.PROTOCOL_ERROR,
+ "Extended request operation not supported"));
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleModify(final RequestContext requestContext,
+ final ModifyRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ // TODO: controls.
+ // TODO: read lock is not really enough since concurrent updates may
+ // still occur to the same entry.
+ entryLock.readLock().lock();
+ try
+ {
+ DN dn = request.getName();
+ Entry entry = entries.get(dn);
+ if (entry == null)
+ {
+ resultHandler.handleErrorResult(ErrorResultException
+ .newErrorResult(ResultCode.NO_SUCH_OBJECT, "The entry "
+ + dn.toString() + " does not exist"));
+ }
+
+ Entry newEntry = new LinkedHashMapEntry(entry);
+ for (Modification mod : request.getModifications())
+ {
+ ModificationType modType = mod.getModificationType();
+ if (modType.equals(ModificationType.ADD))
+ {
+ // TODO: Reject empty attribute and duplicate values.
+ newEntry.addAttribute(mod.getAttribute(), null);
+ }
+ else if (modType.equals(ModificationType.DELETE))
+ {
+ // TODO: Reject missing values.
+ newEntry.removeAttribute(mod.getAttribute(), null);
+ }
+ else if (modType.equals(ModificationType.REPLACE))
+ {
+ newEntry.replaceAttribute(mod.getAttribute());
+ }
+ else
+ {
+ resultHandler
+ .handleErrorResult(newErrorResult(
+ ResultCode.PROTOCOL_ERROR,
+ "Modify request contains an unsupported modification type"));
+ return;
+ }
+ }
+
+ entries.put(dn, newEntry);
+ resultHandler.handleResult(Responses
+ .newResult(ResultCode.SUCCESS));
+ }
+ finally
+ {
+ entryLock.readLock().unlock();
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleModifyDN(final RequestContext requestContext,
+ final ModifyDNRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ // TODO: not implemented.
+ resultHandler.handleErrorResult(newErrorResult(
+ ResultCode.PROTOCOL_ERROR,
+ "ModifyDN request operation not supported"));
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleSearch(final RequestContext requestContext,
+ final SearchRequest request,
+ final SearchResultHandler resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ // TODO: controls, limits, etc.
+ entryLock.readLock().lock();
+ try
+ {
+ DN dn = request.getName();
+ Entry baseEntry = entries.get(dn);
+ if (baseEntry == null)
+ {
+ resultHandler.handleErrorResult(ErrorResultException
+ .newErrorResult(ResultCode.NO_SUCH_OBJECT, "The entry "
+ + dn.toString() + " does not exist"));
+ }
+
+ SearchScope scope = request.getScope();
+ Filter filter = request.getFilter();
+ Matcher matcher = filter.matcher();
+
+ if (scope.equals(SearchScope.BASE_OBJECT))
+ {
+ if (matcher.matches(baseEntry).toBoolean())
+ {
+ sendEntry(request, resultHandler, baseEntry);
+ }
+ }
+ else if (scope.equals(SearchScope.SINGLE_LEVEL))
+ {
+ sendEntry(request, resultHandler, baseEntry);
+
+ NavigableMap<DN, Entry> subtree = entries
+ .tailMap(dn, false);
+ for (Entry entry : subtree.values())
+ {
+ // Check for cancellation.
+ requestContext.checkIfCancelled(false);
+
+ DN childDN = entry.getName();
+ if (childDN.isChildOf(dn))
+ {
+ if (!matcher.matches(entry).toBoolean())
+ {
+ continue;
+ }
+
+ if (!sendEntry(request, resultHandler, entry))
+ {
+ // Caller has asked to stop sending results.
+ break;
+ }
+ }
+ else if (!childDN.isSubordinateOrEqualTo(dn))
+ {
+ // The remaining entries will be out of scope.
+ break;
+ }
+ }
+ }
+ else if (scope.equals(SearchScope.WHOLE_SUBTREE))
+ {
+ NavigableMap<DN, Entry> subtree = entries.tailMap(dn);
+ for (Entry entry : subtree.values())
+ {
+ // Check for cancellation.
+ requestContext.checkIfCancelled(false);
+
+ DN childDN = entry.getName();
+ if (childDN.isSubordinateOrEqualTo(dn))
+ {
+ if (!matcher.matches(entry).toBoolean())
+ {
+ continue;
+ }
+
+ if (!sendEntry(request, resultHandler, entry))
+ {
+ // Caller has asked to stop sending results.
+ break;
+ }
+ }
+ else
+ {
+ // The remaining entries will be out of scope.
+ break;
+ }
+ }
+ }
+ else
+ {
+ resultHandler.handleErrorResult(newErrorResult(
+ ResultCode.PROTOCOL_ERROR,
+ "Search request contains an unsupported search scope"));
+ return;
+ }
+
+ resultHandler.handleResult(Responses
+ .newResult(ResultCode.SUCCESS));
+ }
+ catch (CancelledResultException e)
+ {
+ resultHandler.handleErrorResult(e);
+ }
+ finally
+ {
+ entryLock.readLock().unlock();
+ }
+ }
+
+
+
+ private boolean sendEntry(SearchRequest request,
+ SearchResultHandler resultHandler, Entry entry)
+ {
+ // TODO: check filter, strip attributes.
+ return resultHandler.handleEntry(Responses
+ .newSearchResultEntry(entry));
+ }
}
@@ -538,22 +454,70 @@
// Parse command line arguments.
final String localAddress = args[0];
final int localPort = Integer.parseInt(args[1]);
+ final String ldifFileName = args[2];
+ // Create the memory backend.
+ final ConcurrentSkipListMap<DN, Entry> entries = readEntriesFromLDIF(ldifFileName);
+ final MemoryBackend backend = new MemoryBackend(entries);
+
+ // Create a server connection adapter.
+ final ServerConnectionFactory<LDAPClientContext, Integer> connectionHandler =
+ Connections.newServerConnectionFactory(backend);
+
+ // Create listener.
+ final LDAPListenerOptions options = new LDAPListenerOptions()
+ .setBacklog(4096);
+ LDAPListener listener = null;
+ try
+ {
+ listener = new LDAPListener(localAddress, localPort,
+ connectionHandler, options);
+ System.out.println("Press any key to stop the server...");
+ System.in.read();
+ }
+ catch (final IOException e)
+ {
+ System.out.println("Error listening on " + localAddress + ":"
+ + localPort);
+ e.printStackTrace();
+ }
+ finally
+ {
+ if (listener != null)
+ {
+ listener.close();
+ }
+ }
+ }
+
+
+
+ /**
+ * Reads the entries from the named LDIF file.
+ *
+ * @param ldifFileName
+ * The name of the LDIF file.
+ * @return The entries.
+ */
+ private static ConcurrentSkipListMap<DN, Entry> readEntriesFromLDIF(
+ final String ldifFileName)
+ {
+ final ConcurrentSkipListMap<DN, Entry> entries;
// Read the LDIF.
InputStream ldif;
try
{
- ldif = new FileInputStream(args[2]);
+ ldif = new FileInputStream(ldifFileName);
}
catch (final FileNotFoundException e)
{
System.err.println(e.getMessage());
System.exit(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
- return;
+ return null; // Satisfy compiler.
}
+ entries = new ConcurrentSkipListMap<DN, Entry>();
final LDIFEntryReader reader = new LDIFEntryReader(ldif);
- ConcurrentSkipListMap<DN, Entry> entries = new ConcurrentSkipListMap<DN, Entry>();
try
{
while (reader.hasNext())
@@ -566,7 +530,7 @@
{
System.err.println(e.getMessage());
System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue());
- return;
+ return null; // Satisfy compiler.
}
finally
{
@@ -600,31 +564,7 @@
{
System.exit(1);
}
-
- // Create listener.
- final LDAPListenerOptions options = new LDAPListenerOptions()
- .setBacklog(4096);
- LDAPListener listener = null;
- try
- {
- listener = new LDAPListener(localAddress, localPort, new Store(
- entries), options);
- System.out.println("Press any key to stop the server...");
- System.in.read();
- }
- catch (final IOException e)
- {
- System.out.println("Error listening on " + localAddress + ":"
- + localPort);
- e.printStackTrace();
- }
- finally
- {
- if (listener != null)
- {
- listener.close();
- }
- }
+ return entries;
}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/AbstractLDAPFutureResultImpl.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/AbstractLDAPFutureResultImpl.java
index 2a58062..9ba5157 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/AbstractLDAPFutureResultImpl.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/AbstractLDAPFutureResultImpl.java
@@ -156,7 +156,7 @@
{
if (result.getResultCode().isExceptional())
{
- handleErrorResult(ErrorResultException.wrap(result));
+ handleErrorResult(ErrorResultException.newErrorResult(result));
}
else
{
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java
index d9e55bc..e0ccf0d 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnection.java
@@ -29,6 +29,8 @@
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
+
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.List;
@@ -122,7 +124,7 @@
if (connectionInvalidReason != null)
{
return new CompletedFutureResult<Void>(
- ErrorResultException.wrap(connectionInvalidReason), messageID);
+ newErrorResult(connectionInvalidReason), messageID);
}
if (bindOrStartTLSInProgress.get())
{
@@ -130,7 +132,7 @@
ResultCode.OPERATIONS_ERROR).setDiagnosticMessage(
"Bind or Start TLS operation in progress");
return new CompletedFutureResult<Void>(
- ErrorResultException.wrap(errorResult), messageID);
+ newErrorResult(errorResult), messageID);
}
// First remove the future associated with the request to be abandoned.
@@ -171,7 +173,7 @@
ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e);
connectionErrorOccurred(errorResult);
return new CompletedFutureResult<Void>(
- ErrorResultException.wrap(errorResult), messageID);
+ newErrorResult(errorResult), messageID);
}
}
@@ -273,7 +275,7 @@
.newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR)
.setDiagnosticMessage(
"An error occurred while creating a bind context").setCause(e);
- final ErrorResultException error = ErrorResultException.wrap(errorResult);
+ final ErrorResultException error = ErrorResultException.newErrorResult(errorResult);
if (resultHandler != null)
{
resultHandler.handleErrorResult(error);
@@ -783,7 +785,7 @@
{
if (connectionInvalidReason != null)
{
- throw ErrorResultException.wrap(connectionInvalidReason);
+ throw newErrorResult(connectionInvalidReason);
}
pendingRequests.put(newMsgID, request);
}
@@ -920,7 +922,7 @@
for (final ConnectionEventListener listener : listeners)
{
listener.handleConnectionError(isDisconnectNotification,
- ErrorResultException.wrap(reason));
+ newErrorResult(reason));
}
}
}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java
index 77b59b6..b3a566f 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java
@@ -30,6 +30,8 @@
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
+
import java.io.IOException;
import java.net.SocketAddress;
import java.util.concurrent.ExecutionException;
@@ -40,7 +42,6 @@
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.requests.StartTLSExtendedRequest;
import org.forgerock.opendj.ldap.responses.ExtendedResult;
-import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
import org.glassfish.grizzly.CompletionHandler;
import org.glassfish.grizzly.Connection;
@@ -156,22 +157,18 @@
@Override
public void failed(final Throwable throwable)
{
- final Result errorResult = Responses
- .newResult(ResultCode.CLIENT_SIDE_CONNECT_ERROR)
- .setCause(throwable)
- .setDiagnosticMessage(throwable.getMessage());
- handler.handleErrorResult(ErrorResultException
- .wrap(errorResult));
+ handler.handleErrorResult(newErrorResult(
+ ResultCode.CLIENT_SIDE_CONNECT_ERROR,
+ throwable.getMessage(), throwable));
}
});
return null;
}
catch (final IOException ioe)
{
- final Result errorResult = Responses
- .newResult(ResultCode.CLIENT_SIDE_CONNECT_ERROR)
- .setCause(ioe).setDiagnosticMessage(ioe.getMessage());
- throw ErrorResultException.wrap(errorResult);
+ throw newErrorResult(
+ ResultCode.CLIENT_SIDE_CONNECT_ERROR,
+ ioe.getMessage(), ioe);
}
}
handler.handleResult(null);
@@ -345,9 +342,7 @@
t = t.getCause();
}
- final Result result = Responses
- .newResult(ResultCode.CLIENT_SIDE_CONNECT_ERROR).setCause(t)
- .setDiagnosticMessage(t.getMessage());
- return ErrorResultException.wrap(result);
+ return newErrorResult(ResultCode.CLIENT_SIDE_CONNECT_ERROR,
+ t.getMessage(), t);
}
}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/AsynchronousFutureResult.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/AsynchronousFutureResult.java
index b29413e..c1fd084 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/AsynchronousFutureResult.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/AsynchronousFutureResult.java
@@ -29,13 +29,13 @@
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
+
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import org.forgerock.opendj.ldap.*;
-import org.forgerock.opendj.ldap.responses.Responses;
-import org.forgerock.opendj.ldap.responses.Result;
@@ -134,9 +134,7 @@
ErrorResultException errorResult = handleCancelRequest(mayInterruptIfRunning);
if (errorResult == null)
{
- final Result result = Responses
- .newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED);
- errorResult = ErrorResultException.wrap(result);
+ errorResult = newErrorResult(ResultCode.CLIENT_SIDE_USER_CANCELLED);
}
this.errorResult = errorResult;
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnection.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnection.java
index 12639af..61fad4d 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnection.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractAsynchronousConnection.java
@@ -32,6 +32,7 @@
import static org.forgerock.opendj.ldap.CoreMessages.ERR_NO_SEARCH_RESULT_ENTRIES;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES;
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
@@ -176,29 +177,26 @@
if (entryCount == 0)
{
// Did not find any entries.
- final Result result = Responses.newResult(
- ResultCode.CLIENT_SIDE_NO_RESULTS_RETURNED).setDiagnosticMessage(
+ throw newErrorResult(
+ ResultCode.CLIENT_SIDE_NO_RESULTS_RETURNED,
ERR_NO_SEARCH_RESULT_ENTRIES.get().toString());
- throw ErrorResultException.wrap(result);
}
else if (entryCount > 1)
{
// Got more entries than expected.
- final Result result = Responses
- .newResult(ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED)
- .setDiagnosticMessage(
- ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES.get(entryCount).toString());
- throw ErrorResultException.wrap(result);
+ throw newErrorResult(
+ ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED,
+ ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES.get(entryCount)
+ .toString());
}
else if (firstReference != null)
{
// Got an unexpected search result reference.
- final Result result = Responses.newResult(
- ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED)
- .setDiagnosticMessage(
- ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES.get(
- firstReference.getURIs().iterator().next()).toString());
- throw ErrorResultException.wrap(result);
+ throw newErrorResult(
+ ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED,
+ ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES.get(
+ firstReference.getURIs().iterator().next())
+ .toString());
}
else
{
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java
index 70957e4..46288cb 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractConnection.java
@@ -32,6 +32,7 @@
import static org.forgerock.opendj.ldap.CoreMessages.ERR_NO_SEARCH_RESULT_ENTRIES;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES;
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
import java.util.Collection;
import java.util.concurrent.BlockingQueue;
@@ -433,31 +434,26 @@
if (handler.entryCount == 0)
{
// Did not find any entries.
- final Result result = Responses.newResult(
- ResultCode.CLIENT_SIDE_NO_RESULTS_RETURNED).setDiagnosticMessage(
+ throw newErrorResult(
+ ResultCode.CLIENT_SIDE_NO_RESULTS_RETURNED,
ERR_NO_SEARCH_RESULT_ENTRIES.get().toString());
- throw ErrorResultException.wrap(result);
}
else if (handler.entryCount > 1)
{
// Got more entries than expected.
- final Result result = Responses.newResult(
- ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED)
- .setDiagnosticMessage(
- ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES.get(handler.entryCount)
- .toString());
- throw ErrorResultException.wrap(result);
+ throw newErrorResult(
+ ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED,
+ ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES
+ .get(handler.entryCount).toString());
}
else if (handler.firstReference != null)
{
// Got an unexpected search result reference.
- final Result result = Responses.newResult(
- ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED)
- .setDiagnosticMessage(
- ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES.get(
- handler.firstReference.getURIs().iterator().next())
- .toString());
- throw ErrorResultException.wrap(result);
+ throw newErrorResult(
+ ResultCode.CLIENT_SIDE_UNEXPECTED_RESULTS_RETURNED,
+ ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES.get(
+ handler.firstReference.getURIs().iterator().next())
+ .toString());
}
else
{
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java
index ff9d547..920f712 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java
@@ -29,6 +29,8 @@
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -38,8 +40,6 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
-import org.forgerock.opendj.ldap.responses.Responses;
-
import com.forgerock.opendj.util.AsynchronousFutureResult;
import com.forgerock.opendj.util.StaticUtils;
import com.forgerock.opendj.util.Validator;
@@ -439,8 +439,7 @@
// All factories are offline so give up. We could have a
// configurable policy here such as waiting indefinitely, or for a
// configurable timeout period.
- throw ErrorResultException.wrap(Responses.newResult(
- ResultCode.CLIENT_SIDE_CONNECT_ERROR).setDiagnosticMessage(
- "No operational connection factories available"));
+ throw newErrorResult(ResultCode.CLIENT_SIDE_CONNECT_ERROR,
+ "No operational connection factories available");
}
}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/CancelRequestListener.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/CancelRequestListener.java
new file mode 100644
index 0000000..ae3e154
--- /dev/null
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/CancelRequestListener.java
@@ -0,0 +1,64 @@
+/*
+ * 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/opendj3/legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * 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/opendj3/legal-notices/CDDLv1_0.txt. 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 2011 ForgeRock AS
+ */
+
+package org.forgerock.opendj.ldap;
+
+
+
+import java.util.EventListener;
+
+import org.forgerock.i18n.LocalizableMessage;
+
+
+
+/**
+ * An object that registers to be notified when a cancellation request has been
+ * received and processing of the request should be aborted if possible.
+ * <p>
+ * Requests may be cancelled as a result of an abandon request or a cancel
+ * extended request sent from the client, or by the server itself (e.g. during
+ * server shutdown).
+ */
+public interface CancelRequestListener extends EventListener
+{
+ /**
+ * Invoked when a cancellation request has been received and processing of the
+ * request should be aborted if possible.
+ * <p>
+ * Requests may be cancelled as a result of an abandon request or a cancel
+ * extended request sent from the client, or by the server itself (e.g. during
+ * server shutdown).
+ * <p>
+ * Implementations should, if possible, abort further processing of the
+ * request and return an appropriate cancellation result.
+ *
+ * @param cancellationReason
+ * A message describing the reason why the request is being
+ * cancelled.
+ */
+ void handleCancelRequest(LocalizableMessage cancellationReason);
+}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java
index 7fe0ca8..7b1c24c 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Connections.java
@@ -334,6 +334,83 @@
+ /**
+ * Creates a new server connection factory using the provided
+ * {@link RequestHandler}. The returned factory will manage connection and
+ * request life-cycle, including request cancellation.
+ * <p>
+ * When processing requests, {@link RequestHandler} implementations are passed
+ * a {@link RequestContext} as the first parameter which may be used for
+ * detecting whether or not the request should be aborted due to cancellation
+ * requests or other events, such as connection failure.
+ * <p>
+ * The returned factory maintains state information which includes a table of
+ * active requests. Therefore, {@code RequestHandler} implementations are
+ * required to always return results in order to avoid potential memory leaks.
+ *
+ * @param <C>
+ * The type of client context.
+ * @param requestHandler
+ * The request handler which will be used for all client connections.
+ * @return The new server connection factory.
+ * @throws NullPointerException
+ * If {@code requestHandler} was {@code null}.
+ */
+ public static <C> ServerConnectionFactory<C, Integer> newServerConnectionFactory(
+ final RequestHandler<RequestContext> requestHandler)
+ throws NullPointerException
+ {
+ Validator.ensureNotNull(requestHandler);
+
+ final RequestHandlerFactory<C, RequestContext> factory =
+ new RequestHandlerFactory<C, RequestContext>()
+ {
+
+ public RequestHandler<RequestContext> handleAccept(
+ C clientContext) throws ErrorResultException
+ {
+ return requestHandler;
+ }
+ };
+
+ return new RequestHandlerFactoryAdapter<C>(factory);
+ }
+
+
+
+ /**
+ * Creates a new server connection factory using the provided
+ * {@link RequestHandlerFactory}. The returned factory will manage connection
+ * and request life-cycle, including request cancellation.
+ * <p>
+ * When processing requests, {@link RequestHandler} implementations are passed
+ * a {@link RequestContext} as the first parameter which may be used for
+ * detecting whether or not the request should be aborted due to cancellation
+ * requests or other events, such as connection failure.
+ * <p>
+ * The returned factory maintains state information which includes a table of
+ * active requests. Therefore, {@code RequestHandler} implementations are
+ * required to always return results in order to avoid potential memory leaks.
+ *
+ * @param <C>
+ * The type of client context.
+ * @param factory
+ * The request handler factory to use for associating request
+ * handlers with client connections.
+ * @return The new server connection factory.
+ * @throws NullPointerException
+ * If {@code factory} was {@code null}.
+ */
+ public static <C> ServerConnectionFactory<C, Integer> newServerConnectionFactory(
+ final RequestHandlerFactory<C, RequestContext> factory)
+ throws NullPointerException
+ {
+ Validator.ensureNotNull(factory);
+ return new RequestHandlerFactoryAdapter<C>(factory);
+ }
+
+
+
// Prevent instantiation.
private Connections()
{
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ErrorResultException.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ErrorResultException.java
index 2b81c13..8e40b92 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ErrorResultException.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ErrorResultException.java
@@ -45,6 +45,27 @@
{
/**
+ * Creates a new error result exception with the provided result code and an
+ * empty diagnostic message.
+ *
+ * @param resultCode
+ * The result code.
+ * @return The new error result exception.
+ * @throws IllegalArgumentException
+ * If the provided result code does not represent a failure.
+ * @throws NullPointerException
+ * If {@code resultCode} was {@code null}.
+ */
+ public static ErrorResultException newErrorResult(
+ ResultCode resultCode) throws IllegalArgumentException,
+ NullPointerException
+ {
+ return newErrorResult(resultCode, null, null);
+ }
+
+
+
+ /**
* Creates a new error result exception with the provided result code and
* diagnostic message.
*
@@ -59,9 +80,9 @@
* @throws NullPointerException
* If {@code resultCode} was {@code null}.
*/
- public static ErrorResultException newErrorResult(ResultCode resultCode,
- String diagnosticMessage) throws IllegalArgumentException,
- NullPointerException
+ public static ErrorResultException newErrorResult(
+ ResultCode resultCode, String diagnosticMessage)
+ throws IllegalArgumentException, NullPointerException
{
return newErrorResult(resultCode, diagnosticMessage, null);
}
@@ -69,6 +90,30 @@
/**
+ * Creates a new error result exception with the provided result code and
+ * cause. The diagnostic message will be taken from the cause, if provided.
+ *
+ * @param resultCode
+ * The result code.
+ * @param cause
+ * The throwable cause, which may be {@code null} indicating that
+ * none was provided.
+ * @return The new error result exception.
+ * @throws IllegalArgumentException
+ * If the provided result code does not represent a failure.
+ * @throws NullPointerException
+ * If {@code resultCode} was {@code null}.
+ */
+ public static ErrorResultException newErrorResult(
+ ResultCode resultCode, Throwable cause)
+ throws IllegalArgumentException, NullPointerException
+ {
+ return newErrorResult(resultCode, null, cause);
+ }
+
+
+
+ /**
* Creates a new error result exception with the provided result code,
* diagnostic message, and cause.
*
@@ -78,28 +123,35 @@
* The diagnostic message, which may be empty or {@code null}
* indicating that none was provided.
* @param cause
- * The throwable cause, which may be null indicating that none was
- * provided.
+ * The throwable cause, which may be {@code null} indicating that
+ * none was provided.
* @return The new error result exception.
* @throws IllegalArgumentException
* If the provided result code does not represent a failure.
* @throws NullPointerException
* If {@code resultCode} was {@code null}.
*/
- public static ErrorResultException newErrorResult(ResultCode resultCode,
- String diagnosticMessage, Throwable cause)
+ public static ErrorResultException newErrorResult(
+ ResultCode resultCode, String diagnosticMessage, Throwable cause)
throws IllegalArgumentException, NullPointerException
{
- Result result = Responses.newResult(resultCode)
- .setDiagnosticMessage(diagnosticMessage).setCause(cause);
- return wrap(result);
+ final Result result = Responses.newResult(resultCode);
+ if (diagnosticMessage != null)
+ {
+ result.setDiagnosticMessage(diagnosticMessage);
+ }
+ else if (cause != null)
+ {
+ result.setDiagnosticMessage(cause.getLocalizedMessage());
+ }
+ result.setCause(cause);
+ return newErrorResult(result);
}
/**
- * Wraps the provided result in an appropriate error result exception. The
- * type of error result exception used depends on the underlying result code.
+ * Creates a new error result exception using the provided result.
*
* @param result
* The result whose result code indicates a failure.
@@ -109,8 +161,9 @@
* @throws NullPointerException
* If {@code result} was {@code null}.
*/
- public static ErrorResultException wrap(final Result result)
- throws IllegalArgumentException, NullPointerException
+ public static ErrorResultException newErrorResult(
+ final Result result) throws IllegalArgumentException,
+ NullPointerException
{
if (!result.getResultCode().isExceptional())
{
@@ -199,7 +252,8 @@
*/
ErrorResultException(final Result result)
{
- super(result.getResultCode() + ": " + result.getDiagnosticMessage());
+ super(result.getResultCode() + ": "
+ + result.getDiagnosticMessage());
this.result = result;
}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestContext.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestContext.java
new file mode 100644
index 0000000..8bf6db9
--- /dev/null
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestContext.java
@@ -0,0 +1,118 @@
+/*
+ * 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/opendj3/legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * 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/opendj3/legal-notices/CDDLv1_0.txt. 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 2011 ForgeRock AS
+ */
+
+package org.forgerock.opendj.ldap;
+
+
+
+/**
+ * The context associated with a request currently being processed by a request
+ * handler. A request context can be used to query state information about the
+ * request, such as whether or not it has been cancelled, as well as registering
+ * to be notified if the request has been cancelled. Implementations may provide
+ * additional information, such as the associated schema, time-stamp
+ * information, etc.
+ */
+public interface RequestContext
+{
+
+ /**
+ * Registers the provided cancellation listener with this request context so
+ * that it can be notified if a cancellation request is received and
+ * processing of the request should be aborted if possible.
+ * <p>
+ * Requests may be cancelled as a result of an abandon request or a cancel
+ * extended request sent from the client, or by the server itself (e.g. during
+ * server shutdown).
+ * <p>
+ * This method provides a event notification mechanism which can be used by
+ * asynchronous request handler implementations to detect cancellation of
+ * requests.
+ *
+ * @param listener
+ * The listener which wants to be notified if a cancellation request
+ * is received and processing of the request should be aborted if
+ * possible.
+ * @throws NullPointerException
+ * If the {@code listener} was {@code null}.
+ * @see #checkIfCancelled
+ */
+ void addCancelRequestListener(CancelRequestListener listener)
+ throws NullPointerException;
+
+
+
+ /**
+ * Throws {@link CancelledResultException} if a cancellation request has been
+ * received and processing of the request should be aborted if possible.
+ * <p>
+ * Requests may be cancelled as a result of an abandon request or a cancel
+ * extended request sent from the client, or by the server itself (e.g. during
+ * server shutdown).
+ * <p>
+ * This method provides a polling mechanism which can be used by synchronous
+ * request handler implementations to detect cancellation of requests.
+ *
+ * @param signalTooLate
+ * {@code true} to signal that, after this method returns, processing
+ * of the request will have proceeded too far for it to be aborted by
+ * subsequent cancellation requests.
+ * @throws CancelledResultException
+ * If a cancellation request has been received and processing of the
+ * request should be aborted if possible.
+ * @see #addCancelRequestListener
+ */
+ void checkIfCancelled(boolean signalTooLate)
+ throws CancelledResultException;
+
+
+
+ /**
+ * Returns the message ID of the request, if available. Protocols, such as
+ * LDAP and internal connections, include a unique message ID with each
+ * request which may be useful for logging and auditing.
+ *
+ * @return The message ID of the request, or {@code -1} if there is no message
+ * ID associated with the request.
+ */
+ int getMessageID();
+
+
+
+ /**
+ * Removes the provided cancellation listener from this request context so
+ * that it will not be notified if a cancellation request has been received.
+ *
+ * @param listener
+ * The listener which no longer wants to be notified if a
+ * cancellation request has been received.
+ * @throws NullPointerException
+ * If the {@code listener} was {@code null}.
+ */
+ void removeCancelRequestListener(CancelRequestListener listener)
+ throws NullPointerException;
+}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactory.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactory.java
new file mode 100644
index 0000000..fe745fe
--- /dev/null
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactory.java
@@ -0,0 +1,61 @@
+/*
+ * 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/opendj3/legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * 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/opendj3/legal-notices/CDDLv1_0.txt. 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 2011 ForgeRock AS
+ */
+
+package org.forgerock.opendj.ldap;
+
+
+
+/**
+ * A handler interface for accepting new connections from clients.
+ *
+ * @param <C>
+ * The type of client context.
+ * @param <R>
+ * The type of request context.
+ */
+public interface RequestHandlerFactory<C, R extends RequestContext>
+{
+ /**
+ * Invoked when a new client connection is accepted by the associated
+ * listener. Implementations should return a {@code RequestHandler} which will
+ * be used to handle requests from the client connection.
+ *
+ * @param clientContext
+ * The protocol dependent context information associated with the
+ * client connection. Depending on the protocol this may contain
+ * information about the client such as their address and level
+ * connection security. It may also be used to manage the state of
+ * the client's connection.
+ * @return A {@code RequestHandler} which will be used to handle requests from
+ * a client connection.
+ * @throws ErrorResultException
+ * If this request handler factory cannot accept the client
+ * connection.
+ */
+ RequestHandler<R> handleAccept(C clientContext)
+ throws ErrorResultException;
+}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactoryAdapter.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactoryAdapter.java
new file mode 100644
index 0000000..4f5476d
--- /dev/null
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/RequestHandlerFactoryAdapter.java
@@ -0,0 +1,983 @@
+/*
+ * 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/opendj3/legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * 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/opendj3/legal-notices/CDDLv1_0.txt. 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 2011 ForgeRock AS
+ */
+
+package org.forgerock.opendj.ldap;
+
+
+
+import static org.forgerock.opendj.ldap.CoreMessages.*;
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.opendj.ldap.requests.*;
+import org.forgerock.opendj.ldap.responses.*;
+
+import com.forgerock.opendj.util.Validator;
+
+
+
+/**
+ * An adapter which converts a {@code RequestHandlerFactory} into a
+ * {@code ServerConnectionFactory}.
+ *
+ * @param <C>
+ * The type of client context.
+ */
+final class RequestHandlerFactoryAdapter<C> implements
+ ServerConnectionFactory<C, Integer>
+{
+ /**
+ * Request context implementation.
+ */
+ private static class RequestContextImpl<S extends Result, H extends ResultHandler<? super S>>
+ implements RequestContext, ResultHandler<S>
+ {
+
+ // Adapter class which invokes cancel result handlers with correct result
+ // type.
+ private static final class ExtendedResultHandlerHolder<R extends ExtendedResult>
+ {
+ private final ExtendedRequest<R> request;
+ private final ResultHandler<? super R> resultHandler;
+
+
+
+ private ExtendedResultHandlerHolder(
+ final ExtendedRequest<R> request,
+ final ResultHandler<? super R> resultHandler)
+ {
+ this.request = request;
+ this.resultHandler = resultHandler;
+ }
+
+
+
+ private void handleSuccess()
+ {
+ final R cancelResult = request.getResultDecoder()
+ .newExtendedErrorResult(ResultCode.SUCCESS, "", "");
+ resultHandler.handleResult(cancelResult);
+ }
+
+
+
+ private void handleTooLate()
+ {
+ final R cancelResult = request.getResultDecoder()
+ .newExtendedErrorResult(ResultCode.TOO_LATE, "", "");
+ resultHandler.handleErrorResult(ErrorResultException
+ .newErrorResult(cancelResult));
+ }
+ }
+
+
+
+ private static enum RequestState
+ {
+ // Request active
+ PENDING,
+
+ // Request active, cancel requested
+ CANCEL_REQUESTED,
+
+ // Request active, too late to cancel
+ TOO_LATE,
+
+ // Result sent, not cancelled
+ RESULT_SENT,
+
+ // Result sent, was cancelled
+ CANCELLED;
+ }
+
+
+
+ private final int messageID;
+
+ // Cancellation state guarded by lock.
+ private final Object stateLock = new Object();
+
+ // These should be notified when a cancel request arrives, at most once.
+ private List<CancelRequestListener> cancelRequestListeners = null;
+
+ // These should be notified when the result is set.
+ private List<ExtendedResultHandlerHolder<?>> cancelResultHandlers = null;
+
+ private RequestState state = RequestState.PENDING;
+
+ private LocalizableMessage cancelRequestReason = null;
+
+ private boolean sendResult = true;
+
+ private final boolean isCancelSupported;
+
+ private final ServerConnectionImpl<?> clientConnection;
+
+ protected final H resultHandler;
+
+
+
+ protected RequestContextImpl(
+ final ServerConnectionImpl<?> clientConnection,
+ final H resultHandler, final int messageID,
+ final boolean isCancelSupported)
+ {
+ this.clientConnection = clientConnection;
+ this.resultHandler = resultHandler;
+ this.messageID = messageID;
+ this.isCancelSupported = isCancelSupported;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addCancelRequestListener(
+ final CancelRequestListener listener)
+ throws NullPointerException
+ {
+ Validator.ensureNotNull(listener);
+
+ boolean invokeImmediately = false;
+ synchronized (stateLock)
+ {
+ switch (state)
+ {
+ case PENDING:
+ if (cancelRequestListeners == null)
+ {
+ cancelRequestListeners = new LinkedList<CancelRequestListener>();
+ }
+ cancelRequestListeners.add(listener);
+ break;
+ case CANCEL_REQUESTED:
+ // Signal immediately outside lock.
+ invokeImmediately = true;
+ break;
+ case TOO_LATE:
+ case RESULT_SENT:
+ case CANCELLED:
+ // No point in registering the callback since the request can never be
+ // cancelled now.
+ break;
+ }
+ }
+
+ if (invokeImmediately)
+ {
+ listener.handleCancelRequest(cancelRequestReason);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void checkIfCancelled(final boolean signalTooLate)
+ throws CancelledResultException
+ {
+ synchronized (stateLock)
+ {
+ switch (state)
+ {
+ case PENDING:
+ // No cancel request, so no handlers, just switch state.
+ if (signalTooLate)
+ {
+ cancelRequestListeners = null;
+ state = RequestState.TOO_LATE;
+ }
+ break;
+ case CANCEL_REQUESTED:
+ // Don't change state: let the handler ack the cancellation request.
+ throw (CancelledResultException) newErrorResult(
+ ResultCode.CANCELLED, cancelRequestReason.toString());
+ case TOO_LATE:
+ // Already too late. Nothing to do.
+ break;
+ case RESULT_SENT:
+ case CANCELLED:
+ // This should not happen - could throw an illegal state exception?
+ break;
+ }
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getMessageID()
+ {
+ return messageID;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleErrorResult(final ErrorResultException error)
+ {
+ if (clientConnection.removePendingRequest(this))
+ {
+ if (setResult(error.getResult()))
+ {
+ // FIXME: we must invoke the result handler even when abandoned so
+ // that chained result handlers may clean up, log, etc. We really need
+ // to signal that the result must not be sent to the client.
+ }
+ resultHandler.handleErrorResult(error);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleResult(final S result)
+ {
+ if (clientConnection.removePendingRequest(this))
+ {
+ if (setResult(result))
+ {
+ // FIXME: we must invoke the result handler even when abandoned so
+ // that chained result handlers may clean up, log, etc. We really need
+ // to signal that the result must not be sent to the client.
+ }
+ resultHandler.handleResult(result);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeCancelRequestListener(
+ final CancelRequestListener listener)
+ throws NullPointerException
+ {
+ Validator.ensureNotNull(listener);
+
+ synchronized (stateLock)
+ {
+ if (cancelRequestListeners != null)
+ {
+ cancelRequestListeners.remove(listener);
+ }
+ }
+ }
+
+
+
+ private <R extends ExtendedResult> void cancel(
+ final LocalizableMessage reason,
+ final ExtendedRequest<R> cancelRequest,
+ final ResultHandler<? super R> cancelResultHandler,
+ final boolean sendResult)
+ {
+ Validator.ensureNotNull(reason);
+
+ if (!isCancelSupported)
+ {
+ if (cancelResultHandler != null)
+ {
+ final Result result = Responses
+ .newGenericExtendedResult(ResultCode.CANNOT_CANCEL);
+ cancelResultHandler
+ .handleErrorResult(newErrorResult(result));
+ }
+ return;
+ }
+
+ List<CancelRequestListener> tmpListeners = null;
+ boolean invokeResultHandler = false;
+ boolean resultHandlerIsSuccess = false;
+
+ synchronized (stateLock)
+ {
+ switch (state)
+ {
+ case PENDING:
+ // Switch to CANCEL_REQUESTED state.
+ cancelRequestReason = reason;
+ if (cancelResultHandler != null)
+ {
+ cancelResultHandlers = new LinkedList<ExtendedResultHandlerHolder<?>>();
+ cancelResultHandlers
+ .add(new ExtendedResultHandlerHolder<R>(
+ cancelRequest, cancelResultHandler));
+ }
+ tmpListeners = cancelRequestListeners;
+ cancelRequestListeners = null;
+ state = RequestState.CANCEL_REQUESTED;
+ this.sendResult &= sendResult;
+ break;
+ case CANCEL_REQUESTED:
+ // Cancel already request so listeners already invoked.
+ if (cancelResultHandler != null)
+ {
+ if (cancelResultHandlers == null)
+ {
+ cancelResultHandlers = new LinkedList<ExtendedResultHandlerHolder<?>>();
+ }
+ cancelResultHandlers
+ .add(new ExtendedResultHandlerHolder<R>(
+ cancelRequest, cancelResultHandler));
+ }
+ break;
+ case TOO_LATE:
+ case RESULT_SENT:
+ // Cannot cancel, so invoke result handler immediately outside of
+ // lock.
+ if (cancelResultHandler != null)
+ {
+ invokeResultHandler = true;
+ resultHandlerIsSuccess = false;
+ }
+ break;
+ case CANCELLED:
+ // Multiple cancellation attempts. Clients should not do this, but the
+ // cancel will effectively succeed immediately, so invoke result
+ // handler immediately outside of lock.
+ if (cancelResultHandler != null)
+ {
+ invokeResultHandler = true;
+ resultHandlerIsSuccess = true;
+ }
+ break;
+ }
+ }
+
+ // Invoke listeners outside of lock.
+ if (tmpListeners != null)
+ {
+ for (final CancelRequestListener listener : tmpListeners)
+ {
+ listener.handleCancelRequest(reason);
+ }
+ }
+
+ if (invokeResultHandler)
+ {
+ if (resultHandlerIsSuccess)
+ {
+ final R result = cancelRequest.getResultDecoder()
+ .newExtendedErrorResult(ResultCode.SUCCESS, "", "");
+ cancelResultHandler.handleResult(result);
+ }
+ else
+ {
+ final Result result = Responses
+ .newGenericExtendedResult(ResultCode.TOO_LATE);
+ cancelResultHandler.handleErrorResult(ErrorResultException
+ .newErrorResult(result));
+ }
+ }
+ }
+
+
+
+ /**
+ * Sets the result associated with this request context and updates the
+ * state accordingly.
+ *
+ * @param result
+ * The result.
+ */
+ private boolean setResult(final Result result)
+ {
+ List<ExtendedResultHandlerHolder<?>> tmpHandlers = null;
+ boolean isCancelled = false;
+ boolean maySendResult;
+
+ synchronized (stateLock)
+ {
+ maySendResult = sendResult;
+
+ switch (state)
+ {
+ case PENDING:
+ case TOO_LATE:
+ // Switch to appropriate final state.
+ if (!result.getResultCode().equals(ResultCode.CANCELLED))
+ {
+ state = RequestState.RESULT_SENT;
+ }
+ else
+ {
+ state = RequestState.CANCELLED;
+ }
+ break;
+ case CANCEL_REQUESTED:
+ // Switch to appropriate final state and invoke any cancel request
+ // handlers.
+ if (!result.getResultCode().equals(ResultCode.CANCELLED))
+ {
+ state = RequestState.RESULT_SENT;
+ }
+ else
+ {
+ state = RequestState.CANCELLED;
+ }
+
+ isCancelled = (state == RequestState.CANCELLED);
+ tmpHandlers = cancelResultHandlers;
+ cancelResultHandlers = null;
+ break;
+ case RESULT_SENT:
+ case CANCELLED:
+ // This should not happen - could throw an illegal state exception?
+ maySendResult = false; // Prevent sending multiple results.
+ break;
+ }
+ }
+
+ // Invoke handlers outside of lock.
+ if (tmpHandlers != null)
+ {
+ for (final ExtendedResultHandlerHolder<?> handler : tmpHandlers)
+ {
+ if (isCancelled)
+ {
+ handler.handleSuccess();
+ }
+ else
+ {
+ handler.handleTooLate();
+ }
+ }
+ }
+
+ return maySendResult;
+ }
+ }
+
+
+
+ /**
+ * Search request context implementation.
+ */
+ private final static class SearchRequestContextImpl extends
+ RequestContextImpl<Result, SearchResultHandler> implements
+ SearchResultHandler
+ {
+
+ private SearchRequestContextImpl(
+ final ServerConnectionImpl<?> clientConnection,
+ final SearchResultHandler resultHandler, final int messageID,
+ final boolean isCancelSupported)
+ {
+ super(clientConnection, resultHandler, messageID,
+ isCancelSupported);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean handleEntry(final SearchResultEntry entry)
+ {
+ return resultHandler.handleEntry(entry);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean handleReference(
+ final SearchResultReference reference)
+ {
+ return resultHandler.handleReference(reference);
+ }
+ }
+
+
+
+ private static final class ServerConnectionImpl<C> implements
+ ServerConnection<Integer>
+ {
+ private final RequestHandler<RequestContext> requestHandler;
+
+ private final AtomicBoolean isClosed = new AtomicBoolean();
+
+ private final ConcurrentHashMap<Integer, RequestContextImpl<?, ?>> pendingRequests =
+ new ConcurrentHashMap<Integer, RequestContextImpl<?, ?>>();
+
+
+
+ private ServerConnectionImpl(
+ final RequestHandler<RequestContext> requestHandler)
+ {
+ this.requestHandler = requestHandler;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleAbandon(final Integer messageID,
+ final AbandonRequest request)
+ throws UnsupportedOperationException
+ {
+ final RequestContextImpl<?, ?> abandonedRequest = getPendingRequest(request
+ .getRequestID());
+ if (abandonedRequest != null)
+ {
+ final LocalizableMessage abandonReason = INFO_CANCELED_BY_ABANDON_REQUEST
+ .get(messageID);
+ abandonedRequest.cancel(abandonReason, null, null, false);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleAdd(final Integer messageID,
+ final AddRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ final RequestContextImpl<Result, ResultHandler<? super Result>> requestContext =
+ new RequestContextImpl<Result, ResultHandler<? super Result>>(
+ this, resultHandler, messageID, true);
+ if (addPendingRequest(requestContext))
+ {
+ requestHandler.handleAdd(requestContext, request,
+ requestContext, intermediateResponseHandler);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleBind(final Integer messageID,
+ final int version, final BindRequest request,
+ final ResultHandler<? super BindResult> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ final RequestContextImpl<BindResult, ResultHandler<? super BindResult>> requestContext =
+ new RequestContextImpl<BindResult, ResultHandler<? super BindResult>>(
+ this, resultHandler, messageID, false);
+ if (addPendingRequest(requestContext))
+ {
+ requestHandler.handleBind(requestContext, version, request,
+ requestContext, intermediateResponseHandler);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleCompare(final Integer messageID,
+ final CompareRequest request,
+ final ResultHandler<? super CompareResult> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ final RequestContextImpl<CompareResult, ResultHandler<? super CompareResult>> requestContext =
+ new RequestContextImpl<CompareResult, ResultHandler<? super CompareResult>>(
+ this, resultHandler, messageID, true);
+ if (addPendingRequest(requestContext))
+ {
+ requestHandler.handleCompare(requestContext, request,
+ requestContext, intermediateResponseHandler);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleConnectionClosed(final Integer messageID,
+ final UnbindRequest request)
+ {
+ final LocalizableMessage cancelReason = INFO_CANCELED_BY_CLIENT_DISCONNECT
+ .get();
+ doClose(cancelReason);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleConnectionDisconnected(
+ final ResultCode resultCode, final String message)
+ {
+ final LocalizableMessage cancelReason = INFO_CANCELED_BY_SERVER_DISCONNECT
+ .get();
+ doClose(cancelReason);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleConnectionError(final Throwable error)
+ {
+ final LocalizableMessage cancelReason = INFO_CANCELED_BY_CLIENT_ERROR
+ .get();
+ doClose(cancelReason);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleDelete(final Integer messageID,
+ final DeleteRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ final RequestContextImpl<Result, ResultHandler<? super Result>> requestContext =
+ new RequestContextImpl<Result, ResultHandler<? super Result>>(
+ this, resultHandler, messageID, true);
+ if (addPendingRequest(requestContext))
+ {
+ requestHandler.handleDelete(requestContext, request,
+ requestContext, intermediateResponseHandler);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <R extends ExtendedResult> void handleExtendedRequest(
+ final Integer messageID, final ExtendedRequest<R> request,
+ final ResultHandler<? super R> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ if (request.getOID().equals(CancelExtendedRequest.OID))
+ {
+ // Decode the request as a cancel request.
+ CancelExtendedRequest cancelRequest;
+ try
+ {
+ cancelRequest = CancelExtendedRequest.DECODER
+ .decodeExtendedRequest(request, new DecodeOptions());
+ }
+ catch (final DecodeException e)
+ {
+ // Couldn't decode a cancel request.
+ resultHandler.handleErrorResult(newErrorResult(
+ ResultCode.PROTOCOL_ERROR, e.getLocalizedMessage()));
+ return;
+ }
+
+ // Register the request in the pending requests table. Even though
+ // this request cannot be cancelled, it is important to do this in
+ // order to monitor the number of pending operations.
+ final RequestContextImpl<R, ResultHandler<? super R>> requestContext =
+ new RequestContextImpl<R, ResultHandler<? super R>>(
+ this, resultHandler, messageID, false);
+ if (addPendingRequest(requestContext))
+ {
+ // Find and cancel the request.
+ final RequestContextImpl<?, ?> cancelledRequest = getPendingRequest(cancelRequest
+ .getRequestID());
+ if (cancelledRequest != null)
+ {
+ final LocalizableMessage cancelReason = INFO_CANCELED_BY_CANCEL_REQUEST
+ .get(messageID);
+ cancelledRequest.cancel(cancelReason, request,
+ requestContext, true);
+ }
+ else
+ {
+ // Couldn't find the request. Invoke on context in order to remove
+ // pending request.
+ requestContext
+ .handleErrorResult(newErrorResult(ResultCode.NO_SUCH_OPERATION));
+ }
+ }
+ }
+ else
+ {
+ final RequestContextImpl<R, ResultHandler<? super R>> requestContext;
+ if (request.getOID().equals(StartTLSExtendedRequest.OID))
+ {
+ // StartTLS requests cannot be cancelled.
+ requestContext = new RequestContextImpl<R, ResultHandler<? super R>>(
+ this, resultHandler, messageID, false);
+ }
+ else
+ {
+ requestContext = new RequestContextImpl<R, ResultHandler<? super R>>(
+ this, resultHandler, messageID, true);
+ }
+
+ if (addPendingRequest(requestContext))
+ {
+ requestHandler.handleExtendedRequest(requestContext,
+ request, requestContext, intermediateResponseHandler);
+ }
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleModify(final Integer messageID,
+ final ModifyRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ final RequestContextImpl<Result, ResultHandler<? super Result>> requestContext =
+ new RequestContextImpl<Result, ResultHandler<? super Result>>(
+ this, resultHandler, messageID, true);
+ if (addPendingRequest(requestContext))
+ {
+ requestHandler.handleModify(requestContext, request,
+ requestContext, intermediateResponseHandler);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleModifyDN(final Integer messageID,
+ final ModifyDNRequest request,
+ final ResultHandler<? super Result> resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ final RequestContextImpl<Result, ResultHandler<? super Result>> requestContext =
+ new RequestContextImpl<Result, ResultHandler<? super Result>>(
+ this, resultHandler, messageID, true);
+ if (addPendingRequest(requestContext))
+ {
+ requestHandler.handleModifyDN(requestContext, request,
+ requestContext, intermediateResponseHandler);
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleSearch(final Integer messageID,
+ final SearchRequest request,
+ final SearchResultHandler resultHandler,
+ final IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException
+ {
+ final SearchRequestContextImpl requestContext = new SearchRequestContextImpl(
+ this, resultHandler, messageID, true);
+ if (addPendingRequest(requestContext))
+ {
+ requestHandler.handleSearch(requestContext, request,
+ requestContext, intermediateResponseHandler);
+ }
+ }
+
+
+
+ private boolean addPendingRequest(
+ final RequestContextImpl<?, ?> requestContext)
+ {
+ final Integer messageID = requestContext.getMessageID();
+
+ if (isClosed.get())
+ {
+ final LocalizableMessage message = INFO_CLIENT_CONNECTION_CLOSING
+ .get();
+ requestContext.handleErrorResult(newErrorResult(
+ ResultCode.UNWILLING_TO_PERFORM, message.toString()));
+ return false;
+ }
+ else if (pendingRequests.putIfAbsent(messageID, requestContext) != null)
+ {
+ final LocalizableMessage message = WARN_CLIENT_DUPLICATE_MESSAGE_ID
+ .get(requestContext.getMessageID());
+ requestContext.handleErrorResult(newErrorResult(
+ ResultCode.PROTOCOL_ERROR, message.toString()));
+ return false;
+ }
+ else if (isClosed.get())
+ {
+ // A concurrent close may have already removed the pending request but
+ // it will have only been notified for cancellation.
+ pendingRequests.remove(messageID);
+
+ final LocalizableMessage message = INFO_CLIENT_CONNECTION_CLOSING
+ .get();
+ requestContext.handleErrorResult(newErrorResult(
+ ResultCode.UNWILLING_TO_PERFORM, message.toString()));
+ return false;
+ }
+ else
+ {
+ // If the connection is closed now then we just have to pay the cost of
+ // invoking the request in the request handler.
+ return true;
+ }
+ }
+
+
+
+ private void doClose(final LocalizableMessage cancelReason)
+ {
+ if (!isClosed.getAndSet(true))
+ {
+ // At this point if any pending requests are added then we may end up
+ // cancelling them, but this does not matter since addPendingRequest
+ // will fail the request immediately.
+ final Iterator<RequestContextImpl<?, ?>> iterator = pendingRequests
+ .values().iterator();
+ while (iterator.hasNext())
+ {
+ final RequestContextImpl<?, ?> pendingRequest = iterator
+ .next();
+ pendingRequest.cancel(cancelReason, null, null, false);
+ iterator.remove();
+ }
+ }
+ }
+
+
+
+ /**
+ * Returns the pending request context having the specified message ID.
+ *
+ * @param messageID
+ * The message ID associated with the request context.
+ * @return The pending request context.
+ */
+ private RequestContextImpl<?, ?> getPendingRequest(
+ final Integer messageID)
+ {
+ return pendingRequests.get(messageID);
+ }
+
+
+
+ /**
+ * Deregister a request context once it has completed.
+ *
+ * @param requestContext
+ * The request context.
+ * @return {@code true} if the request context was found and removed.
+ */
+ private boolean removePendingRequest(
+ final RequestContextImpl<?, ?> requestContext)
+ {
+ return pendingRequests.remove(requestContext.getMessageID()) != null;
+ }
+
+ }
+
+
+
+ private final RequestHandlerFactory<C, RequestContext> factory;
+
+
+
+ /**
+ * Creates a new server connection factory using the provided request handler
+ * factory.
+ *
+ * @param factory
+ * The request handler factory to be adapted into a server connection
+ * factory.
+ */
+ RequestHandlerFactoryAdapter(
+ final RequestHandlerFactory<C, RequestContext> factory)
+ {
+ this.factory = factory;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ServerConnection<Integer> handleAccept(final C clientContext)
+ throws ErrorResultException
+ {
+ final RequestHandler<RequestContext> requestHandler = factory
+ .handleAccept(clientContext);
+ return new ServerConnectionImpl<C>(requestHandler);
+ }
+
+}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/CRAMMD5SASLBindRequestImpl.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/CRAMMD5SASLBindRequestImpl.java
index d40afe2..6fcadb0 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/CRAMMD5SASLBindRequestImpl.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/CRAMMD5SASLBindRequestImpl.java
@@ -29,6 +29,8 @@
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
+
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
@@ -85,8 +87,7 @@
}
catch (final SaslException e)
{
- throw ErrorResultException.wrap(Responses.newResult(
- ResultCode.CLIENT_SIDE_LOCAL_ERROR).setCause(e));
+ throw newErrorResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR, e);
}
}
@@ -122,7 +123,7 @@
{
// FIXME: I18N need to have a better error message.
// FIXME: Is this the best result code?
- throw ErrorResultException.wrap(Responses.newResult(
+ throw ErrorResultException.newErrorResult(Responses.newResult(
ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
"An error occurred during multi-stage authentication")
.setCause(e));
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/DigestMD5SASLBindRequestImpl.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/DigestMD5SASLBindRequestImpl.java
index ccc4ed5..3dae736 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/DigestMD5SASLBindRequestImpl.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/DigestMD5SASLBindRequestImpl.java
@@ -32,6 +32,7 @@
import static com.forgerock.opendj.util.StaticUtils.getExceptionMessage;
import static com.forgerock.opendj.util.StaticUtils.joinCollection;
import static org.forgerock.opendj.ldap.CoreMessages.ERR_SASL_PROTOCOL_ERROR;
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
import java.util.*;
@@ -49,7 +50,6 @@
import org.forgerock.opendj.ldap.ErrorResultException;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.responses.BindResult;
-import org.forgerock.opendj.ldap.responses.Responses;
import com.forgerock.opendj.util.Validator;
@@ -154,8 +154,7 @@
}
catch (final SaslException e)
{
- throw ErrorResultException.wrap(Responses.newResult(
- ResultCode.CLIENT_SIDE_LOCAL_ERROR).setCause(e));
+ throw newErrorResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR, e);
}
}
@@ -191,11 +190,8 @@
{
// 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));
+ throw newErrorResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR,
+ "An error occurred during multi-stage authentication", e);
}
}
@@ -229,9 +225,8 @@
{
final LocalizableMessage msg = ERR_SASL_PROTOCOL_ERROR.get(
SASL_MECHANISM_NAME, getExceptionMessage(e));
- throw ErrorResultException.wrap(Responses
- .newResult(ResultCode.CLIENT_SIDE_DECODING_ERROR)
- .setDiagnosticMessage(msg.toString()).setCause(e));
+ throw newErrorResult(ResultCode.CLIENT_SIDE_DECODING_ERROR,
+ msg.toString(), e);
}
}
@@ -249,9 +244,8 @@
{
final LocalizableMessage msg = ERR_SASL_PROTOCOL_ERROR.get(
SASL_MECHANISM_NAME, getExceptionMessage(e));
- throw ErrorResultException.wrap(Responses
- .newResult(ResultCode.CLIENT_SIDE_ENCODING_ERROR)
- .setDiagnosticMessage(msg.toString()).setCause(e));
+ throw newErrorResult(ResultCode.CLIENT_SIDE_ENCODING_ERROR,
+ msg.toString(), e);
}
}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/ExternalSASLBindRequestImpl.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/ExternalSASLBindRequestImpl.java
index b815c75..654f715 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/ExternalSASLBindRequestImpl.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/ExternalSASLBindRequestImpl.java
@@ -29,6 +29,8 @@
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
+
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
@@ -76,8 +78,7 @@
}
catch (final SaslException e)
{
- throw ErrorResultException.wrap(Responses.newResult(
- ResultCode.CLIENT_SIDE_LOCAL_ERROR).setCause(e));
+ throw newErrorResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR, e);
}
}
@@ -113,7 +114,7 @@
{
// FIXME: I18N need to have a better error message.
// FIXME: Is this the best result code?
- throw ErrorResultException.wrap(Responses.newResult(
+ throw ErrorResultException.newErrorResult(Responses.newResult(
ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
"An error occurred during multi-stage authentication")
.setCause(e));
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/GSSAPISASLBindRequestImpl.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/GSSAPISASLBindRequestImpl.java
index c3cb540..86f741d 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/GSSAPISASLBindRequestImpl.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/GSSAPISASLBindRequestImpl.java
@@ -32,6 +32,7 @@
import static com.forgerock.opendj.util.StaticUtils.getExceptionMessage;
import static com.forgerock.opendj.util.StaticUtils.joinCollection;
import static org.forgerock.opendj.ldap.CoreMessages.*;
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
@@ -61,6 +62,7 @@
/**
* GSSAPI SASL bind request implementation.
*/
+@SuppressWarnings("restriction")
final class GSSAPISASLBindRequestImpl extends
AbstractSASLBindRequest<GSSAPISASLBindRequest> implements
GSSAPISASLBindRequest
@@ -75,7 +77,7 @@
{
// FIXME: I18N need to have a better error message.
// FIXME: Is this the best result code?
- throw ErrorResultException.wrap(Responses.newResult(
+ throw ErrorResultException.newErrorResult(Responses.newResult(
ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
"No authentication ID specified for GSSAPI SASL authentication"));
}
@@ -84,7 +86,7 @@
{
// FIXME: I18N need to have a better error message.
// FIXME: Is this the best result code?
- throw ErrorResultException.wrap(Responses.newResult(
+ throw ErrorResultException.newErrorResult(Responses.newResult(
ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
"No password specified for GSSAPI SASL authentication"));
}
@@ -119,7 +121,7 @@
// FIXME: Is this the best result code?
final LocalizableMessage message = ERR_LDAPAUTH_GSSAPI_LOCAL_AUTHENTICATION_FAILED
.get(StaticUtils.getExceptionMessage(e));
- throw ErrorResultException.wrap(Responses
+ throw ErrorResultException.newErrorResult(Responses
.newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR)
.setDiagnosticMessage(message.toString()).setCause(e));
}
@@ -151,7 +153,7 @@
{
// FIXME: I18N need to have a better error message.
// FIXME: Is this the best result code?
- throw ErrorResultException.wrap(Responses
+ throw ErrorResultException.newErrorResult(Responses
.newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR)
.setDiagnosticMessage(
"An error occurred during multi-stage authentication")
@@ -239,8 +241,7 @@
}
catch (final SaslException e)
{
- throw ErrorResultException.wrap(Responses.newResult(
- ResultCode.CLIENT_SIDE_LOCAL_ERROR).setCause(e));
+ throw newErrorResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR, e);
}
}
});
@@ -254,11 +255,10 @@
else
{
// This should not happen. Must be a bug.
- final LocalizableMessage msg = ERR_SASL_CONTEXT_CREATE_ERROR.get(
- SASL_MECHANISM_NAME, getExceptionMessage(e));
- throw ErrorResultException.wrap(Responses
- .newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR)
- .setDiagnosticMessage(msg.toString()).setCause(e));
+ final LocalizableMessage msg = ERR_SASL_CONTEXT_CREATE_ERROR
+ .get(SASL_MECHANISM_NAME, getExceptionMessage(e));
+ throw newErrorResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR,
+ msg.toString(), e);
}
}
}
@@ -300,9 +300,8 @@
// This should not happen. Must be a bug.
final LocalizableMessage msg = ERR_SASL_PROTOCOL_ERROR.get(
SASL_MECHANISM_NAME, getExceptionMessage(e));
- throw ErrorResultException.wrap(Responses
- .newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR)
- .setDiagnosticMessage(msg.toString()).setCause(e));
+ throw newErrorResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR,
+ msg.toString(), e);
}
}
}
@@ -337,9 +336,8 @@
{
final LocalizableMessage msg = ERR_SASL_PROTOCOL_ERROR.get(
SASL_MECHANISM_NAME, getExceptionMessage(e));
- throw ErrorResultException.wrap(Responses
- .newResult(ResultCode.CLIENT_SIDE_DECODING_ERROR)
- .setDiagnosticMessage(msg.toString()).setCause(e));
+ throw newErrorResult(ResultCode.CLIENT_SIDE_DECODING_ERROR,
+ msg.toString(), e);
}
}
@@ -357,9 +355,8 @@
{
final LocalizableMessage msg = ERR_SASL_PROTOCOL_ERROR.get(
SASL_MECHANISM_NAME, getExceptionMessage(e));
- throw ErrorResultException.wrap(Responses
- .newResult(ResultCode.CLIENT_SIDE_ENCODING_ERROR)
- .setDiagnosticMessage(msg.toString()).setCause(e));
+ throw newErrorResult(ResultCode.CLIENT_SIDE_ENCODING_ERROR,
+ msg.toString(), e);
}
}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/PlainSASLBindRequestImpl.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/PlainSASLBindRequestImpl.java
index 9c3c64d..3732b8a 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/PlainSASLBindRequestImpl.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/requests/PlainSASLBindRequestImpl.java
@@ -29,6 +29,8 @@
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
+
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
@@ -40,7 +42,6 @@
import org.forgerock.opendj.ldap.ErrorResultException;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.responses.BindResult;
-import org.forgerock.opendj.ldap.responses.Responses;
import com.forgerock.opendj.util.Validator;
@@ -87,8 +88,7 @@
}
catch (final SaslException e)
{
- throw ErrorResultException.wrap(Responses.newResult(
- ResultCode.CLIENT_SIDE_LOCAL_ERROR).setCause(e));
+ throw newErrorResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR, e);
}
}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/responses/AbstractExtendedResultDecoder.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/responses/AbstractExtendedResultDecoder.java
index 3dc865d..07b19b6 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/responses/AbstractExtendedResultDecoder.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/responses/AbstractExtendedResultDecoder.java
@@ -29,6 +29,8 @@
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
+
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.ExtendedRequest;
@@ -89,8 +91,7 @@
.newExtendedErrorResult(result.getResultCode(),
result.getMatchedDN(), result.getDiagnosticMessage());
adaptedResult.setCause(result.getCause());
- resultHandler.handleErrorResult(ErrorResultException
- .wrap(adaptedResult));
+ resultHandler.handleErrorResult(newErrorResult(adaptedResult));
}
@@ -108,8 +109,7 @@
{
final R adaptedResult = request.getResultDecoder()
.adaptDecodeException(e);
- resultHandler.handleErrorResult(ErrorResultException
- .wrap(adaptedResult));
+ resultHandler.handleErrorResult(newErrorResult(adaptedResult));
}
}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java
index 501e926..6a2d2b9 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java
@@ -29,6 +29,7 @@
import static org.forgerock.opendj.ldap.CoreMessages.*;
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
import java.util.Collection;
import java.util.Collections;
@@ -40,8 +41,6 @@
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.requests.SearchRequest;
-import org.forgerock.opendj.ldap.responses.Responses;
-import org.forgerock.opendj.ldap.responses.Result;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
import com.forgerock.opendj.util.FutureResultTransformer;
@@ -1829,10 +1828,10 @@
if (subentryAttr == null || subentryAttr.isEmpty())
{
// Did not get the subschema sub-entry attribute.
- final Result result = Responses.newResult(
- ResultCode.CLIENT_SIDE_NO_RESULTS_RETURNED).setDiagnosticMessage(
- ERR_NO_SUBSCHEMA_SUBENTRY_ATTR.get(name.toString()).toString());
- throw ErrorResultException.wrap(result);
+ throw newErrorResult(
+ ResultCode.CLIENT_SIDE_NO_RESULTS_RETURNED,
+ ERR_NO_SUBSCHEMA_SUBENTRY_ATTR.get(name.toString())
+ .toString());
}
final String dnString = subentryAttr.iterator().next().toString();
@@ -1843,11 +1842,10 @@
}
catch (final LocalizedIllegalArgumentException e)
{
- final Result result = Responses.newResult(
- ResultCode.CLIENT_SIDE_NO_RESULTS_RETURNED).setDiagnosticMessage(
- ERR_INVALID_SUBSCHEMA_SUBENTRY_ATTR.get(name.toString(), dnString,
- e.getMessageObject()).toString());
- throw ErrorResultException.wrap(result);
+ throw newErrorResult(
+ ResultCode.CLIENT_SIDE_NO_RESULTS_RETURNED,
+ ERR_INVALID_SUBSCHEMA_SUBENTRY_ATTR.get(name.toString(),
+ dnString, e.getMessageObject()).toString());
}
return subschemaDN;
}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryReader.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryReader.java
index 34c1f94..b1029ab 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryReader.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/ConnectionEntryReader.java
@@ -29,6 +29,8 @@
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
+
import java.io.InterruptedIOException;
import java.util.NoSuchElementException;
import java.util.concurrent.BlockingQueue;
@@ -273,8 +275,7 @@
return false;
}
- final ErrorResultException e = ErrorResultException.wrap(result);
- throw new ErrorResultIOException(e);
+ throw new ErrorResultIOException(newErrorResult(result));
}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/resources/org/forgerock/opendj/ldap/core.properties b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/resources/org/forgerock/opendj/ldap/core.properties
index 4556fe9..d8a6561 100755
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/resources/org/forgerock/opendj/ldap/core.properties
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/resources/org/forgerock/opendj/ldap/core.properties
@@ -1269,6 +1269,22 @@
contained the OID '%s', when '%s' was expected
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 operation was rejected because there is \
+ already 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 has disconnected from the server
+INFO_CANCELED_BY_SERVER_DISCONNECT=The operation was canceled because the \
+ server has disconnected from the client
+INFO_CANCELED_BY_CLIENT_ERROR=The operation was canceled because the \
+ client connection failed
+INFO_CLIENT_CONNECTION_CLOSING=The operation was rejected because the \
+ client connection is closing
+
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java
index 11ea51c..a98ce81 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPListenerTestCase.java
@@ -223,7 +223,7 @@
throws UnsupportedOperationException
{
resultHandler
- .handleErrorResult(ErrorResultException.wrap(request
+ .handleErrorResult(ErrorResultException.newErrorResult(request
.getResultDecoder().newExtendedErrorResult(
ResultCode.PROTOCOL_ERROR, "",
"Extended operation " + request.getOID() + " not supported")));
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java
index 46def3d..322f95d 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPServer.java
@@ -200,7 +200,7 @@
{
// duplicate entry.
result = Responses.newResult(ResultCode.ENTRY_ALREADY_EXISTS);
- final ErrorResultException ere = ErrorResultException.wrap(result);
+ final ErrorResultException ere = ErrorResultException.newErrorResult(result);
handler.handleErrorResult(ere);
// doesn't matter if it was canceled.
requestsInProgress.remove(context);
@@ -222,7 +222,7 @@
if (abReq.isCanceled())
{
result = Responses.newResult(ResultCode.CANCELLED);
- final ErrorResultException ere = ErrorResultException.wrap(result);
+ final ErrorResultException ere = ErrorResultException.newErrorResult(result);
handler.handleErrorResult(ere);
requestsInProgress.remove(context);
return;
@@ -349,7 +349,7 @@
}
catch (SaslException e)
{
- throw ErrorResultException.wrap(Responses.newResult(
+ throw ErrorResultException.newErrorResult(Responses.newResult(
ResultCode.OPERATIONS_ERROR).setCause(e));
}
}
@@ -365,7 +365,7 @@
}
catch (SaslException e)
{
- throw ErrorResultException.wrap(Responses.newResult(
+ throw ErrorResultException.newErrorResult(Responses.newResult(
ResultCode.OPERATIONS_ERROR).setCause(e));
}
}
@@ -384,7 +384,7 @@
}
catch (Exception e)
{
- resultHandler.handleErrorResult(ErrorResultException.wrap(Responses
+ resultHandler.handleErrorResult(ErrorResultException.newErrorResult(Responses
.newBindResult(ResultCode.OPERATIONS_ERROR).setCause(e)
.setDiagnosticMessage(e.toString())));
}
@@ -469,7 +469,7 @@
{
// entry not found.
result = Responses.newCompareResult(ResultCode.NO_SUCH_ATTRIBUTE);
- final ErrorResultException ere = ErrorResultException.wrap(result);
+ final ErrorResultException ere = ErrorResultException.newErrorResult(result);
resultHandler.handleErrorResult(ere);
// doesn't matter if it was canceled.
requestsInProgress.remove(context);
@@ -488,7 +488,7 @@
if (abReq.isCanceled())
{
final Result r = Responses.newResult(ResultCode.CANCELLED);
- final ErrorResultException ere = ErrorResultException.wrap(r);
+ final ErrorResultException ere = ErrorResultException.newErrorResult(r);
resultHandler.handleErrorResult(ere);
requestsInProgress.remove(context);
return;
@@ -529,7 +529,7 @@
{
// entry is not found.
result = Responses.newResult(ResultCode.NO_SUCH_OBJECT);
- final ErrorResultException ere = ErrorResultException.wrap(result);
+ final ErrorResultException ere = ErrorResultException.newErrorResult(result);
handler.handleErrorResult(ere);
// doesn't matter if it was canceled.
requestsInProgress.remove(context);
@@ -539,7 +539,7 @@
if (abReq.isCanceled())
{
result = Responses.newResult(ResultCode.CANCELLED);
- final ErrorResultException ere = ErrorResultException.wrap(result);
+ final ErrorResultException ere = ErrorResultException.newErrorResult(result);
handler.handleErrorResult(ere);
requestsInProgress.remove(context);
return;
@@ -633,7 +633,7 @@
{
// Entry not found.
result = Responses.newResult(ResultCode.NO_SUCH_OBJECT);
- final ErrorResultException ere = ErrorResultException.wrap(result);
+ final ErrorResultException ere = ErrorResultException.newErrorResult(result);
resultHandler.handleErrorResult(ere);
// Should searchResultHandler handle anything?
@@ -645,7 +645,7 @@
if (abReq.isCanceled())
{
result = Responses.newResult(ResultCode.CANCELLED);
- final ErrorResultException ere = ErrorResultException.wrap(result);
+ final ErrorResultException ere = ErrorResultException.newErrorResult(result);
resultHandler.handleErrorResult(ere);
requestsInProgress.remove(context);
return;
diff --git a/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java b/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java
index 3cea6f2..e116bae 100644
--- a/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java
+++ b/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java
@@ -32,6 +32,7 @@
import static com.forgerock.opendj.ldap.tools.ToolsMessages.*;
import static com.forgerock.opendj.ldap.tools.ToolConstants.*;
import static com.forgerock.opendj.ldap.tools.Utils.filterExitCode;
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
import java.io.*;
import java.util.ArrayList;
@@ -44,7 +45,6 @@
import org.forgerock.opendj.ldap.controls.ProxiedAuthV2RequestControl;
import org.forgerock.opendj.ldap.requests.CompareRequest;
import org.forgerock.opendj.ldap.requests.Requests;
-import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
import com.forgerock.opendj.util.Base64;
@@ -229,9 +229,8 @@
{
// This shouldn't happen because there are no other threads to
// interrupt this one.
- result = Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED)
- .setCause(e).setDiagnosticMessage(e.getLocalizedMessage());
- throw ErrorResultException.wrap(result);
+ throw newErrorResult(ResultCode.CLIENT_SIDE_USER_CANCELLED,
+ e.getLocalizedMessage(), e);
}
if (result.getResultCode() == ResultCode.COMPARE_FALSE)
diff --git a/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPModify.java b/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPModify.java
index 347637c..598df04 100644
--- a/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPModify.java
+++ b/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPModify.java
@@ -32,6 +32,7 @@
import static com.forgerock.opendj.ldap.tools.ToolsMessages.*;
import static com.forgerock.opendj.ldap.tools.ToolConstants.*;
import static com.forgerock.opendj.ldap.tools.Utils.filterExitCode;
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
import java.io.FileInputStream;
import java.io.IOException;
@@ -50,7 +51,6 @@
import org.forgerock.opendj.ldap.requests.DeleteRequest;
import org.forgerock.opendj.ldap.requests.ModifyDNRequest;
import org.forgerock.opendj.ldap.requests.ModifyRequest;
-import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
import org.forgerock.opendj.ldif.*;
@@ -87,9 +87,9 @@
{
// This shouldn't happen because there are no other threads
// to interrupt this one.
- r = Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED)
- .setCause(e).setDiagnosticMessage(e.getLocalizedMessage());
- throw ErrorResultException.wrap(r);
+ throw newErrorResult(
+ ResultCode.CLIENT_SIDE_USER_CANCELLED,
+ e.getLocalizedMessage(), e);
}
printResult(opType, change.getName().toString(), r);
return r.getResultCode().intValue();
@@ -127,9 +127,8 @@
{
// This shouldn't happen because there are no other threads
// to interrupt this one.
- r = Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED)
- .setCause(e).setDiagnosticMessage(e.getLocalizedMessage());
- throw ErrorResultException.wrap(r);
+ throw newErrorResult(ResultCode.CLIENT_SIDE_USER_CANCELLED,
+ e.getLocalizedMessage(), e);
}
printResult(opType, change.getName().toString(), r);
return r.getResultCode().intValue();
@@ -167,9 +166,8 @@
{
// This shouldn't happen because there are no other threads
// to interrupt this one.
- r = Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED)
- .setCause(e).setDiagnosticMessage(e.getLocalizedMessage());
- throw ErrorResultException.wrap(r);
+ throw newErrorResult(ResultCode.CLIENT_SIDE_USER_CANCELLED,
+ e.getLocalizedMessage(), e);
}
printResult(opType, change.getName().toString(), r);
return r.getResultCode().intValue();
@@ -207,9 +205,8 @@
{
// This shouldn't happen because there are no other threads
// to interrupt this one.
- r = Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED)
- .setCause(e).setDiagnosticMessage(e.getLocalizedMessage());
- throw ErrorResultException.wrap(r);
+ throw newErrorResult(ResultCode.CLIENT_SIDE_USER_CANCELLED,
+ e.getLocalizedMessage(), e);
}
printResult(opType, change.getName().toString(), r);
return r.getResultCode().intValue();
diff --git a/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPPasswordModify.java b/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPPasswordModify.java
index f872bec..04fc6de 100644
--- a/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPPasswordModify.java
+++ b/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPPasswordModify.java
@@ -32,6 +32,7 @@
import static com.forgerock.opendj.ldap.tools.ToolsMessages.*;
import static com.forgerock.opendj.ldap.tools.ToolConstants.*;
import static com.forgerock.opendj.ldap.tools.Utils.filterExitCode;
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
import java.io.InputStream;
import java.io.OutputStream;
@@ -42,7 +43,6 @@
import org.forgerock.opendj.ldap.requests.PasswordModifyExtendedRequest;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.responses.PasswordModifyExtendedResult;
-import org.forgerock.opendj.ldap.responses.Responses;
@@ -446,10 +446,8 @@
{
// This shouldn't happen because there are no other threads to
// interrupt this one.
- result = Responses.newPasswordModifyExtendedResult(
- ResultCode.CLIENT_SIDE_USER_CANCELLED).setCause(e)
- .setDiagnosticMessage(e.getLocalizedMessage());
- throw ErrorResultException.wrap(result);
+ throw newErrorResult(ResultCode.CLIENT_SIDE_USER_CANCELLED,
+ e.getLocalizedMessage(), e);
}
}
catch (final ErrorResultException e)
diff --git a/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPSearch.java b/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPSearch.java
index cd58570..9aa4952 100644
--- a/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPSearch.java
+++ b/opendj-sdk/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPSearch.java
@@ -32,6 +32,7 @@
import static com.forgerock.opendj.ldap.tools.ToolsMessages.*;
import static com.forgerock.opendj.ldap.tools.ToolConstants.*;
import static com.forgerock.opendj.ldap.tools.Utils.filterExitCode;
+import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult;
import java.io.*;
import java.util.*;
@@ -42,7 +43,6 @@
import org.forgerock.opendj.ldap.controls.*;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.requests.SearchRequest;
-import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
import org.forgerock.opendj.ldap.responses.SearchResultReference;
@@ -1168,9 +1168,8 @@
{
// This shouldn't happen because there are no other threads to
// interrupt this one.
- result = Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED)
- .setCause(e).setDiagnosticMessage(e.getLocalizedMessage());
- throw ErrorResultException.wrap(result);
+ throw newErrorResult(ResultCode.CLIENT_SIDE_USER_CANCELLED,
+ e.getLocalizedMessage(), e);
}
try
--
Gitblit v1.10.0