mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

matthew_swift
21.56.2010 22e401b056b6311fe88929b810c7ab7c3d941b26
Hide LB classes for now and expose only constructors via Connections class.
1 files deleted
4 files modified
645 ■■■■■ changed files
sdk/src/org/opends/sdk/AbstractLoadBalancingAlgorithm.java 196 ●●●●● patch | view | raw | blame | history
sdk/src/org/opends/sdk/Connections.java 106 ●●●● patch | view | raw | blame | history
sdk/src/org/opends/sdk/FailoverLoadBalancingAlgorithm.java 245 ●●●●● patch | view | raw | blame | history
sdk/src/org/opends/sdk/LoadBalancingAlgorithm.java 46 ●●●● patch | view | raw | blame | history
sdk/src/org/opends/sdk/LoadBalancingConnectionFactory.java 52 ●●●● patch | view | raw | blame | history
sdk/src/org/opends/sdk/AbstractLoadBalancingAlgorithm.java
File was deleted
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.
  }
}
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"));
  }
}
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;
}
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;
    }