From ff1e5d33d24b8ec9393e9262be0fdce1213352b4 Mon Sep 17 00:00:00 2001
From: Ludovic Poitou <ludovic.poitou@forgerock.com>
Date: Thu, 14 Oct 2010 16:15:50 +0000
Subject: [PATCH] Commit from OpenDS, matthew_swift * add unit tests for ConnectionEventListeners.
---
/dev/null | 82 --
opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LDAPListenerTestCase.java | 230 ++++++
opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java | 315 --------
opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java | 50
opendj-sdk/sdk/src/org/opends/sdk/RoundRobinLoadBalancingAlgorithm.java | 52
opendj-sdk/sdk/src/com/sun/opends/sdk/util/AsynchronousConnectionDecorator.java | 508 +++++++++++++
opendj-sdk/sdk/src/com/sun/opends/sdk/tools/AuthenticatedConnectionFactory.java | 310 -------
opendj-sdk/sdk/src/org/opends/sdk/AbstractLoadBalancingAlgorithm.java | 62
opendj-sdk/sdk/src/org/opends/sdk/Connections.java | 123 ++
opendj-sdk/sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java | 532 +++----------
10 files changed, 1,081 insertions(+), 1,183 deletions(-)
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/AuthenticatedConnectionFactory.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/AuthenticatedConnectionFactory.java
index f66b335..6dcf1ea 100644
--- a/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/AuthenticatedConnectionFactory.java
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/tools/AuthenticatedConnectionFactory.java
@@ -29,13 +29,11 @@
-import java.util.Collection;
-
import org.opends.sdk.*;
-import org.opends.sdk.requests.*;
-import org.opends.sdk.responses.*;
-import org.opends.sdk.schema.Schema;
+import org.opends.sdk.requests.BindRequest;
+import org.opends.sdk.responses.BindResult;
+import com.sun.opends.sdk.util.AsynchronousConnectionDecorator;
import com.sun.opends.sdk.util.FutureResultTransformer;
import com.sun.opends.sdk.util.RecursiveFutureResult;
import com.sun.opends.sdk.util.Validator;
@@ -70,69 +68,27 @@
* An authenticated asynchronous connection supports all operations except
* Bind operations.
*/
- public static final class AuthenticatedAsynchronousConnection implements
- AsynchronousConnection
+ public static final class AuthenticatedAsynchronousConnection extends
+ AsynchronousConnectionDecorator
{
private final BindRequest request;
private volatile BindResult result;
- private final AsynchronousConnection connection;
-
private AuthenticatedAsynchronousConnection(
final AsynchronousConnection connection, final BindRequest request,
final BindResult result)
{
- this.connection = connection;
+ super(connection);
this.request = request;
this.result = result;
}
- public FutureResult<Void> abandon(final AbandonRequest request)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.abandon(request);
- }
-
-
-
- public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<? super Result> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.add(request, handler);
- }
-
-
-
- public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection
- .add(request, resultHandler, intermediateResponseHandler);
- }
-
-
-
- public void addConnectionEventListener(
- final ConnectionEventListener listener) throws IllegalStateException,
- NullPointerException
- {
- connection.addConnectionEventListener(listener);
- }
-
-
-
/**
* Bind operations are not supported by pre-authenticated connections. This
* method will always throw {@code UnsupportedOperationException}.
@@ -147,96 +103,17 @@
+ /**
+ * Bind operations are not supported by pre-authenticated connections. This
+ * method will always throw {@code UnsupportedOperationException}.
+ */
public FutureResult<BindResult> bind(final BindRequest request,
final ResultHandler<? super BindResult> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
- return connection.bind(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- public void close()
- {
- connection.close();
- }
-
-
-
- public void close(final UnbindRequest request, final String reason)
- throws NullPointerException
- {
- connection.close(request, reason);
- }
-
-
-
- public FutureResult<CompareResult> compare(final CompareRequest request,
- final ResultHandler<? super CompareResult> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.compare(request, handler);
- }
-
-
-
- public FutureResult<CompareResult> compare(final CompareRequest request,
- final ResultHandler<? super CompareResult> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.compare(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<? super Result> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.delete(request, handler);
- }
-
-
-
- public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.delete(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- public <R extends ExtendedResult> FutureResult<R> extendedRequest(
- final ExtendedRequest<R> request, final ResultHandler<? super R> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.extendedRequest(request, handler);
- }
-
-
-
- public <R extends ExtendedResult> FutureResult<R> extendedRequest(
- final ExtendedRequest<R> request,
- final ResultHandler<? super R> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.extendedRequest(request, resultHandler,
- intermediateResponseHandler);
+ throw new UnsupportedOperationException();
}
@@ -256,127 +133,6 @@
/**
- * {@inheritDoc}
- */
- public Connection getSynchronousConnection()
- {
- return new SynchronousConnection(connection);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public boolean isClosed()
- {
- return connection.isClosed();
- }
-
-
-
- public boolean isValid()
- {
- return connection.isValid();
- }
-
-
-
- public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<? super Result> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.modify(request, handler);
- }
-
-
-
- public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.modify(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<? super Result> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.modifyDN(request, handler);
- }
-
-
-
- public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.modifyDN(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public FutureResult<SearchResultEntry> readEntry(final DN name,
- final Collection<String> attributeDescriptions,
- final ResultHandler<? super SearchResultEntry> resultHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.readEntry(name, attributeDescriptions, resultHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public FutureResult<RootDSE> readRootDSE(
- final ResultHandler<? super RootDSE> handler)
- throws UnsupportedOperationException, IllegalStateException
- {
- return connection.readRootDSE(handler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public FutureResult<Schema> readSchema(final DN name,
- final ResultHandler<? super Schema> handler)
- throws UnsupportedOperationException, IllegalStateException
- {
- return connection.readSchema(name, handler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public FutureResult<Schema> readSchemaForEntry(final DN name,
- final ResultHandler<? super Schema> handler)
- throws UnsupportedOperationException, IllegalStateException
- {
- return connection.readSchemaForEntry(name, handler);
- }
-
-
-
- /**
* Re-authenticates to the Directory Server using the bind request
* associated with this connection. If re-authentication fails for some
* reason then this connection will be automatically closed.
@@ -439,50 +195,6 @@
- public void removeConnectionEventListener(
- final ConnectionEventListener listener) throws NullPointerException
- {
- connection.removeConnectionEventListener(listener);
- }
-
-
-
- public FutureResult<Result> search(final SearchRequest request,
- final SearchResultHandler handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.search(request, handler);
- }
-
-
-
- public FutureResult<Result> search(final SearchRequest request,
- final SearchResultHandler resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.search(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public FutureResult<SearchResultEntry> searchSingleEntry(
- final SearchRequest request,
- final ResultHandler<? super SearchResultEntry> resultHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.searchSingleEntry(request, resultHandler);
- }
-
-
-
/**
* {@inheritDoc}
*/
diff --git a/opendj-sdk/sdk/src/com/sun/opends/sdk/util/AsynchronousConnectionDecorator.java b/opendj-sdk/sdk/src/com/sun/opends/sdk/util/AsynchronousConnectionDecorator.java
new file mode 100644
index 0000000..14a4c48
--- /dev/null
+++ b/opendj-sdk/sdk/src/com/sun/opends/sdk/util/AsynchronousConnectionDecorator.java
@@ -0,0 +1,508 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2010 Sun Microsystems, Inc.
+ */
+
+package com.sun.opends.sdk.util;
+
+
+
+import java.util.Collection;
+
+import org.opends.sdk.*;
+import org.opends.sdk.requests.*;
+import org.opends.sdk.responses.*;
+import org.opends.sdk.schema.Schema;
+
+
+
+/**
+ * A base class from which asynchronous connection decorators may be easily
+ * implemented. The default implementation of each method is to delegate to the
+ * decorated connection.
+ */
+public abstract class AsynchronousConnectionDecorator implements
+ AsynchronousConnection
+{
+ /**
+ * The decorated asynchronous connection.
+ */
+ protected final AsynchronousConnection connection;
+
+
+
+ /**
+ * Creates a new asynchronous connection decorator.
+ *
+ * @param connection
+ * The asynchronous connection to be decorated.
+ */
+ protected AsynchronousConnectionDecorator(AsynchronousConnection connection)
+ {
+ Validator.ensureNotNull(connection);
+ this.connection = connection;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<Void> abandon(AbandonRequest request)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.abandon(request);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<Result> add(AddRequest request,
+ ResultHandler<? super Result> handler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.add(request, handler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<Result> add(AddRequest request,
+ ResultHandler<? super Result> resultHandler,
+ IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.add(request, resultHandler, intermediateResponseHandler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public void addConnectionEventListener(ConnectionEventListener listener)
+ throws IllegalStateException, NullPointerException
+ {
+ connection.addConnectionEventListener(listener);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<BindResult> bind(BindRequest request,
+ ResultHandler<? super BindResult> handler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.bind(request, handler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<BindResult> bind(BindRequest request,
+ ResultHandler<? super BindResult> resultHandler,
+ IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.bind(request, resultHandler, intermediateResponseHandler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public void close()
+ {
+ connection.close();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public void close(UnbindRequest request, String reason)
+ throws NullPointerException
+ {
+ connection.close(request, reason);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<CompareResult> compare(CompareRequest request,
+ ResultHandler<? super CompareResult> handler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.compare(request, handler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<CompareResult> compare(CompareRequest request,
+ ResultHandler<? super CompareResult> resultHandler,
+ IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.compare(request, resultHandler,
+ intermediateResponseHandler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<Result> delete(DeleteRequest request,
+ ResultHandler<? super Result> handler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.delete(request, handler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<Result> delete(DeleteRequest request,
+ ResultHandler<? super Result> resultHandler,
+ IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.delete(request, resultHandler,
+ intermediateResponseHandler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public <R extends ExtendedResult> FutureResult<R> extendedRequest(
+ ExtendedRequest<R> request, ResultHandler<? super R> handler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.extendedRequest(request, handler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public <R extends ExtendedResult> FutureResult<R> extendedRequest(
+ ExtendedRequest<R> request, ResultHandler<? super R> resultHandler,
+ IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.extendedRequest(request, resultHandler,
+ intermediateResponseHandler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to return a synchronous view of this
+ * decorated connection.
+ */
+ public Connection getSynchronousConnection()
+ {
+ return new SynchronousConnection(this);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public boolean isClosed()
+ {
+ return connection.isClosed();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public boolean isValid()
+ {
+ return connection.isValid();
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<Result> modify(ModifyRequest request,
+ ResultHandler<? super Result> handler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.modify(request, handler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<Result> modify(ModifyRequest request,
+ ResultHandler<? super Result> resultHandler,
+ IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.modify(request, resultHandler,
+ intermediateResponseHandler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<Result> modifyDN(ModifyDNRequest request,
+ ResultHandler<? super Result> handler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.modifyDN(request, handler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<Result> modifyDN(ModifyDNRequest request,
+ ResultHandler<? super Result> resultHandler,
+ IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.modifyDN(request, resultHandler,
+ intermediateResponseHandler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<SearchResultEntry> readEntry(DN name,
+ Collection<String> attributeDescriptions,
+ ResultHandler<? super SearchResultEntry> handler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.readEntry(name, attributeDescriptions, handler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<RootDSE> readRootDSE(
+ ResultHandler<? super RootDSE> handler)
+ throws UnsupportedOperationException, IllegalStateException
+ {
+ return connection.readRootDSE(handler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<Schema> readSchema(DN name,
+ ResultHandler<? super Schema> handler)
+ throws UnsupportedOperationException, IllegalStateException
+ {
+ return connection.readSchema(name, handler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<Schema> readSchemaForEntry(DN name,
+ ResultHandler<? super Schema> handler)
+ throws UnsupportedOperationException, IllegalStateException
+ {
+ return connection.readSchemaForEntry(name, handler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public void removeConnectionEventListener(ConnectionEventListener listener)
+ throws NullPointerException
+ {
+ connection.removeConnectionEventListener(listener);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<Result> search(SearchRequest request,
+ SearchResultHandler handler) throws UnsupportedOperationException,
+ IllegalStateException, NullPointerException
+ {
+ return connection.search(request, handler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<Result> search(SearchRequest request,
+ SearchResultHandler resultHandler,
+ IntermediateResponseHandler intermediateResponseHandler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.search(request, resultHandler,
+ intermediateResponseHandler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public FutureResult<SearchResultEntry> searchSingleEntry(
+ SearchRequest request, ResultHandler<? super SearchResultEntry> handler)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException
+ {
+ return connection.searchSingleEntry(request, handler);
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default implementation is to delegate.
+ */
+ public String toString()
+ {
+ return connection.toString();
+ }
+
+}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/AbstractLoadBalancingAlgorithm.java b/opendj-sdk/sdk/src/org/opends/sdk/AbstractLoadBalancingAlgorithm.java
index 75826a1..42c7f8c 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/AbstractLoadBalancingAlgorithm.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/AbstractLoadBalancingAlgorithm.java
@@ -196,7 +196,7 @@
{
// Enable monitoring.
monitoringFuture = scheduler.scheduleWithFixedDelay(
- new MonitorThread(), 0, monitoringInterval,
+ new MonitorRunnable(), 0, monitoringInterval,
monitoringIntervalTimeUnit);
}
}
@@ -237,9 +237,9 @@
- private final class MonitorThread implements Runnable
+ private final class MonitorRunnable implements Runnable
{
- private MonitorThread()
+ private MonitorRunnable()
{
// Nothing to do.
}
@@ -277,43 +277,26 @@
/**
- * Creates a new abstract load balancing algorithm.
+ * Creates a new abstract load balancing algorithm which will monitor offline
+ * connection factories every 10 seconds using the default scheduler.
*
* @param factories
* The connection factories.
*/
AbstractLoadBalancingAlgorithm(final Collection<ConnectionFactory> factories)
{
- this(factories, StaticUtils.getDefaultScheduler());
+ this(factories, 10, TimeUnit.SECONDS, StaticUtils.getDefaultScheduler());
}
/**
- * Creates a new abstract load balancing algorithm.
+ * Creates a new abstract load balancing algorithm which will monitor offline
+ * connection factories using the specified frequency using the default
+ * scheduler.
*
* @param factories
* The connection factories.
- * @param scheduler
- * The scheduler which should for periodically monitoring dead
- * connection factories to see if they are usable again.
- */
- AbstractLoadBalancingAlgorithm(final Collection<ConnectionFactory> factories,
- final ScheduledExecutorService scheduler)
- {
- this(factories, StaticUtils.getDefaultScheduler(), 10, TimeUnit.SECONDS);
- }
-
-
-
- /**
- * Creates a new abstract load balancing algorithm.
- *
- * @param factories
- * The connection factories.
- * @param scheduler
- * The scheduler which should for periodically monitoring dead
- * connection factories to see if they are usable again.
* @param interval
* The interval between attempts to poll offline factories.
* @param unit
@@ -321,8 +304,31 @@
* factories.
*/
AbstractLoadBalancingAlgorithm(final Collection<ConnectionFactory> factories,
- final ScheduledExecutorService scheduler, final long interval,
- final TimeUnit unit)
+ final long interval, final TimeUnit unit)
+ {
+ this(factories, interval, unit, StaticUtils.getDefaultScheduler());
+ }
+
+
+
+ /**
+ * Creates a new abstract load balancing algorithm which will monitor offline
+ * connection factories using the specified frequency and scheduler.
+ *
+ * @param factories
+ * The connection factories.
+ * @param interval
+ * The interval between attempts to poll offline factories.
+ * @param unit
+ * The time unit for the interval between attempts to poll offline
+ * factories.
+ * @param scheduler
+ * The scheduler which should for periodically monitoring dead
+ * connection factories to see if they are usable again.
+ */
+ AbstractLoadBalancingAlgorithm(final Collection<ConnectionFactory> factories,
+ final long interval, final TimeUnit unit,
+ final ScheduledExecutorService scheduler)
{
Validator.ensureNotNull(factories, scheduler, unit);
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java b/opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java
index 425e8e0..168d660 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java
@@ -29,12 +29,10 @@
-import java.util.Collection;
+import org.opends.sdk.requests.BindRequest;
+import org.opends.sdk.responses.BindResult;
-import org.opends.sdk.requests.*;
-import org.opends.sdk.responses.*;
-import org.opends.sdk.schema.Schema;
-
+import com.sun.opends.sdk.util.AsynchronousConnectionDecorator;
import com.sun.opends.sdk.util.FutureResultTransformer;
import com.sun.opends.sdk.util.RecursiveFutureResult;
@@ -59,58 +57,14 @@
* An authenticated asynchronous connection supports all operations except
* Bind operations.
*/
- public static final class AuthenticatedAsynchronousConnection implements
- AsynchronousConnection
+ public static final class AuthenticatedAsynchronousConnection extends
+ AsynchronousConnectionDecorator
{
- private final AsynchronousConnection connection;
-
-
-
private AuthenticatedAsynchronousConnection(
final AsynchronousConnection connection)
{
- this.connection = connection;
- }
-
-
-
- public FutureResult<Void> abandon(final AbandonRequest request)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.abandon(request);
- }
-
-
-
- public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<? super Result> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.add(request, handler);
- }
-
-
-
- public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection
- .add(request, resultHandler, intermediateResponseHandler);
- }
-
-
-
- public void addConnectionEventListener(
- final ConnectionEventListener listener) throws IllegalStateException,
- NullPointerException
- {
- connection.addConnectionEventListener(listener);
+ super(connection);
}
@@ -129,264 +83,17 @@
+ /**
+ * Bind operations are not supported by pre-authenticated connections. This
+ * method will always throw {@code UnsupportedOperationException}.
+ */
public FutureResult<BindResult> bind(final BindRequest request,
final ResultHandler<? super BindResult> resultHandler,
final IntermediateResponseHandler intermediateResponseHandler)
throws UnsupportedOperationException, IllegalStateException,
NullPointerException
{
- return connection.bind(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- public void close()
- {
- connection.close();
- }
-
-
-
- public void close(final UnbindRequest request, final String reason)
- throws NullPointerException
- {
- connection.close(request, reason);
- }
-
-
-
- public FutureResult<CompareResult> compare(final CompareRequest request,
- final ResultHandler<? super CompareResult> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.compare(request, handler);
- }
-
-
-
- public FutureResult<CompareResult> compare(final CompareRequest request,
- final ResultHandler<? super CompareResult> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.compare(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<? super Result> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.delete(request, handler);
- }
-
-
-
- public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.delete(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- public <R extends ExtendedResult> FutureResult<R> extendedRequest(
- final ExtendedRequest<R> request, final ResultHandler<? super R> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.extendedRequest(request, handler);
- }
-
-
-
- public <R extends ExtendedResult> FutureResult<R> extendedRequest(
- final ExtendedRequest<R> request,
- final ResultHandler<? super R> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.extendedRequest(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public Connection getSynchronousConnection()
- {
- return new SynchronousConnection(this);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public boolean isClosed()
- {
- return connection.isClosed();
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public boolean isValid()
- {
- return connection.isValid();
- }
-
-
-
- public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<? super Result> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.modify(request, handler);
- }
-
-
-
- public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.modify(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<? super Result> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.modifyDN(request, handler);
- }
-
-
-
- public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.modifyDN(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public FutureResult<SearchResultEntry> readEntry(final DN name,
- final Collection<String> attributeDescriptions,
- final ResultHandler<? super SearchResultEntry> resultHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.readEntry(name, attributeDescriptions, resultHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public FutureResult<RootDSE> readRootDSE(
- final ResultHandler<? super RootDSE> handler)
- throws UnsupportedOperationException, IllegalStateException
- {
- return connection.readRootDSE(handler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public FutureResult<Schema> readSchema(final DN name,
- final ResultHandler<? super Schema> handler)
- throws UnsupportedOperationException, IllegalStateException
- {
- return connection.readSchema(name, handler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public FutureResult<Schema> readSchemaForEntry(final DN name,
- final ResultHandler<? super Schema> handler)
- throws UnsupportedOperationException, IllegalStateException
- {
- return connection.readSchemaForEntry(name, handler);
- }
-
-
-
- public void removeConnectionEventListener(
- final ConnectionEventListener listener) throws NullPointerException
- {
- connection.removeConnectionEventListener(listener);
- }
-
-
-
- public FutureResult<Result> search(final SearchRequest request,
- final SearchResultHandler handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.search(request, handler);
- }
-
-
-
- public FutureResult<Result> search(final SearchRequest request,
- final SearchResultHandler resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.search(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public FutureResult<SearchResultEntry> searchSingleEntry(
- final SearchRequest request,
- final ResultHandler<? super SearchResultEntry> resultHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.searchSingleEntry(request, resultHandler);
+ throw new UnsupportedOperationException();
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/Connections.java b/opendj-sdk/sdk/src/org/opends/sdk/Connections.java
index 74813f0..7965ebb 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/Connections.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/Connections.java
@@ -29,6 +29,7 @@
+import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.opends.sdk.requests.BindRequest;
@@ -103,64 +104,120 @@
/**
- * Creates a new connection factory which will create connections using the
- * provided connection factory and periodically probe any created connections
- * in order to detect that they are still alive.
+ * Creates a new heart-beat connection factory which will create connections
+ * using the provided connection factory and periodically ping any created
+ * connections in order to detect that they are still alive every 10 seconds
+ * using the default scheduler.
*
* @param factory
* The connection factory to use for creating connections.
- * @param timeout
- * The time to wait between keep-alive probes.
- * @param unit
- * The time unit of the timeout argument.
* @return The new heart-beat connection factory.
- * @throws IllegalArgumentException
- * If {@code timeout} was negative.
* @throws NullPointerException
- * If {@code factory} or {@code unit} was {@code null}.
+ * If {@code factory} was {@code null}.
*/
public static ConnectionFactory newHeartBeatConnectionFactory(
- final ConnectionFactory factory, final long timeout, final TimeUnit unit)
- throws IllegalArgumentException, NullPointerException
+ final ConnectionFactory factory) throws NullPointerException
{
- Validator.ensureNotNull(factory, unit);
- Validator.ensureTrue(timeout >= 0, "negative timeout");
-
- return new HeartBeatConnectionFactory(factory, timeout, unit);
+ return new HeartBeatConnectionFactory(factory);
}
/**
- * Creates a new connection factory which will create connections using the
- * provided connection factory and periodically probe any created connections
- * using the specified search request in order to detect that they are still
- * alive.
+ * Creates a new heart-beat connection factory which will create connections
+ * using the provided connection factory and periodically ping any created
+ * connections in order to detect that they are still alive using the
+ * specified frequency and the default scheduler.
*
* @param factory
* The connection factory to use for creating connections.
- * @param timeout
- * The time to wait between keep-alive probes.
+ * @param interval
+ * The interval between keepalive pings.
* @param unit
- * The time unit of the timeout argument.
- * @param heartBeat
- * The search request to use when pinging connections.
+ * The time unit for the interval between keepalive pings.
* @return The new heart-beat connection factory.
* @throws IllegalArgumentException
- * If {@code timeout} was negative.
+ * If {@code interval} was negative.
+ * @throws NullPointerException
+ * If {@code factory} or {@code unit} was {@code null}.
+ */
+ public static ConnectionFactory newHeartBeatConnectionFactory(
+ final ConnectionFactory factory, final long interval, final TimeUnit unit)
+ throws IllegalArgumentException, NullPointerException
+ {
+ return new HeartBeatConnectionFactory(factory, interval, unit);
+ }
+
+
+
+
+
+
+ /**
+ * Creates a new heart-beat connection factory which will create connections
+ * using the provided connection factory and periodically ping any created
+ * connections using the specified search request in order to detect that they
+ * are still alive.
+ *
+ * @param factory
+ * The connection factory to use for creating connections.
+ * @param interval
+ * The interval between keepalive pings.
+ * @param unit
+ * The time unit for the interval between keepalive pings.
+ * @param heartBeat
+ * The search request to use for keepalive pings.
+ * @return The new heart-beat connection factory.
+ * @throws IllegalArgumentException
+ * If {@code interval} was negative.
+ * @throws NullPointerException
+ * If {@code factory}, {@code unit}, or {@code heartBeat} was {@code null}.
+ */
+ public static ConnectionFactory newHeartBeatConnectionFactory(
+ final ConnectionFactory factory, final long interval, final TimeUnit unit,
+ final SearchRequest heartBeat) throws IllegalArgumentException,
+ NullPointerException
+ {
+ return new HeartBeatConnectionFactory(factory, interval, unit, heartBeat);
+ }
+
+
+
+
+
+
+ /**
+ * Creates a new heart-beat connection factory which will create connections
+ * using the provided connection factory and periodically ping any created
+ * connections using the specified search request in order to detect that they
+ * are still alive.
+ *
+ * @param factory
+ * The connection factory to use for creating connections.
+ * @param interval
+ * The interval between keepalive pings.
+ * @param unit
+ * The time unit for the interval between keepalive pings.
+ * @param heartBeat
+ * The search request to use for keepalive pings.
+ * @param scheduler
+ * The scheduler which should for periodically sending keepalive
+ * pings.
+ * @return The new heart-beat connection factory.
+ * @throws IllegalArgumentException
+ * If {@code interval} was negative.
* @throws NullPointerException
* If {@code factory}, {@code unit}, or {@code heartBeat} was
* {@code null}.
*/
public static ConnectionFactory newHeartBeatConnectionFactory(
- final ConnectionFactory factory, final long timeout, final TimeUnit unit,
- final SearchRequest heartBeat) throws IllegalArgumentException,
- NullPointerException
+ final ConnectionFactory factory, final long interval,
+ final TimeUnit unit, final SearchRequest heartBeat,
+ final ScheduledExecutorService scheduler)
+ throws IllegalArgumentException, NullPointerException
{
- Validator.ensureNotNull(factory, unit, heartBeat);
- Validator.ensureTrue(timeout >= 0, "negative timeout");
-
- return new HeartBeatConnectionFactory(factory, timeout, unit, heartBeat);
+ return new HeartBeatConnectionFactory(factory, interval, unit, heartBeat,
+ scheduler);
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java b/opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java
index 6ac3148..0fed20d 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java
@@ -69,8 +69,8 @@
{
/**
- * Creates a new fail-over load balancing algorithm which will use a default
- * scheduler for monitoring offline connection factories every 10 seconds.
+ * Creates a new fail-over load balancing algorithm which will monitor offline
+ * connection factories every 10 seconds using the default scheduler.
*
* @param factories
* The ordered collection of connection factories.
@@ -84,47 +84,47 @@
/**
- * Creates a new fail-over load balancing algorithm which will use the
- * provided scheduler for monitoring offline connection factories every 10
- * seconds.
+ * Creates a new fail-over load balancing algorithm which will monitor offline
+ * connection factories using the specified frequency using the default
+ * scheduler.
*
* @param factories
- * The ordered collection of connection factories.
- * @param scheduler
- * The scheduler which should for periodically monitoring offline
- * connection factories to see if they are usable again.
+ * The connection factories.
+ * @param interval
+ * The interval between attempts to poll offline factories.
+ * @param unit
+ * The time unit for the interval between attempts to poll offline
+ * factories.
*/
public FailoverLoadBalancingAlgorithm(
- final Collection<ConnectionFactory> factories,
- final ScheduledExecutorService scheduler)
+ final Collection<ConnectionFactory> factories, final long interval,
+ final TimeUnit unit)
{
- super(factories, scheduler);
+ super(factories, interval, unit);
}
/**
- * Creates a new fail-over load balancing algorithm which will use the
- * provided scheduler for monitoring offline connection factories.
+ * Creates a new fail-over load balancing algorithm which will monitor offline
+ * connection factories using the specified frequency and scheduler.
*
* @param factories
- * The ordered collection of connection factories.
- * @param scheduler
- * The scheduler which should for periodically monitoring offline
- * connection factories to see if they are usable again.
+ * The connection factories.
* @param interval
- * The interval between attempts to poll offline connection
- * factories.
+ * The interval between attempts to poll offline factories.
* @param unit
* The time unit for the interval between attempts to poll offline
- * connection factories.
+ * factories.
+ * @param scheduler
+ * The scheduler which should for periodically monitoring dead
+ * connection factories to see if they are usable again.
*/
public FailoverLoadBalancingAlgorithm(
- final Collection<ConnectionFactory> factories,
- final ScheduledExecutorService scheduler, final long interval,
- final TimeUnit unit)
+ final Collection<ConnectionFactory> factories, final long interval,
+ final TimeUnit unit, final ScheduledExecutorService scheduler)
{
- super(factories, scheduler, interval, unit);
+ super(factories, interval, unit, scheduler);
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java b/opendj-sdk/sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java
index 381cc43..77a29cb 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java
@@ -29,16 +29,23 @@
-import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
-import org.opends.sdk.requests.*;
-import org.opends.sdk.responses.*;
-import org.opends.sdk.schema.Schema;
+import org.opends.sdk.requests.Requests;
+import org.opends.sdk.requests.SearchRequest;
+import org.opends.sdk.responses.ExtendedResult;
+import org.opends.sdk.responses.Result;
+import org.opends.sdk.responses.SearchResultEntry;
+import org.opends.sdk.responses.SearchResultReference;
+import com.sun.opends.sdk.util.AsynchronousConnectionDecorator;
import com.sun.opends.sdk.util.FutureResultTransformer;
+import com.sun.opends.sdk.util.StaticUtils;
+import com.sun.opends.sdk.util.Validator;
@@ -52,11 +59,10 @@
* An asynchronous connection that sends heart beats and supports all
* operations.
*/
- private final class AsynchronousConnectionImpl implements
- AsynchronousConnection, ConnectionEventListener, SearchResultHandler
+ private final class AsynchronousConnectionImpl extends
+ AsynchronousConnectionDecorator implements ConnectionEventListener,
+ SearchResultHandler
{
- private final AsynchronousConnection connection;
-
private long lastSuccessfulPing;
private FutureResult<Result> lastPingFuture;
@@ -65,187 +71,24 @@
private AsynchronousConnectionImpl(final AsynchronousConnection connection)
{
- this.connection = connection;
+ super(connection);
}
- public FutureResult<Void> abandon(final AbandonRequest request)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.abandon(request);
- }
-
-
-
- public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<? super Result> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.add(request, handler);
- }
-
-
-
- public FutureResult<Result> add(final AddRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection
- .add(request, resultHandler, intermediateResponseHandler);
- }
-
-
-
- public void addConnectionEventListener(
- final ConnectionEventListener listener) throws IllegalStateException,
- NullPointerException
- {
- connection.addConnectionEventListener(listener);
- }
-
-
-
- public FutureResult<BindResult> bind(final BindRequest request,
- final ResultHandler<? super BindResult> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.bind(request, handler);
- }
-
-
-
- public FutureResult<BindResult> bind(final BindRequest request,
- final ResultHandler<? super BindResult> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.bind(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- public void close()
- {
- synchronized (activeConnections)
- {
- connection.removeConnectionEventListener(this);
- activeConnections.remove(this);
- }
- connection.close();
- }
-
-
-
- public void close(final UnbindRequest request, final String reason)
- throws NullPointerException
- {
- synchronized (activeConnections)
- {
- connection.removeConnectionEventListener(this);
- activeConnections.remove(this);
- }
- connection.close(request, reason);
- }
-
-
-
- public FutureResult<CompareResult> compare(final CompareRequest request,
- final ResultHandler<? super CompareResult> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.compare(request, handler);
- }
-
-
-
- public FutureResult<CompareResult> compare(final CompareRequest request,
- final ResultHandler<? super CompareResult> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.compare(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
+ @Override
public void handleConnectionClosed()
{
- // Ignore - we intercept close through the close method.
+ notifyClosed();
}
+ @Override
public void handleConnectionError(final boolean isDisconnectNotification,
final ErrorResultException error)
{
- synchronized (activeConnections)
- {
- connection.removeConnectionEventListener(this);
- activeConnections.remove(this);
- }
- }
-
-
-
- public void handleUnsolicitedNotification(final ExtendedResult notification)
- {
- // Do nothing
- }
-
-
-
- public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<? super Result> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.delete(request, handler);
- }
-
-
-
- public FutureResult<Result> delete(final DeleteRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.delete(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- public <R extends ExtendedResult> FutureResult<R> extendedRequest(
- final ExtendedRequest<R> request, final ResultHandler<? super R> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.extendedRequest(request, handler);
- }
-
-
-
- public <R extends ExtendedResult> FutureResult<R> extendedRequest(
- final ExtendedRequest<R> request,
- final ResultHandler<? super R> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.extendedRequest(request, resultHandler,
- intermediateResponseHandler);
+ notifyClosed();
}
@@ -253,17 +96,8 @@
/**
* {@inheritDoc}
*/
- public Connection getSynchronousConnection()
- {
- return new SynchronousConnection(this);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public boolean handleEntry(SearchResultEntry entry)
+ @Override
+ public boolean handleEntry(final SearchResultEntry entry)
{
// Ignore.
return true;
@@ -271,6 +105,10 @@
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void handleErrorResult(final ErrorResultException error)
{
connection.close(Requests.newUnbindRequest(), "Heartbeat retured error: "
@@ -282,7 +120,8 @@
/**
* {@inheritDoc}
*/
- public boolean handleReference(SearchResultReference reference)
+ @Override
+ public boolean handleReference(final SearchResultReference reference)
{
// Ignore.
return true;
@@ -290,6 +129,10 @@
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void handleResult(final Result result)
{
lastSuccessfulPing = System.currentTimeMillis();
@@ -297,12 +140,10 @@
- /**
- * {@inheritDoc}
- */
- public boolean isClosed()
+ @Override
+ public void handleUnsolicitedNotification(final ExtendedResult notification)
{
- return connection.isClosed();
+ // Do nothing
}
@@ -310,55 +151,12 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean isValid()
{
return connection.isValid()
&& (lastSuccessfulPing <= 0 || System.currentTimeMillis()
- - lastSuccessfulPing < unit.toMillis(timeout) * 2);
- }
-
-
-
- public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<? super Result> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.modify(request, handler);
- }
-
-
-
- public FutureResult<Result> modify(final ModifyRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.modify(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<? super Result> handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.modifyDN(request, handler);
- }
-
-
-
- public FutureResult<Result> modifyDN(final ModifyDNRequest request,
- final ResultHandler<? super Result> resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.modifyDN(request, resultHandler,
- intermediateResponseHandler);
+ - lastSuccessfulPing < unit.toMillis(interval) * 2);
}
@@ -366,108 +164,32 @@
/**
* {@inheritDoc}
*/
- public FutureResult<SearchResultEntry> readEntry(final DN name,
- final Collection<String> attributeDescriptions,
- final ResultHandler<? super SearchResultEntry> resultHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.readEntry(name, attributeDescriptions, resultHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public FutureResult<RootDSE> readRootDSE(
- final ResultHandler<? super RootDSE> handler)
- throws UnsupportedOperationException, IllegalStateException
- {
- return connection.readRootDSE(handler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public FutureResult<Schema> readSchema(final DN name,
- final ResultHandler<? super Schema> handler)
- throws UnsupportedOperationException, IllegalStateException
- {
- return connection.readSchema(name, handler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public FutureResult<Schema> readSchemaForEntry(final DN name,
- final ResultHandler<? super Schema> handler)
- throws UnsupportedOperationException, IllegalStateException
- {
- return connection.readSchemaForEntry(name, handler);
- }
-
-
-
- public void removeConnectionEventListener(
- final ConnectionEventListener listener) throws NullPointerException
- {
- connection.removeConnectionEventListener(listener);
- }
-
-
-
- public FutureResult<Result> search(final SearchRequest request,
- final SearchResultHandler handler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.search(request, handler);
- }
-
-
-
- public FutureResult<Result> search(final SearchRequest request,
- final SearchResultHandler resultHandler,
- final IntermediateResponseHandler intermediateResponseHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.search(request, resultHandler,
- intermediateResponseHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public FutureResult<SearchResultEntry> searchSingleEntry(
- final SearchRequest request,
- final ResultHandler<? super SearchResultEntry> resultHandler)
- throws UnsupportedOperationException, IllegalStateException,
- NullPointerException
- {
- return connection.searchSingleEntry(request, resultHandler);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
+ @Override
public String toString()
{
- StringBuilder builder = new StringBuilder();
+ final StringBuilder builder = new StringBuilder();
builder.append("HeartBeatConnection(");
builder.append(connection);
builder.append(')');
return builder.toString();
}
+
+
+
+ private void notifyClosed()
+ {
+ synchronized (activeConnections)
+ {
+ connection.removeConnectionEventListener(this);
+ activeConnections.remove(this);
+
+ if (activeConnections.isEmpty())
+ {
+ // This is the last active connection, so stop the heart beat.
+ heartBeatFuture.cancel(false);
+ }
+ }
+ }
}
@@ -497,6 +219,12 @@
synchronized (activeConnections)
{
connection.addConnectionEventListener(heartBeatConnection);
+ if (activeConnections.isEmpty())
+ {
+ // This is the first active connection, so start the heart beat.
+ heartBeatFuture = scheduler.scheduleWithFixedDelay(
+ new HeartBeatRunnable(), 0, interval, unit);
+ }
activeConnections.add(heartBeatConnection);
}
return heartBeatConnection;
@@ -506,12 +234,11 @@
- private final class HeartBeatThread extends Thread
+ private final class HeartBeatRunnable implements Runnable
{
- private HeartBeatThread()
+ private HeartBeatRunnable()
{
- super("Heart Beat Thread");
- this.setDaemon(true);
+ // Nothing to do.
}
@@ -519,35 +246,17 @@
@Override
public void run()
{
- long startTime;
- while (true)
+ synchronized (activeConnections)
{
- startTime = System.currentTimeMillis();
- synchronized (activeConnections)
+ for (final AsynchronousConnectionImpl connection : activeConnections)
{
- for (final AsynchronousConnectionImpl connection : activeConnections)
+ if (connection.lastPingFuture == null
+ || connection.lastPingFuture.isDone())
{
- if (connection.lastPingFuture == null
- || connection.lastPingFuture.isDone())
- {
- connection.lastPingFuture = connection.search(heartBeat,
- connection, null);
- }
+ connection.lastPingFuture = connection.search(heartBeat,
+ connection, null);
}
}
- try
- {
- final long sleepTime = unit.toMillis(timeout)
- - (System.currentTimeMillis() - startTime);
- if (sleepTime > 0)
- {
- sleep(sleepTime);
- }
- }
- catch (final InterruptedException e)
- {
- // Ignore
- }
}
}
}
@@ -556,37 +265,58 @@
private final SearchRequest heartBeat;
- private final long timeout;
+ private final long interval;
- // FIXME: use a single global scheduler?
+ private final ScheduledExecutorService scheduler;
private final TimeUnit unit;
private final List<AsynchronousConnectionImpl> activeConnections;
- private final ConnectionFactory parentFactory;
+ private final ConnectionFactory factory;
private static final SearchRequest DEFAULT_SEARCH = Requests
.newSearchRequest("", SearchScope.BASE_OBJECT, "(objectClass=*)", "1.1");
+ private ScheduledFuture<?> heartBeatFuture;
+
/**
* Creates a new heart-beat connection factory which will create connections
* using the provided connection factory and periodically ping any created
- * connections in order to detect that they are still alive.
+ * connections in order to detect that they are still alive every 10 seconds
+ * using the default scheduler.
*
- * @param connectionFactory
+ * @param factory
* The connection factory to use for creating connections.
- * @param timeout
- * The time to wait between keepalive pings.
- * @param unit
- * The time unit of the timeout argument.
*/
- HeartBeatConnectionFactory(final ConnectionFactory connectionFactory,
- final long timeout, final TimeUnit unit)
+ HeartBeatConnectionFactory(final ConnectionFactory factory)
{
- this(connectionFactory, timeout, unit, DEFAULT_SEARCH);
+ this(factory, 10, TimeUnit.SECONDS, DEFAULT_SEARCH, StaticUtils
+ .getDefaultScheduler());
+ }
+
+
+
+ /**
+ * Creates a new heart-beat connection factory which will create connections
+ * using the provided connection factory and periodically ping any created
+ * connections in order to detect that they are still alive using the
+ * specified frequency and the default scheduler.
+ *
+ * @param factory
+ * The connection factory to use for creating connections.
+ * @param interval
+ * The interval between keepalive pings.
+ * @param unit
+ * The time unit for the interval between keepalive pings.
+ */
+ HeartBeatConnectionFactory(final ConnectionFactory factory,
+ final long interval, final TimeUnit unit)
+ {
+ this(factory, interval, unit, DEFAULT_SEARCH, StaticUtils
+ .getDefaultScheduler());
}
@@ -597,25 +327,54 @@
* connections using the specified search request in order to detect that they
* are still alive.
*
- * @param connectionFactory
+ * @param factory
* The connection factory to use for creating connections.
- * @param timeout
- * The time to wait between keepalive pings.
+ * @param interval
+ * The interval between keepalive pings.
* @param unit
- * The time unit of the timeout argument.
+ * The time unit for the interval between keepalive pings.
* @param heartBeat
- * The search request to use when pinging connections.
+ * The search request to use for keepalive pings.
*/
- HeartBeatConnectionFactory(final ConnectionFactory connectionFactory,
- final long timeout, final TimeUnit unit, final SearchRequest heartBeat)
+ HeartBeatConnectionFactory(final ConnectionFactory factory,
+ final long interval, final TimeUnit unit, final SearchRequest heartBeat)
{
+ this(factory, interval, unit, heartBeat, StaticUtils.getDefaultScheduler());
+ }
+
+
+
+ /**
+ * Creates a new heart-beat connection factory which will create connections
+ * using the provided connection factory and periodically ping any created
+ * connections using the specified search request in order to detect that they
+ * are still alive.
+ *
+ * @param factory
+ * The connection factory to use for creating connections.
+ * @param interval
+ * The interval between keepalive pings.
+ * @param unit
+ * The time unit for the interval between keepalive pings.
+ * @param heartBeat
+ * The search request to use for keepalive pings.
+ * @param scheduler
+ * The scheduler which should for periodically sending keepalive
+ * pings.
+ */
+ HeartBeatConnectionFactory(final ConnectionFactory factory,
+ final long interval, final TimeUnit unit, final SearchRequest heartBeat,
+ final ScheduledExecutorService scheduler)
+ {
+ Validator.ensureNotNull(factory, heartBeat, unit, scheduler);
+ Validator.ensureTrue(interval >= 0, "negative timeout");
+
this.heartBeat = heartBeat;
- this.timeout = timeout;
+ this.interval = interval;
this.unit = unit;
this.activeConnections = new LinkedList<AsynchronousConnectionImpl>();
- this.parentFactory = connectionFactory;
-
- new HeartBeatThread().start();
+ this.factory = factory;
+ this.scheduler = scheduler;
}
@@ -625,7 +384,7 @@
final ResultHandler<? super AsynchronousConnection> handler)
{
final FutureResultImpl future = new FutureResultImpl(handler);
- future.setFutureResult(parentFactory.getAsynchronousConnection(future));
+ future.setFutureResult(factory.getAsynchronousConnection(future));
return future;
}
@@ -634,11 +393,12 @@
/**
* {@inheritDoc}
*/
+ @Override
public String toString()
{
final StringBuilder builder = new StringBuilder();
builder.append("HeartBeatConnectionFactory(");
- builder.append(String.valueOf(parentFactory));
+ builder.append(String.valueOf(factory));
builder.append(')');
return builder.toString();
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingConnectionFactory.java b/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingConnectionFactory.java
deleted file mode 100644
index af4b0b7..0000000
--- a/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingConnectionFactory.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE
- * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
- * Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- * Copyright 2010 Sun Microsystems, Inc.
- */
-
-package org.opends.sdk;
-
-
-
-import com.sun.opends.sdk.util.AbstractFutureResult;
-import com.sun.opends.sdk.util.Validator;
-
-
-
-/**
- * A load balancing connection factory allocates connections using the provided
- * algorithm.
- */
-final class LoadBalancingConnectionFactory extends AbstractConnectionFactory
-{
- private final LoadBalancingAlgorithm algorithm;
-
-
-
- public LoadBalancingConnectionFactory(final LoadBalancingAlgorithm algorithm)
- {
- Validator.ensureNotNull(algorithm);
- this.algorithm = algorithm;
- }
-
-
-
- @Override
- public FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<? super AsynchronousConnection> resultHandler)
- {
- ConnectionFactory factory;
-
- try
- {
- factory = algorithm.getNextConnectionFactory();
- }
- catch (final ErrorResultException e)
- {
- final AbstractFutureResult<AsynchronousConnection> future =
- new AbstractFutureResult<AsynchronousConnection>(resultHandler)
- {
- public int getRequestID()
- {
- return -1;
- }
- };
-
- future.handleErrorResult(e);
- return future;
- }
-
- return factory.getAsynchronousConnection(resultHandler);
- }
-}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/RoundRobinLoadBalancingAlgorithm.java b/opendj-sdk/sdk/src/org/opends/sdk/RoundRobinLoadBalancingAlgorithm.java
index cf4ab46..2968565 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/RoundRobinLoadBalancingAlgorithm.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/RoundRobinLoadBalancingAlgorithm.java
@@ -68,11 +68,11 @@
/**
- * Creates a new round robin load balancing algorithm which will use a default
- * scheduler for monitoring offline connection factories every 10 seconds.
+ * Creates a new round robin load balancing algorithm which will monitor
+ * offline connection factories every 10 seconds using the default scheduler.
*
* @param factories
- * The unordered collection of connection factories.
+ * The ordered collection of connection factories.
*/
public RoundRobinLoadBalancingAlgorithm(
final Collection<ConnectionFactory> factories)
@@ -84,48 +84,48 @@
/**
- * Creates a new round robin load balancing algorithm which will use the
- * provided scheduler for monitoring offline connection factories every 10
- * seconds.
+ * Creates a new round robin load balancing algorithm which will monitor
+ * offline connection factories using the specified frequency using the
+ * default scheduler.
*
* @param factories
- * The unordered collection of connection factories.
- * @param scheduler
- * The scheduler which should for periodically monitoring offline
- * connection factories to see if they are usable again.
+ * The connection factories.
+ * @param interval
+ * The interval between attempts to poll offline factories.
+ * @param unit
+ * The time unit for the interval between attempts to poll offline
+ * factories.
*/
public RoundRobinLoadBalancingAlgorithm(
- final Collection<ConnectionFactory> factories,
- final ScheduledExecutorService scheduler)
+ final Collection<ConnectionFactory> factories, final long interval,
+ final TimeUnit unit)
{
- super(factories, scheduler);
+ super(factories, interval, unit);
this.maxIndex = factories.size();
}
/**
- * Creates a new round robin load balancing algorithm which will use the
- * provided scheduler for monitoring offline connection factories.
+ * Creates a new round robin load balancing algorithm which will monitor
+ * offline connection factories using the specified frequency and scheduler.
*
* @param factories
- * The unordered collection of connection factories.
- * @param scheduler
- * The scheduler which should for periodically monitoring offline
- * connection factories to see if they are usable again.
+ * The connection factories.
* @param interval
- * The interval between attempts to poll offline connection
- * factories.
+ * The interval between attempts to poll offline factories.
* @param unit
* The time unit for the interval between attempts to poll offline
- * connection factories.
+ * factories.
+ * @param scheduler
+ * The scheduler which should for periodically monitoring dead
+ * connection factories to see if they are usable again.
*/
public RoundRobinLoadBalancingAlgorithm(
- final Collection<ConnectionFactory> factories,
- final ScheduledExecutorService scheduler, final long interval,
- final TimeUnit unit)
+ final Collection<ConnectionFactory> factories, final long interval,
+ final TimeUnit unit, final ScheduledExecutorService scheduler)
{
- super(factories, scheduler, interval, unit);
+ super(factories, interval, unit, scheduler);
this.maxIndex = factories.size();
}
diff --git a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LDAPListenerTestCase.java b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LDAPListenerTestCase.java
index 6aec25d..2b58e3b 100644
--- a/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LDAPListenerTestCase.java
+++ b/opendj-sdk/sdk/tests/unit-tests-testng/src/org/opends/sdk/LDAPListenerTestCase.java
@@ -32,6 +32,7 @@
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.*;
@@ -46,6 +47,40 @@
public class LDAPListenerTestCase extends SdkTestCase
{
+ private static class MockConnectionEventListener implements
+ ConnectionEventListener
+ {
+ final CountDownLatch closeLatch = new CountDownLatch(1);
+ String errorMessage = null;
+
+
+
+ public void handleUnsolicitedNotification(ExtendedResult notification)
+ {
+ errorMessage = "Unexpected call to handleUnsolicitedNotification";
+ closeLatch.countDown();
+ }
+
+
+
+ public void handleConnectionError(boolean isDisconnectNotification,
+ ErrorResultException error)
+ {
+ errorMessage = "Unexpected call to handleConnectionError";
+ closeLatch.countDown();
+ }
+
+
+
+ public void handleConnectionClosed()
+ {
+ errorMessage = "Unexpected call to handleConnectionClosed";
+ closeLatch.countDown();
+ }
+ }
+
+
+
private static class MockServerConnection implements
ServerConnection<Integer>
{
@@ -773,4 +808,199 @@
Assert.assertTrue(connection.isClosed());
}
}
+
+
+
+ /**
+ * Tests connection event listener.
+ *
+ * @throws Exception
+ * If an unexpected error occurred.
+ */
+ @Test
+ public void testConnectionEventListenerClose() throws Exception
+ {
+ final MockServerConnection onlineServerConnection = new MockServerConnection();
+ final MockServerConnectionFactory onlineServerConnectionFactory = new MockServerConnectionFactory(
+ onlineServerConnection);
+ final LDAPListener onlineServerListener = new LDAPListener("localhost",
+ TestCaseUtils.findFreePort(), onlineServerConnectionFactory);
+
+ final Connection connection;
+ try
+ {
+ // Connect and bind.
+ connection = new LDAPConnectionFactory(
+ onlineServerListener.getSocketAddress()).getConnection();
+
+ MockConnectionEventListener listener = new MockConnectionEventListener()
+ {
+
+ public void handleConnectionClosed()
+ {
+ closeLatch.countDown();
+ }
+ };
+
+ connection.addConnectionEventListener(listener);
+ Assert.assertEquals(listener.closeLatch.getCount(), 1);
+ connection.close();
+ listener.closeLatch.await();
+ Assert.assertNull(listener.errorMessage);
+ }
+ finally
+ {
+ onlineServerListener.close();
+ }
+ }
+
+
+
+ /**
+ * Tests connection event listener.
+ *
+ * @throws Exception
+ * If an unexpected error occurred.
+ */
+ @Test
+ public void testConnectionEventListenerUnbind() throws Exception
+ {
+ final MockServerConnection onlineServerConnection = new MockServerConnection();
+ final MockServerConnectionFactory onlineServerConnectionFactory = new MockServerConnectionFactory(
+ onlineServerConnection);
+ final LDAPListener onlineServerListener = new LDAPListener("localhost",
+ TestCaseUtils.findFreePort(), onlineServerConnectionFactory);
+
+ final Connection connection;
+ try
+ {
+ // Connect and bind.
+ connection = new LDAPConnectionFactory(
+ onlineServerListener.getSocketAddress()).getConnection();
+
+ MockConnectionEventListener listener = new MockConnectionEventListener()
+ {
+
+ public void handleConnectionClosed()
+ {
+ closeLatch.countDown();
+ }
+ };
+
+ connection.addConnectionEventListener(listener);
+ Assert.assertEquals(listener.closeLatch.getCount(), 1);
+ connection.close(Requests.newUnbindRequest(), "called from unit test");
+ listener.closeLatch.await();
+ Assert.assertNull(listener.errorMessage);
+ }
+ finally
+ {
+ onlineServerListener.close();
+ }
+ }
+
+
+
+ /**
+ * Tests connection event listener.
+ *
+ * @throws Exception
+ * If an unexpected error occurred.
+ */
+ @Test
+ public void testConnectionEventListenerDisconnect() throws Exception
+ {
+ final MockServerConnection onlineServerConnection = new MockServerConnection();
+ final MockServerConnectionFactory onlineServerConnectionFactory = new MockServerConnectionFactory(
+ onlineServerConnection);
+ final LDAPListener onlineServerListener = new LDAPListener("localhost",
+ TestCaseUtils.findFreePort(), onlineServerConnectionFactory);
+
+ final Connection connection;
+ try
+ {
+ // Connect and bind.
+ connection = new LDAPConnectionFactory(
+ onlineServerListener.getSocketAddress()).getConnection();
+
+ MockConnectionEventListener listener = new MockConnectionEventListener()
+ {
+
+ public void handleConnectionError(boolean isDisconnectNotification,
+ ErrorResultException error)
+ {
+ if (isDisconnectNotification)
+ {
+ errorMessage = "Unexpected disconnect notification";
+ }
+ closeLatch.countDown();
+ }
+ };
+
+ connection.addConnectionEventListener(listener);
+ Assert.assertEquals(listener.closeLatch.getCount(), 1);
+ onlineServerConnection.context.disconnect();
+ listener.closeLatch.await();
+ Assert.assertNull(listener.errorMessage);
+ connection.close();
+ }
+ finally
+ {
+ onlineServerListener.close();
+ }
+ }
+
+
+
+ /**
+ * Tests connection event listener.
+ *
+ * @throws Exception
+ * If an unexpected error occurred.
+ */
+ @Test
+ public void testConnectionEventListenerDisconnectNotification()
+ throws Exception
+ {
+ final MockServerConnection onlineServerConnection = new MockServerConnection();
+ final MockServerConnectionFactory onlineServerConnectionFactory = new MockServerConnectionFactory(
+ onlineServerConnection);
+ final LDAPListener onlineServerListener = new LDAPListener("localhost",
+ TestCaseUtils.findFreePort(), onlineServerConnectionFactory);
+
+ final Connection connection;
+ try
+ {
+ // Connect and bind.
+ connection = new LDAPConnectionFactory(
+ onlineServerListener.getSocketAddress()).getConnection();
+
+ MockConnectionEventListener listener = new MockConnectionEventListener()
+ {
+
+ public void handleConnectionError(boolean isDisconnectNotification,
+ ErrorResultException error)
+ {
+ if (!isDisconnectNotification
+ || !error.getResult().getResultCode().equals(ResultCode.BUSY)
+ || !error.getResult().getDiagnosticMessage().equals("test"))
+ {
+ errorMessage = "Missing disconnect notification: " + error;
+ }
+ closeLatch.countDown();
+ }
+ };
+
+ connection.addConnectionEventListener(listener);
+ Assert.assertEquals(listener.closeLatch.getCount(), 1);
+ onlineServerConnection.context.disconnect(ResultCode.BUSY, "test");
+ listener.closeLatch.await();
+ Assert.assertNull(listener.errorMessage);
+ connection.close();
+ }
+ finally
+ {
+ onlineServerListener.close();
+ }
+ }
}
--
Gitblit v1.10.0