From 62928746caae4f80dbb4cac71cf6b78a93d60f25 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Thu, 21 Jan 2010 14:56:10 +0000
Subject: [PATCH] Hide LB classes for now and expose only constructors via Connections class.
---
/dev/null | 196 -----------------
opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingConnectionFactory.java | 52 +++-
opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java | 245 +++++++++++++++++++++
opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingAlgorithm.java | 46 +++
opendj-sdk/sdk/src/org/opends/sdk/Connections.java | 106 +++++++-
5 files changed, 404 insertions(+), 241 deletions(-)
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/AbstractLoadBalancingAlgorithm.java b/opendj-sdk/sdk/src/org/opends/sdk/AbstractLoadBalancingAlgorithm.java
deleted file mode 100644
index 099d4db..0000000
--- a/opendj-sdk/sdk/src/org/opends/sdk/AbstractLoadBalancingAlgorithm.java
+++ /dev/null
@@ -1,196 +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 2009 Sun Microsystems, Inc.
- */
-
-package org.opends.sdk;
-
-
-
-import com.sun.opends.sdk.util.Validator;
-import com.sun.opends.sdk.util.StaticUtils;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.logging.Level;
-
-
-
-/**
- * Created by IntelliJ IDEA. User: digitalperk Date: Dec 15, 2009 Time:
- * 3:49:17 PM To change this template use File | Settings | File
- * Templates.
- */
-public abstract class AbstractLoadBalancingAlgorithm implements
- LoadBalancingAlgorithm
-{
- protected final List<MonitoredConnectionFactory> factoryList;
-
-
-
- protected AbstractLoadBalancingAlgorithm(
- ConnectionFactory... factories)
- {
- Validator.ensureNotNull((Object[]) factories);
- factoryList = new ArrayList<MonitoredConnectionFactory>(
- factories.length);
- for (ConnectionFactory f : factories)
- {
- factoryList.add(new MonitoredConnectionFactory(f));
- }
-
- new MonitorThread().start();
- }
-
-
-
- protected class MonitoredConnectionFactory extends
- AbstractConnectionFactory implements
- ResultHandler<AsynchronousConnection>
- {
- private final ConnectionFactory factory;
-
- private volatile boolean isOperational;
-
- private volatile FutureResult<?> pendingConnectFuture;
-
-
-
- private MonitoredConnectionFactory(ConnectionFactory factory)
- {
- this.factory = factory;
- this.isOperational = true;
- }
-
-
-
- public boolean isOperational()
- {
- return isOperational;
- }
-
-
-
- public void handleErrorResult(ErrorResultException error)
- {
- isOperational = false;
- }
-
-
-
- public void handleResult(AsynchronousConnection result)
- {
- isOperational = true;
- // TODO: Notify the server is back up
- result.close();
- }
-
-
-
- public FutureResult<AsynchronousConnection> getAsynchronousConnection(
- final ResultHandler<AsynchronousConnection> resultHandler)
- {
- ResultHandler<AsynchronousConnection> handler = new ResultHandler<AsynchronousConnection>()
- {
- public void handleErrorResult(ErrorResultException error)
- {
- isOperational = false;
- if (resultHandler != null)
- {
- resultHandler.handleErrorResult(error);
- }
- if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING))
- {
- StaticUtils.DEBUG_LOG.warning(String
- .format("Connection factory " + factory
- + " is no longer operational: "
- + error.getMessage()));
- }
- }
-
-
-
- public void handleResult(AsynchronousConnection result)
- {
- isOperational = true;
- if (resultHandler != null)
- {
- resultHandler.handleResult(result);
- }
- if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING))
- {
- StaticUtils.DEBUG_LOG.warning(String
- .format("Connection factory " + factory
- + " is now operational"));
- }
- }
- };
- return factory.getAsynchronousConnection(handler);
- }
- }
-
-
-
- private class MonitorThread extends Thread
- {
- private MonitorThread()
- {
- super("Connection Factory Health Monitor");
- this.setDaemon(true);
- }
-
-
-
- public void run()
- {
- while (true)
- {
- for (MonitoredConnectionFactory f : factoryList)
- {
- if (!f.isOperational
- && (f.pendingConnectFuture == null || f.pendingConnectFuture
- .isDone()))
- {
- if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
- {
- StaticUtils.DEBUG_LOG.finest(String
- .format("Attempting connect on factory " + f));
- }
- f.pendingConnectFuture = f.factory
- .getAsynchronousConnection(f);
- }
- }
- try
- {
- sleep(10000);
- }
- catch (InterruptedException e)
- {
- // Ignore and just go around again...
- }
- }
- }
- }
-}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/Connections.java b/opendj-sdk/sdk/src/org/opends/sdk/Connections.java
index c59148a..fd2b22b 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.Collection;
import java.util.concurrent.TimeUnit;
import org.opends.sdk.requests.BindRequest;
@@ -44,14 +45,6 @@
*/
public final class Connections
{
- // Prevent instantiation.
- private Connections()
- {
- // Do nothing.
- }
-
-
-
/**
* Creates a new authenticated connection factory which will obtain
* connections using the provided connection factory and immediately
@@ -113,18 +106,84 @@
/**
- * 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.
+ * Creates a new connection factory providing fault tolerance across
+ * multiple underlying connection factories.
+ * <p>
+ * The returned fail-over connection factory forwards connection
+ * requests to one of the provided connection factories. If the
+ * request fails for some reason (for example, due to network
+ * failure), then the fail-over connection factory switches to another
+ * connection faction, repeating the process until the connection
+ * request succeeds, or until all the connection factories are
+ * determined to be unavailable, in which case the connection request
+ * will fail.
+ * <p>
+ * The implementation periodically attempts to connect to failed
+ * connection factories in order to determine if they have become
+ * available again.
+ *
+ * @param factories
+ * The connection factories which will be used for fail-over.
+ * @return The new fail-over connection factory.
+ * @throws NullPointerException
+ * If {@code factories} was {@code null}.
+ */
+ public static ConnectionFactory newFailoverConnectionFactory(
+ Collection<ConnectionFactory> factories)
+ throws NullPointerException
+ {
+ FailoverLoadBalancingAlgorithm algorithm = new FailoverLoadBalancingAlgorithm(
+ factories);
+ return new LoadBalancingConnectionFactory(algorithm);
+ }
+
+
+
+ /**
+ * Creates a new connection factory providing fault tolerance across
+ * multiple underlying connection factories.
+ * <p>
+ * The returned fail-over connection factory forwards connection
+ * requests to one of the provided connection factories. If the
+ * request fails for some reason (for example, due to network
+ * failure), then the fail-over connection factory switches to another
+ * connection faction, repeating the process until the connection
+ * request succeeds, or until all the connection factories are
+ * determined to be unavailable, in which case the connection request
+ * will fail.
+ * <p>
+ * The implementation periodically attempts to connect to failed
+ * connection factories in order to determine if they have become
+ * available again.
+ *
+ * @param factories
+ * The connection factories which will be used for fail-over.
+ * @return The new fail-over connection factory.
+ * @throws NullPointerException
+ * If {@code factories} was {@code null}.
+ */
+ public static ConnectionFactory newFailoverConnectionFactory(
+ ConnectionFactory... factories) throws NullPointerException
+ {
+ FailoverLoadBalancingAlgorithm algorithm = new FailoverLoadBalancingAlgorithm(
+ factories);
+ return new LoadBalancingConnectionFactory(algorithm);
+ }
+
+
+
+ /**
+ * 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.
*
* @param factory
* The connection factory to use for creating connections.
* @param timeout
- * The time to wait between keepalive pings.
+ * The time to wait between keep-alive probes.
* @param unit
* The time unit of the timeout argument.
- * @return The heart-beat connection factory.
+ * @return The new heart-beat connection factory.
* @throws IllegalArgumentException
* If {@code timeout} was negative.
* @throws NullPointerException
@@ -143,20 +202,20 @@
/**
- * 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.
+ * 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.
*
* @param factory
* The connection factory to use for creating connections.
* @param timeout
- * The time to wait between keepalive pings.
+ * The time to wait between keep-alive probes.
* @param unit
* The time unit of the timeout argument.
* @param heartBeat
* The search request to use when pinging connections.
- * @return The heart-beat connection factory.
+ * @return The new heart-beat connection factory.
* @throws IllegalArgumentException
* If {@code timeout} was negative.
* @throws NullPointerException
@@ -175,4 +234,11 @@
heartBeat);
}
+
+
+ // Prevent instantiation.
+ private Connections()
+ {
+ // Do nothing.
+ }
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java b/opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java
index a057e76..2bbc581 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java
@@ -1,29 +1,258 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2010 Sun Microsystems, Inc.
+ */
+
package org.opends.sdk;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Level;
+
+import org.opends.sdk.responses.Responses;
+
+import com.sun.opends.sdk.util.StaticUtils;
+import com.sun.opends.sdk.util.Validator;
+
+
+
/**
- * Created by IntelliJ IDEA. User: digitalperk Date: Dec 15, 2009 Time:
- * 5:42:01 PM To change this template use File | Settings | File
- * Templates.
+ * A fail-over load balancing algorithm provides fault tolerance across
+ * multiple underlying connection factories.
+ * <p>
+ * If a problem occurs that temporarily prevents connections from being
+ * obtained for one of the connection factories, then this algorithm
+ * "fails over" to another operational connection factory in the list.
+ * If none of the connection factories are operational then a {@code
+ * ConnectionException} is returned to the client.
+ * <p>
+ * The implementation periodically attempts to connect to failed
+ * connection factories in order to determine if they have become
+ * available again.
*/
-public class FailoverLoadBalancingAlgorithm extends
- AbstractLoadBalancingAlgorithm
+class FailoverLoadBalancingAlgorithm implements LoadBalancingAlgorithm
{
+ private final List<MonitoredConnectionFactory> monitoredFactories;
+
+
+
+ private static final class MonitoredConnectionFactory extends
+ AbstractConnectionFactory implements
+ ResultHandler<AsynchronousConnection>
+ {
+ private final ConnectionFactory factory;
+
+ private volatile boolean isOperational;
+
+ private volatile FutureResult<?> pendingConnectFuture;
+
+
+
+ private MonitoredConnectionFactory(ConnectionFactory factory)
+ {
+ this.factory = factory;
+ this.isOperational = true;
+ }
+
+
+
+ private boolean isOperational()
+ {
+ return isOperational;
+ }
+
+
+
+ public void handleErrorResult(ErrorResultException error)
+ {
+ isOperational = false;
+ }
+
+
+
+ public void handleResult(AsynchronousConnection result)
+ {
+ isOperational = true;
+ // TODO: Notify the server is back up
+ result.close();
+ }
+
+
+
+ public FutureResult<AsynchronousConnection> getAsynchronousConnection(
+ final ResultHandler<AsynchronousConnection> resultHandler)
+ {
+ ResultHandler<AsynchronousConnection> handler = new ResultHandler<AsynchronousConnection>()
+ {
+ public void handleErrorResult(ErrorResultException error)
+ {
+ isOperational = false;
+ if (resultHandler != null)
+ {
+ resultHandler.handleErrorResult(error);
+ }
+ if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING))
+ {
+ StaticUtils.DEBUG_LOG.warning(String
+ .format("Connection factory " + factory
+ + " is no longer operational: "
+ + error.getMessage()));
+ }
+ }
+
+
+
+ public void handleResult(AsynchronousConnection result)
+ {
+ isOperational = true;
+ if (resultHandler != null)
+ {
+ resultHandler.handleResult(result);
+ }
+ if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING))
+ {
+ StaticUtils.DEBUG_LOG.warning(String
+ .format("Connection factory " + factory
+ + " is now operational"));
+ }
+ }
+ };
+ return factory.getAsynchronousConnection(handler);
+ }
+ }
+
+
+
+ private class MonitorThread extends Thread
+ {
+ private MonitorThread()
+ {
+ super("Connection Factory Health Monitor");
+ this.setDaemon(true);
+ }
+
+
+
+ public void run()
+ {
+ while (true)
+ {
+ for (MonitoredConnectionFactory f : monitoredFactories)
+ {
+ if (!f.isOperational
+ && (f.pendingConnectFuture == null || f.pendingConnectFuture
+ .isDone()))
+ {
+ if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
+ {
+ StaticUtils.DEBUG_LOG.finest(String
+ .format("Attempting connect on factory " + f));
+ }
+ f.pendingConnectFuture = f.factory
+ .getAsynchronousConnection(f);
+ }
+ }
+
+ try
+ {
+ sleep(10000);
+ }
+ catch (InterruptedException e)
+ {
+ // Termination requested - exit.
+ break;
+ }
+ }
+ }
+ }
+
+
+
+ /**
+ * Creates a new fail-over load balancing algorithm which will
+ * fail-over across the provided list of connection factories.
+ *
+ * @param factories
+ * The connection factories which will be used for fail-over.
+ */
public FailoverLoadBalancingAlgorithm(ConnectionFactory... factories)
{
- super(factories);
+ Validator.ensureNotNull((Object[]) factories);
+
+ monitoredFactories = new ArrayList<MonitoredConnectionFactory>(
+ factories.length);
+ for (ConnectionFactory f : factories)
+ {
+ monitoredFactories.add(new MonitoredConnectionFactory(f));
+ }
+
+ new MonitorThread().start();
+ }
+
+
+
+ /**
+ * Creates a new fail-over load balancing algorithm which will
+ * fail-over across the provided collection of connection factories.
+ *
+ * @param factories
+ * The connection factories which will be used for fail-over.
+ */
+ public FailoverLoadBalancingAlgorithm(
+ Collection<ConnectionFactory> factories)
+ {
+ Validator.ensureNotNull(factories);
+
+ monitoredFactories = new ArrayList<MonitoredConnectionFactory>(
+ factories.size());
+ for (ConnectionFactory f : factories)
+ {
+ monitoredFactories.add(new MonitoredConnectionFactory(f));
+ }
+
+ new MonitorThread().start();
}
public ConnectionFactory getNextConnectionFactory()
+ throws ErrorResultException
{
- for (MonitoredConnectionFactory f : factoryList)
+ for (MonitoredConnectionFactory f : monitoredFactories)
{
if (f.isOperational())
{
return f;
}
}
- return null;
+
+ throw ErrorResultException.wrap(Responses.newResult(
+ ResultCode.CLIENT_SIDE_CONNECT_ERROR).setDiagnosticMessage(
+ "No operational connection factories available"));
}
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingAlgorithm.java b/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingAlgorithm.java
index af351b3..439122a 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingAlgorithm.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingAlgorithm.java
@@ -1,11 +1,47 @@
+/*
+ * 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;
/**
- * Created by IntelliJ IDEA. User: digitalperk Date: Dec 15, 2009 Time:
- * 3:37:03 PM To change this template use File | Settings | File
- * Templates.
+ * A load balancing algorithm distributes connection requests across one
+ * or more underlying connection factories in an implementation defined
+ * manner.
*/
-public interface LoadBalancingAlgorithm
+interface LoadBalancingAlgorithm
{
- public ConnectionFactory getNextConnectionFactory();
+ /**
+ * Returns the next connection factory which should be used in order
+ * to obtain a connection.
+ *
+ * @return The next connection factory.
+ * @throws ErrorResultException
+ * If no connection factories are available for use.
+ */
+ ConnectionFactory getNextConnectionFactory()
+ throws ErrorResultException;
}
diff --git a/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingConnectionFactory.java b/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingConnectionFactory.java
index 5794506..40d3717 100644
--- a/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingConnectionFactory.java
+++ b/opendj-sdk/sdk/src/org/opends/sdk/LoadBalancingConnectionFactory.java
@@ -1,20 +1,44 @@
+/*
+ * 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.Validator;
import com.sun.opends.sdk.util.AbstractFutureResult;
-
-import org.opends.sdk.responses.Responses;
+import com.sun.opends.sdk.util.Validator;
/**
- * Created by IntelliJ IDEA. User: digitalperk Date: Dec 15, 2009 Time:
- * 3:23:52 PM To change this template use File | Settings | File
- * Templates.
+ * A load balancing connection factory allocates connections using the
+ * provided algorithm.
*/
-public class LoadBalancingConnectionFactory extends
+final class LoadBalancingConnectionFactory extends
AbstractConnectionFactory
{
private final LoadBalancingAlgorithm algorithm;
@@ -32,8 +56,13 @@
public FutureResult<AsynchronousConnection> getAsynchronousConnection(
ResultHandler<AsynchronousConnection> resultHandler)
{
- ConnectionFactory factory = algorithm.getNextConnectionFactory();
- if (factory == null)
+ ConnectionFactory factory;
+
+ try
+ {
+ factory = algorithm.getNextConnectionFactory();
+ }
+ catch (ErrorResultException e)
{
AbstractFutureResult<AsynchronousConnection> future = new AbstractFutureResult<AsynchronousConnection>(
resultHandler)
@@ -43,9 +72,8 @@
return -1;
}
};
- future.handleErrorResult(new ErrorResultException(Responses
- .newResult(ResultCode.CLIENT_SIDE_CONNECT_ERROR)
- .setDiagnosticMessage("No connection factories available")));
+
+ future.handleErrorResult(e);
return future;
}
--
Gitblit v1.10.0