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