From fa59221ed4c2777097b0fd1a38c6839d60680499 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Fri, 04 Dec 2009 11:12:28 +0000
Subject: [PATCH] Merge Bo's most recent changes.
---
opendj-sdk/sdk/src/org/opends/sdk/AbstractConnectionFactory.java | 4
opendj-sdk/sdk/src/org/opends/sdk/ConnectionException.java | 40 ++
opendj-sdk/sdk/src/org/opends/sdk/OperationTimeoutException.java | 41 ++
opendj-sdk/sdk/src/org/opends/sdk/AbstractConnection.java | 6
opendj-sdk/sdk/src/org/opends/sdk/ErrorResultException.java | 18
opendj-sdk/sdk/src/org/opends/sdk/ldap/LDAPConnection.java | 193 +++++----
opendj-sdk/sdk/src/org/opends/sdk/CancelledException.java | 41 ++
opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java | 12
opendj-sdk/sdk/src/org/opends/sdk/Connection.java | 4
opendj-sdk/sdk/src/org/opends/sdk/ldap/AbstractResultFutureImpl.java | 6
opendj-sdk/sdk/src/org/opends/sdk/AsynchronousConnection.java | 21
opendj-sdk/sdk/src/org/opends/sdk/ldap/ConnectionPool.java | 438 +++++++++++++++++++++
opendj-sdk/sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java | 360 ++++++++++++++++++
opendj-sdk/sdk/src/org/opends/sdk/SynchronousConnection.java | 5
14 files changed, 1,083 insertions(+), 106 deletions(-)
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnection.java b/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnection.java
index 0f29a4c..b36f3cf 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnection.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnection.java
@@ -254,10 +254,10 @@
{
// Got more entries than expected.
Result result = Responses.newResult(
- ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
+ ResultCode.CLIENT_SIDE_MORE_RESULTS_TO_RETURN).setDiagnosticMessage(
ERR_UNEXPECTED_SEARCH_RESULT_ENTRIES.get(handler.entryCount)
.toString());
- throw new ErrorResultException(result);
+ throw ErrorResultException.wrap(result);
}
else if (handler.firstReference != null)
{
@@ -267,7 +267,7 @@
ERR_UNEXPECTED_SEARCH_RESULT_REFERENCES.get(
handler.firstReference.getURIs().iterator().next())
.toString());
- throw new ErrorResultException(result);
+ throw ErrorResultException.wrap(result);
}
else
{
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnectionFactory.java b/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnectionFactory.java
index f80baf0..93fb7c4 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnectionFactory.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/AbstractConnectionFactory.java
@@ -116,10 +116,10 @@
future.cancel(false);
Result result =
- Responses.newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR)
+ Responses.newResult(ResultCode.CLIENT_SIDE_CONNECT_ERROR)
.setCause(e)
.setDiagnosticMessage(e.getLocalizedMessage());
- throw new ErrorResultException(result);
+ throw ErrorResultException.wrap(result);
}
}
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/AsynchronousConnection.java b/opendj-sdk/sdk/src/org/opends/sdk/AsynchronousConnection.java
index ac0837c..89c3c06 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/AsynchronousConnection.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/AsynchronousConnection.java
@@ -32,8 +32,9 @@
import java.io.Closeable;
import org.opends.sdk.requests.*;
-import org.opends.sdk.responses.*;
-
+import org.opends.sdk.responses.BindResult;
+import org.opends.sdk.responses.CompareResult;
+import org.opends.sdk.responses.Result;
/**
@@ -260,12 +261,12 @@
* @param request
* The unbind request to use in the case where a physical
* connection is closed.
+ * @param reason
+ * A reason describing why the connection was closed.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
- void close(UnbindRequest request) throws NullPointerException;
-
-
+ void close(UnbindRequest request, String reason);
/**
* Compares an entry in the Directory Server using the provided
@@ -492,4 +493,14 @@
*/
void removeConnectionEventListener(ConnectionEventListener listener)
throws NullPointerException;
+
+
+ /**
+ * Returns <code>true</code> if the connection is closed for
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if the connection is closed for
+ * <code>false</code> otherwise.
+ */
+ boolean isClosed();
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java b/opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java
index 1bb8ed5..08d91f6 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/AuthenticatedConnectionFactory.java
@@ -105,6 +105,7 @@
ConnectionResultHandler<? super AuthenticatedAsynchronousConnection, P> handler,
P p)
{
+ // TODO: bug here? if allowRebind= false then bind will never happen
ConnectionFutureImpl<P> future = new ConnectionFutureImpl<P>(
allowRebinds ? request : null, handler, p);
future.connectFuture = parentFactory.getAsynchronousConnection(
@@ -315,10 +316,10 @@
- public void close(UnbindRequest request)
+ public void close(UnbindRequest request, String reason)
throws NullPointerException
{
- connection.close(request);
+ connection.close(request, reason);
}
@@ -463,6 +464,13 @@
searchResulthandler, p);
}
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isClosed()
+ {
+ return connection.isClosed();
+ }
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/CancelledException.java b/opendj-sdk/sdk/src/org/opends/sdk/CancelledException.java
new file mode 100644
index 0000000..72ef73b
--- /dev/null
+++ b/opendj-sdk/sdk/src/org/opends/sdk/CancelledException.java
@@ -0,0 +1,41 @@
+/*
+ * 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 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.sdk;
+
+import org.opends.sdk.responses.Result;
+
+/**
+ * Created by IntelliJ IDEA. User: boli Date: Dec 2, 2009 Time: 12:25:31 PM To
+ * change this template use File | Settings | File Templates.
+ */
+public class CancelledException extends ErrorResultException
+{
+ public CancelledException(Result result) {
+ super(result);
+ }
+}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/Connection.java b/opendj-sdk/sdk/src/org/opends/sdk/Connection.java
index a4be674..5e82780 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/Connection.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/Connection.java
@@ -303,10 +303,12 @@
* @param request
* The unbind request to use in the case where a physical
* connection is closed.
+ * @param reason
+ * A reason describing why the connection was closed.
* @throws NullPointerException
* If {@code request} was {@code null}.
*/
- void close(UnbindRequest request) throws NullPointerException;
+ void close(UnbindRequest request, String reason) throws NullPointerException;
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/ConnectionException.java b/opendj-sdk/sdk/src/org/opends/sdk/ConnectionException.java
new file mode 100644
index 0000000..eaffa68
--- /dev/null
+++ b/opendj-sdk/sdk/src/org/opends/sdk/ConnectionException.java
@@ -0,0 +1,40 @@
+/*
+ * 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 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.sdk;
+
+import org.opends.sdk.responses.Result;
+
+/**
+ * Created by IntelliJ IDEA. User: boli Date: Dec 1, 2009 Time: 2:31:58 PM To
+ * change this template use File | Settings | File Templates.
+ */
+public class ConnectionException extends ErrorResultException {
+ public ConnectionException(Result result) {
+ super(result);
+ }
+}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/ErrorResultException.java b/opendj-sdk/sdk/src/org/opends/sdk/ErrorResultException.java
index 5a4d7dc..9eee0d5 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/ErrorResultException.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/ErrorResultException.java
@@ -70,6 +70,24 @@
// TODO: choose type of exception based on result code (e.g.
// referral).
+ if(result.getResultCode() == ResultCode.CLIENT_SIDE_SERVER_DOWN ||
+ result.getResultCode() == ResultCode.CLIENT_SIDE_CONNECT_ERROR ||
+ result.getResultCode() == ResultCode.CLIENT_SIDE_DECODING_ERROR ||
+ result.getResultCode() == ResultCode.CLIENT_SIDE_ENCODING_ERROR)
+ {
+ return new ConnectionException(result);
+ }
+
+ if(result.getResultCode() == ResultCode.CLIENT_SIDE_TIMEOUT)
+ {
+ return new OperationTimeoutException(result);
+ }
+
+ if(result.getResultCode() == ResultCode.CLIENT_SIDE_USER_CANCELLED)
+ {
+ return new CancelledException(result);
+ }
+
return new ErrorResultException(result);
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java b/opendj-sdk/sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java
new file mode 100644
index 0000000..83133c1
--- /dev/null
+++ b/opendj-sdk/sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java
@@ -0,0 +1,360 @@
+/*
+ * 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 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.sdk;
+
+import org.opends.sdk.responses.*;
+import org.opends.sdk.requests.*;
+import org.opends.sdk.util.Validator;
+
+import java.util.List;
+import java.util.LinkedList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * An heart beat connection factory can be used to create
+ * connections that sends a periodic search request to a Directory Server.
+ */
+public class HeartBeatConnectionFactory
+ extends AbstractConnectionFactory<
+ HeartBeatConnectionFactory.HeartBeatAsynchronousConnection> {
+ private final SearchRequest heartBeat;
+ private final int interval;
+ private final List<HeartBeatAsynchronousConnection> activeConnections;
+ private final ConnectionFactory<?> parentFactory;
+
+ private boolean stopRequested;
+
+ public HeartBeatConnectionFactory(
+ ConnectionFactory<?> parentFactory,
+ int interval) {
+ this(parentFactory, Requests.newSearchRequest("", SearchScope.BASE_OBJECT,
+ "(objectClass=*)", "1.1"), interval);
+ }
+
+ public HeartBeatConnectionFactory(
+ ConnectionFactory<?> parentFactory,
+ SearchRequest heartBeat, int interval) {
+ Validator.ensureNotNull(parentFactory, heartBeat);
+ this.heartBeat = heartBeat;
+ this.interval = interval;
+ this.activeConnections = new LinkedList<HeartBeatAsynchronousConnection>();
+ this.parentFactory = parentFactory;
+
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ stopRequested = true;
+ }
+ });
+
+ new HeartBeatThread().start();
+ }
+
+ /**
+ * An asynchronous connection that sends heart beats and supports all
+ * operations.
+ */
+ public final class HeartBeatAsynchronousConnection
+ implements AsynchronousConnection, ConnectionEventListener,
+ ResultHandler<Result, Void> {
+ private final AsynchronousConnection connection;
+
+ public HeartBeatAsynchronousConnection(AsynchronousConnection connection) {
+ this.connection = connection;
+ }
+
+ public void abandon(AbandonRequest request)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ connection.abandon(request);
+ }
+
+ public <P> ResultFuture<Result> add(
+ AddRequest request,
+ ResultHandler<Result, P> handler, P p)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ return connection.add(request, handler, p);
+ }
+
+ public <P> ResultFuture<BindResult> bind(
+ BindRequest request, ResultHandler<? super BindResult, P> handler, P p)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ return connection.bind(request, handler, p);
+ }
+
+ public void close() {
+ synchronized (activeConnections) {
+ connection.removeConnectionEventListener(this);
+ activeConnections.remove(this);
+ }
+ connection.close();
+ }
+
+ public void close(UnbindRequest request, String reason)
+ throws NullPointerException {
+ synchronized (activeConnections) {
+ connection.removeConnectionEventListener(this);
+ activeConnections.remove(this);
+ }
+ connection.close(request, reason);
+ }
+
+ public <P> ResultFuture<CompareResult> compare(
+ CompareRequest request, ResultHandler<? super CompareResult, P> handler,
+ P p) throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ return connection.compare(request, handler, p);
+ }
+
+ public <P> ResultFuture<Result> delete(
+ DeleteRequest request,
+ ResultHandler<Result, P> handler,
+ P p)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ return connection.delete(request, handler, p);
+ }
+
+ public <R extends Result, P> ResultFuture<R> extendedRequest(
+ ExtendedRequest<R> request, ResultHandler<? super R, P> handler, P p)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ return connection.extendedRequest(request, handler, p);
+ }
+
+ public <P> ResultFuture<Result> modify(
+ ModifyRequest request,
+ ResultHandler<Result, P> handler,
+ P p)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ return connection.modify(request, handler, p);
+ }
+
+ public <P> ResultFuture<Result> modifyDN(
+ ModifyDNRequest request,
+ ResultHandler<Result, P> handler,
+ P p)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ return connection.modifyDN(request, handler, p);
+ }
+
+ public <P> ResultFuture<Result> search(
+ SearchRequest request, ResultHandler<Result, P> resultHandler,
+ SearchResultHandler<P> searchResultHandler, P p)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ return connection.search(request, resultHandler, searchResultHandler, p);
+ }
+
+ public void addConnectionEventListener(ConnectionEventListener listener)
+ throws IllegalStateException, NullPointerException {
+ connection.addConnectionEventListener(listener);
+ }
+
+ public void removeConnectionEventListener(ConnectionEventListener listener)
+ throws NullPointerException {
+ connection.removeConnectionEventListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isClosed()
+ {
+ return connection.isClosed();
+ }
+
+ public void connectionReceivedUnsolicitedNotification(
+ GenericExtendedResult notification) {
+ // Do nothing
+ }
+
+ public void connectionErrorOccurred(
+ boolean isDisconnectNotification,
+ ErrorResultException error) {
+ synchronized (activeConnections) {
+ connection.removeConnectionEventListener(this);
+ activeConnections.remove(this);
+ }
+ }
+
+ public void handleErrorResult(Void aVoid, ErrorResultException error) {
+ // TODO: I18N
+ if(error instanceof OperationTimeoutException)
+ {
+ close(Requests.newUnbindRequest(), "Heart beat timed out");
+ }
+ }
+
+ public void handleResult(Void aVoid, Result result) {
+ // Do nothing
+ }
+
+ private void sendHeartBeat() {
+ search(heartBeat, this, null, null);
+ }
+ }
+
+ private final class HeartBeatThread extends Thread {
+ private HeartBeatThread() {
+ super("Heart Beat Thread");
+ }
+
+ public void run() {
+ while (!stopRequested) {
+ synchronized (activeConnections) {
+ for (HeartBeatAsynchronousConnection connection : activeConnections) {
+ connection.sendHeartBeat();
+ }
+ }
+ try {
+ sleep(interval);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+ }
+ }
+
+ private final class ConnectionFutureImpl<P> implements
+ ConnectionFuture<HeartBeatAsynchronousConnection>,
+ ConnectionResultHandler<AsynchronousConnection, Void> {
+ private volatile HeartBeatAsynchronousConnection heartBeatConnection;
+
+ private volatile ErrorResultException exception;
+
+ private volatile ConnectionFuture<?> connectFuture;
+
+ private final CountDownLatch latch = new CountDownLatch(1);
+
+ private final
+ ConnectionResultHandler<? super HeartBeatAsynchronousConnection, P> handler;
+
+ private final P p;
+
+ private boolean cancelled;
+
+
+ private ConnectionFutureImpl(
+ ConnectionResultHandler<
+ ? super HeartBeatAsynchronousConnection, P> handler,
+ P p) {
+ this.handler = handler;
+ this.p = p;
+ }
+
+
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ cancelled = connectFuture.cancel(mayInterruptIfRunning);
+ if (cancelled) {
+ latch.countDown();
+ }
+ return cancelled;
+ }
+
+
+ public HeartBeatAsynchronousConnection get()
+ throws InterruptedException, ErrorResultException {
+ latch.await();
+ if (cancelled) {
+ throw new CancellationException();
+ }
+ if (exception != null) {
+ throw exception;
+ }
+ return heartBeatConnection;
+ }
+
+
+ public HeartBeatAsynchronousConnection get(
+ long timeout,
+ TimeUnit unit) throws InterruptedException, TimeoutException,
+ ErrorResultException {
+ latch.await(timeout, unit);
+ if (cancelled) {
+ throw new CancellationException();
+ }
+ if (exception != null) {
+ throw exception;
+ }
+ return heartBeatConnection;
+ }
+
+
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+
+ public boolean isDone() {
+ return latch.getCount() == 0;
+ }
+
+
+ public void handleConnection(
+ Void v,
+ AsynchronousConnection connection) {
+ heartBeatConnection = new HeartBeatAsynchronousConnection(connection);
+ synchronized (activeConnections) {
+ connection.addConnectionEventListener(heartBeatConnection);
+ activeConnections.add(heartBeatConnection);
+ }
+ if (handler != null) {
+ handler.handleConnection(p, heartBeatConnection);
+ }
+ latch.countDown();
+ }
+
+
+ public void handleConnectionError(Void v, ErrorResultException error) {
+ exception = error;
+ if (handler != null) {
+ handler.handleConnectionError(p, error);
+ }
+ latch.countDown();
+ }
+ }
+
+ public <P> ConnectionFuture<? extends HeartBeatAsynchronousConnection>
+ getAsynchronousConnection(
+ ConnectionResultHandler<? super
+ HeartBeatAsynchronousConnection, P> pConnectionResultHandler, P p) {
+ ConnectionFutureImpl<P> future =
+ new ConnectionFutureImpl<P>(pConnectionResultHandler, p);
+ future.connectFuture =
+ parentFactory.getAsynchronousConnection(future, null);
+ return future;
+ }
+}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/OperationTimeoutException.java b/opendj-sdk/sdk/src/org/opends/sdk/OperationTimeoutException.java
new file mode 100644
index 0000000..dfaca1e
--- /dev/null
+++ b/opendj-sdk/sdk/src/org/opends/sdk/OperationTimeoutException.java
@@ -0,0 +1,41 @@
+/*
+ * 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 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.sdk;
+
+import org.opends.sdk.responses.Result;
+
+/**
+ * Created by IntelliJ IDEA. User: boli Date: Dec 2, 2009 Time: 1:28:13 PM To
+ * change this template use File | Settings | File Templates.
+ */
+public class OperationTimeoutException extends ErrorResultException
+{
+ public OperationTimeoutException(Result result) {
+ super(result);
+ }
+}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/SynchronousConnection.java b/opendj-sdk/sdk/src/org/opends/sdk/SynchronousConnection.java
index b648053..81bf207 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/SynchronousConnection.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/SynchronousConnection.java
@@ -122,9 +122,10 @@
- public void close(UnbindRequest request) throws NullPointerException
+ public void close(UnbindRequest request, String reason)
+ throws NullPointerException
{
- connection.close(request);
+ connection.close(request, reason);
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/ldap/AbstractResultFutureImpl.java b/opendj-sdk/sdk/src/org/opends/sdk/ldap/AbstractResultFutureImpl.java
index 6bd5050..3111494 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/ldap/AbstractResultFutureImpl.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/ldap/AbstractResultFutureImpl.java
@@ -38,6 +38,7 @@
import org.opends.sdk.ResultHandler;
import org.opends.sdk.requests.Requests;
import org.opends.sdk.responses.Result;
+import org.opends.sdk.responses.Responses;
import org.opends.sdk.util.StaticUtils;
@@ -241,11 +242,12 @@
- private R get0() throws CancellationException, ErrorResultException
+ private R get0() throws ErrorResultException
{
if (isCancelled())
{
- throw new CancellationException();
+ throw ErrorResultException.wrap(
+ Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED));
}
else if (result.getResultCode().isExceptional())
{
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/ldap/ConnectionPool.java b/opendj-sdk/sdk/src/org/opends/sdk/ldap/ConnectionPool.java
new file mode 100644
index 0000000..f97356e
--- /dev/null
+++ b/opendj-sdk/sdk/src/org/opends/sdk/ldap/ConnectionPool.java
@@ -0,0 +1,438 @@
+/*
+ * 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 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.sdk.ldap;
+
+import org.opends.sdk.*;
+import org.opends.sdk.util.StaticUtils;
+import org.opends.sdk.responses.Result;
+import org.opends.sdk.responses.BindResult;
+import org.opends.sdk.responses.CompareResult;
+import org.opends.sdk.responses.GenericExtendedResult;
+import org.opends.sdk.requests.*;
+
+import java.util.concurrent.*;
+import java.util.Queue;
+import java.util.Stack;
+import java.util.logging.Level;
+
+/**
+ * Created by IntelliJ IDEA. User: digitalperk Date: Nov 25, 2009 Time: 11:12:29
+ * AM To change this template use File | Settings | File Templates.
+ */
+public class ConnectionPool
+ extends AbstractConnectionFactory<AsynchronousConnection> {
+ private final ConnectionFactory<?> connectionFactory;
+ private volatile int numConnections;
+ private final int poolSize;
+ private final Stack<AsynchronousConnection> pool;
+ private final ConcurrentLinkedQueue<PendingConnectionFuture> pendingFutures;
+ private final Object lock = new Object();
+
+ private class PooledConnectionWapper
+ implements AsynchronousConnection, ConnectionEventListener {
+ private AsynchronousConnection connection;
+
+ private PooledConnectionWapper(AsynchronousConnection connection) {
+ this.connection = connection;
+ this.connection.addConnectionEventListener(this);
+ }
+
+ public void abandon(AbandonRequest request)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ if (connection == null) {
+ throw new IllegalStateException();
+ }
+ connection.abandon(request);
+ }
+
+ public <P> ResultFuture<Result> add(
+ AddRequest request,
+ ResultHandler<Result, P> handler, P p)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ if (connection == null) {
+ throw new IllegalStateException();
+ }
+ return connection.add(request, handler, p);
+ }
+
+ public <P> ResultFuture<BindResult> bind(
+ BindRequest request, ResultHandler<? super BindResult, P> handler, P p)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ if (connection == null) {
+ throw new IllegalStateException();
+ }
+ return connection.bind(request, handler, p);
+ }
+
+ public void close() {
+ synchronized (lock) {
+ try {
+ // Don't put closed connections back in the pool.
+ if (connection.isClosed()) {
+ if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
+ {
+ StaticUtils.DEBUG_LOG.finest(String
+ .format("Dead connection released to pool. " +
+ "numConnections: %d, poolSize: %d, pendingFutures: %d",
+ numConnections, pool.size(), pendingFutures.size()));
+ }
+ return;
+ }
+
+ // See if there waiters pending
+ PendingConnectionFuture future = pendingFutures.poll();
+ if (future != null) {
+ PooledConnectionWapper pooledConnection =
+ new PooledConnectionWapper(connection);
+ future.connection(pooledConnection);
+ if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
+ {
+ StaticUtils.DEBUG_LOG.finest(String
+ .format("Connection released to pool and directly " +
+ "given to waiter. numConnections: %d, poolSize: %d, " +
+ "pendingFutures: %d", numConnections, pool.size(),
+ pendingFutures.size()));
+ }
+ return;
+ }
+
+ // No waiters. Put back in pool.
+ pool.push(connection);
+ if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
+ {
+ StaticUtils.DEBUG_LOG.finest(String
+ .format("Connection released to pool. " +
+ "numConnections: %d, poolSize: %d, pendingFutures: %d",
+ numConnections, pool.size(), pendingFutures.size()));
+ }
+ }
+ finally {
+ // Null out the underlying connection to prevent further use.
+ connection = null;
+ }
+ }
+ }
+
+ public void close(UnbindRequest request, String reason)
+ throws NullPointerException {
+ close();
+ }
+
+ public <P> ResultFuture<CompareResult> compare(
+ CompareRequest request, ResultHandler<? super CompareResult, P> handler,
+ P p) throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ if (connection == null) {
+ throw new IllegalStateException();
+ }
+ return connection.compare(request, handler, p);
+ }
+
+ public <P> ResultFuture<Result> delete(
+ DeleteRequest request, ResultHandler<Result, P> handler, P p)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ if (connection == null) {
+ throw new IllegalStateException();
+ }
+ return connection.delete(request, handler, p);
+ }
+
+ public <R extends Result, P> ResultFuture<R> extendedRequest(
+ ExtendedRequest<R> request, ResultHandler<? super R, P> handler, P p)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ if (connection == null) {
+ throw new IllegalStateException();
+ }
+ return connection.extendedRequest(request, handler, p);
+ }
+
+ public <P> ResultFuture<Result> modify(
+ ModifyRequest request, ResultHandler<Result, P> handler, P p)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ if (connection == null) {
+ throw new IllegalStateException();
+ }
+ return connection.modify(request, handler, p);
+ }
+
+ public <P> ResultFuture<Result> modifyDN(
+ ModifyDNRequest request, ResultHandler<Result, P> handler, P p)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ if (connection == null) {
+ throw new IllegalStateException();
+ }
+ return connection.modifyDN(request, handler, p);
+ }
+
+ public <P> ResultFuture<Result> search(
+ SearchRequest request, ResultHandler<Result, P> resultHandler,
+ SearchResultHandler<P> searchResulthandler, P p)
+ throws UnsupportedOperationException, IllegalStateException,
+ NullPointerException {
+ if (connection == null) {
+ throw new IllegalStateException();
+ }
+ return connection.search(request, resultHandler, searchResulthandler, p);
+ }
+
+ public void addConnectionEventListener(ConnectionEventListener listener)
+ throws IllegalStateException, NullPointerException {
+ if (connection == null) {
+ throw new IllegalStateException();
+ }
+ }
+
+ public void removeConnectionEventListener(ConnectionEventListener listener)
+ throws NullPointerException {
+ if (connection == null) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isClosed()
+ {
+ return connection == null;
+ }
+
+ public void connectionReceivedUnsolicitedNotification(
+ GenericExtendedResult notification) {
+ // Ignore
+ }
+
+ public void connectionErrorOccurred(
+ boolean isDisconnectNotification, ErrorResultException error) {
+ synchronized (lock) {
+ // Remove this connection from the pool if its in there
+ pool.remove(this);
+ numConnections--;
+ connection.removeConnectionEventListener(this);
+ if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
+ {
+ StaticUtils.DEBUG_LOG.finest(String
+ .format("Connection error occured: " + error.getMessage() +
+ " numConnections: %d, poolSize: %d, pendingFutures: %d",
+ numConnections, pool.size(), pendingFutures.size()));
+ }
+ }
+ }
+ }
+
+ public class CompletedConnectionFuture
+ implements ConnectionFuture<AsynchronousConnection> {
+ private final PooledConnectionWapper connection;
+
+ public CompletedConnectionFuture(PooledConnectionWapper connection) {
+ this.connection = connection;
+ }
+
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ return false;
+ }
+
+ public AsynchronousConnection get()
+ throws InterruptedException, ErrorResultException {
+ return connection;
+ }
+
+ public AsynchronousConnection get(long timeout, TimeUnit unit)
+ throws InterruptedException, TimeoutException, ErrorResultException {
+ return connection;
+ }
+
+ public boolean isCancelled() {
+ return false;
+ }
+
+ public boolean isDone() {
+ return true;
+ }
+ }
+
+ public class PendingConnectionFuture<P>
+ implements ConnectionFuture<AsynchronousConnection> {
+ private volatile boolean isCancelled;
+ private volatile PooledConnectionWapper connection;
+ private volatile ErrorResultException err;
+ private final ConnectionResultHandler<? super AsynchronousConnection, P>
+ handler;
+ private final P p;
+ private final CountDownLatch latch = new CountDownLatch(1);
+
+ public PendingConnectionFuture() {
+ this.handler = null;
+ this.p = null;
+ }
+
+ public PendingConnectionFuture(
+ P p,
+ ConnectionResultHandler<? super AsynchronousConnection, P> handler) {
+ this.handler = handler;
+ this.p = p;
+ }
+
+ public synchronized boolean cancel(boolean mayInterruptIfRunning) {
+ return pendingFutures.remove(this) && (isCancelled = true);
+ }
+
+ public AsynchronousConnection get()
+ throws InterruptedException, ErrorResultException {
+ latch.await();
+ if (err != null) {
+ throw err;
+ }
+ return connection;
+ }
+
+ public AsynchronousConnection get(long timeout, TimeUnit unit)
+ throws InterruptedException, TimeoutException, ErrorResultException {
+ latch.await(timeout, unit);
+ if (err != null) {
+ throw err;
+ }
+ return connection;
+ }
+
+ public synchronized boolean isCancelled() {
+ return isCancelled;
+ }
+
+ public boolean isDone() {
+ return latch.getCount() == 0;
+ }
+
+ private void connection(PooledConnectionWapper connection) {
+ this.connection = connection;
+ if (handler != null) {
+ handler.handleConnection(p, connection);
+ }
+ latch.countDown();
+ }
+
+ private void error(ErrorResultException e) {
+ this.err = e;
+ if (handler != null) {
+ handler.handleConnectionError(p, e);
+ }
+ latch.countDown();
+ }
+ }
+
+ public ConnectionPool(ConnectionFactory<?> connectionFactory, int poolSize) {
+ this.connectionFactory = connectionFactory;
+ this.poolSize = poolSize;
+ this.pool = new Stack<AsynchronousConnection>();
+ this.pendingFutures = new ConcurrentLinkedQueue<PendingConnectionFuture>();
+ }
+
+ private class WrapConnectionResultHandler
+ implements ConnectionResultHandler<AsynchronousConnection, Void> {
+ private final PendingConnectionFuture future;
+
+ private WrapConnectionResultHandler(PendingConnectionFuture future) {
+ this.future = future;
+ }
+
+ public void handleConnection(
+ java.lang.Void p,
+ AsynchronousConnection connection) {
+ PooledConnectionWapper pooledConnection =
+ new PooledConnectionWapper(connection);
+ future.connection(pooledConnection);
+ }
+
+ public void handleConnectionError(
+ java.lang.Void p,
+ ErrorResultException error) {
+ future.error(error);
+ }
+ }
+
+ public <P> ConnectionFuture<AsynchronousConnection> getAsynchronousConnection(
+ ConnectionResultHandler<? super AsynchronousConnection, P> handler, P p) {
+ synchronized (lock) {
+ // Check to see if we have a connection in the pool
+
+
+ if (!pool.isEmpty()) {
+ AsynchronousConnection conn = pool.pop();
+ if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
+ {
+ StaticUtils.DEBUG_LOG.finest(String
+ .format("Connection aquired from pool. " +
+ "numConnections: %d, poolSize: %d, pendingFutures: %d",
+ numConnections, pool.size(), pendingFutures.size()));
+ }
+ PooledConnectionWapper pooledConnection =
+ new PooledConnectionWapper(conn);
+ if (handler != null) {
+ handler.handleConnection(p, pooledConnection);
+ }
+ return new CompletedConnectionFuture(pooledConnection);
+ }
+
+ PendingConnectionFuture<P> pendingFuture =
+ new PendingConnectionFuture<P>(p, handler);
+ // Pool was empty. Maybe a new connection if pool size is not reached
+ if (numConnections < poolSize) {
+ numConnections++;
+ WrapConnectionResultHandler wrapHandler =
+ new WrapConnectionResultHandler(pendingFuture);
+ connectionFactory.getAsynchronousConnection(wrapHandler, null);
+ if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
+ {
+ StaticUtils.DEBUG_LOG.finest(String
+ .format("New connection established and aquired. " +
+ "numConnections: %d, poolSize: %d, pendingFutures: %d",
+ numConnections, pool.size(), pendingFutures.size()));
+ }
+ } else {
+ // Have to wait
+ pendingFutures.add(pendingFuture);
+ if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
+ {
+ StaticUtils.DEBUG_LOG.finest(String
+ .format("No connections available. Wait-listed" +
+ "numConnections: %d, poolSize: %d, pendingFutures: %d",
+ numConnections, pool.size(), pendingFutures.size()));
+ }
+ }
+
+ return pendingFuture;
+ }
+ }
+}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/ldap/LDAPConnection.java b/opendj-sdk/sdk/src/org/opends/sdk/ldap/LDAPConnection.java
index b13e923..b2c71d6 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/ldap/LDAPConnection.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/ldap/LDAPConnection.java
@@ -38,6 +38,7 @@
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import javax.net.ssl.SSLContext;
@@ -130,11 +131,15 @@
saslContext.evaluateCredentials(result
.getServerSASLCredentials());
}
- catch (SaslException se)
+ catch (SaslException e)
{
pendingBindOrStartTLS = -1;
- Result errorResult = adaptException(se);
+ // FIXME: I18N need to have a better error message.
+ // FIXME: Is this the best result code?
+ Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
+ "An error occurred during SASL authentication").setCause(e);
future.handleErrorResult(errorResult);
return;
}
@@ -163,7 +168,10 @@
{
pendingRequests.remove(messageID);
- Result errorResult = adaptException(e);
+ // FIXME: what other sort of IOExceptions can be thrown?
+ // FIXME: Is this the best result code?
+ Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e);
connectionErrorOccurred(errorResult);
future.handleErrorResult(errorResult);
}
@@ -251,7 +259,20 @@
*/
public void handleException(Throwable throwable)
{
- Result errorResult = adaptException(throwable);
+ Result errorResult;
+ if(throwable instanceof EOFException)
+ {
+ // FIXME: Is this the best result code?
+ errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_SERVER_DOWN).setCause(throwable);
+ }
+ else
+ {
+ // FIXME: what other sort of IOExceptions can be thrown?
+ // FIXME: Is this the best result code?
+ errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_DECODING_ERROR).setCause(throwable);
+ }
connectionErrorOccurred(errorResult);
}
@@ -625,7 +646,8 @@
private boolean isClosed = false;
- private final List<ConnectionEventListener> listeners = new LinkedList<ConnectionEventListener>();
+ private final List<ConnectionEventListener> listeners =
+ new CopyOnWriteArrayList<ConnectionEventListener>();
private final AtomicInteger nextMsgID = new AtomicInteger(1);
@@ -702,7 +724,10 @@
}
catch (IOException e)
{
- Result errorResult = adaptException(e);
+ // FIXME: what other sort of IOExceptions can be thrown?
+ // FIXME: Is this the best result code?
+ Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e);
connectionErrorOccurred(errorResult);
}
}
@@ -754,7 +779,10 @@
{
pendingRequests.remove(messageID);
- Result errorResult = adaptException(e);
+ // FIXME: what other sort of IOExceptions can be thrown?
+ // FIXME: Is this the best result code?
+ Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e);
connectionErrorOccurred(errorResult);
future.handleErrorResult(errorResult);
}
@@ -847,7 +875,11 @@
}
catch (SaslException e)
{
- Result errorResult = adaptException(e);
+ // FIXME: I18N need to have a better error message.
+ // FIXME: Is this the best result code?
+ Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
+ "An error occurred during SASL authentication").setCause(e);
future.handleErrorResult(errorResult);
return future;
}
@@ -860,7 +892,8 @@
else
{
pendingRequests.remove(messageID);
- future.handleResult(Responses.newBindResult(ResultCode.PROTOCOL_ERROR)
+ future.handleResult(Responses.newBindResult(
+ ResultCode.CLIENT_SIDE_AUTH_UNKNOWN)
.setDiagnosticMessage("Auth type not supported"));
}
asn1Writer.flush();
@@ -869,7 +902,10 @@
{
pendingRequests.remove(messageID);
- Result errorResult = adaptException(e);
+ // FIXME: what other sort of IOExceptions can be thrown?
+ // FIXME: Is this the best result code?
+ Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e);
connectionErrorOccurred(errorResult);
future.handleErrorResult(errorResult);
}
@@ -890,25 +926,25 @@
*/
public void close()
{
- close(Requests.newUnbindRequest());
+ close(Requests.newUnbindRequest(), null);
}
-
/**
* {@inheritDoc}
*/
- public void close(UnbindRequest request) throws NullPointerException
- {
+ public void close(UnbindRequest request, String reason)
+ throws NullPointerException {
// FIXME: I18N need to internationalize this message.
Validator.ensureNotNull(request);
- close(request, false, Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED)
- .setDiagnosticMessage("Connection closed by client"));
+ close(request, false,
+ Responses.newResult(ResultCode.CLIENT_SIDE_USER_CANCELLED)
+ .setDiagnosticMessage("Connection closed by client" +
+ (reason != null ? ": " + reason : "")));
}
-
/**
* {@inheritDoc}
*/
@@ -950,7 +986,10 @@
{
pendingRequests.remove(messageID);
- Result errorResult = adaptException(e);
+ // FIXME: what other sort of IOExceptions can be thrown?
+ // FIXME: Is this the best result code?
+ Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e);
connectionErrorOccurred(errorResult);
future.handleErrorResult(errorResult);
}
@@ -1005,7 +1044,10 @@
{
pendingRequests.remove(messageID);
- Result errorResult = adaptException(e);
+ // FIXME: what other sort of IOExceptions can be thrown?
+ // FIXME: Is this the best result code?
+ Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e);
connectionErrorOccurred(errorResult);
future.handleErrorResult(errorResult);
}
@@ -1081,7 +1123,10 @@
{
pendingRequests.remove(messageID);
- Result errorResult = adaptException(e);
+ // FIXME: what other sort of IOExceptions can be thrown?
+ // FIXME: Is this the best result code?
+ Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e);
connectionErrorOccurred(errorResult);
future.handleErrorResult(errorResult);
}
@@ -1136,7 +1181,10 @@
{
pendingRequests.remove(messageID);
- Result errorResult = adaptException(e);
+ // FIXME: what other sort of IOExceptions can be thrown?
+ // FIXME: Is this the best result code?
+ Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e);
connectionErrorOccurred(errorResult);
future.handleErrorResult(errorResult);
}
@@ -1191,7 +1239,10 @@
{
pendingRequests.remove(messageID);
- Result errorResult = adaptException(e);
+ // FIXME: what other sort of IOExceptions can be thrown?
+ // FIXME: Is this the best result code?
+ Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e);
connectionErrorOccurred(errorResult);
future.handleErrorResult(errorResult);
}
@@ -1264,7 +1315,10 @@
{
pendingRequests.remove(messageID);
- Result errorResult = adaptException(e);
+ // FIXME: what other sort of IOExceptions can be thrown?
+ // FIXME: Is this the best result code?
+ Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_ENCODING_ERROR).setCause(e);
connectionErrorOccurred(errorResult);
future.handleErrorResult(errorResult);
}
@@ -1307,57 +1361,6 @@
- private Result adaptException(Throwable t)
- {
- if (t instanceof ExecutionException)
- {
- ExecutionException e = (ExecutionException) t;
- t = e.getCause();
- }
-
- Result errorResult;
-
- try
- {
- throw t;
- }
- catch (SaslException e)
- {
- // FIXME: I18N need to have a better error message.
- // FIXME: Is this the best result code?
- errorResult = Responses.newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
- "An error occurred during SASL authentication").setCause(e);
- }
- catch (EOFException e)
- {
- // FIXME: I18N need to have a better error message.
- // FIXME: what sort of IOExceptions can be thrown?
- // FIXME: Is this the best result code?
- errorResult = Responses.newResult(ResultCode.CLIENT_SIDE_SERVER_DOWN).setDiagnosticMessage(
- "Connection unexpectedly terminated by server").setCause(e);
- }
- catch (IOException e)
- {
- // FIXME: I18N need to have a better error message.
- // FIXME: what sort of IOExceptions can be thrown?
- // FIXME: Is this the best result code?
- errorResult = Responses.newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
- "An error occurred whilst attempting to send a request: "
- + e.toString()).setCause(e);
- }
- catch (Throwable e)
- {
- // FIXME: I18N need to have a better error message.
- // FIXME: Is this the best result code?
- errorResult = Responses.newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR).setDiagnosticMessage(
- "An unknown error occurred: " + e.toString()).setCause(e);
- }
-
- return errorResult;
- }
-
-
-
private void close(UnbindRequest unbindRequest,
boolean isDisconnectNotification, Result reason)
{
@@ -1489,8 +1492,8 @@
{
for (ConnectionEventListener listener : listeners)
{
- listener.connectionErrorOccurred(false, ErrorResultException
- .wrap(reason));
+ listener.connectionErrorOccurred(isDisconnectNotification,
+ ErrorResultException.wrap(reason));
}
}
}
@@ -1506,16 +1509,16 @@
// TODO uncomment if we decide these methods are useful.
- // /**
- // * {@inheritDoc}
- // */
- // public boolean isClosed()
- // {
- // synchronized (writeLock)
- // {
- // return isClosed;
- // }
- // }
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isClosed()
+ {
+ synchronized (writeLock)
+ {
+ return isClosed;
+ }
+ }
//
//
//
@@ -1645,11 +1648,23 @@
sslHandshaker.handshake(reader, writer, sslEngineConfigurator)
.get();
}
+ catch (ExecutionException ee)
+ {
+ // FIXME: what other sort of IOExceptions can be thrown?
+ // FIXME: Is this the best result code?
+ Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_CONNECT_ERROR).setCause(ee.getCause());
+ connectionErrorOccurred(errorResult);
+ throw ErrorResultException.wrap(errorResult);
+ }
catch (Exception e)
{
- Result result = adaptException(e);
- connectionErrorOccurred(result);
- throw ErrorResultException.wrap(result);
+ // FIXME: what other sort of IOExceptions can be thrown?
+ // FIXME: Is this the best result code?
+ Result errorResult = Responses.newResult(
+ ResultCode.CLIENT_SIDE_CONNECT_ERROR).setCause(e);
+ connectionErrorOccurred(errorResult);
+ throw ErrorResultException.wrap(errorResult);
}
}
--
Gitblit v1.10.0