From 22e401b056b6311fe88929b810c7ab7c3d941b26 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.
---
sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java | 245 +++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 237 insertions(+), 8 deletions(-)
diff --git a/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java b/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java
index a057e76..2bbc581 100644
--- a/sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java
+++ b/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"));
}
}
--
Gitblit v1.10.0