From e0a30f365c33e3c77cf9e7405e924b9e680d217d Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 24 Nov 2015 00:25:24 +0000
Subject: [PATCH] OPENDJ-1607 use Options for configuring load-balancers

---
 opendj-sdk/opendj-core/clirr-ignored-api-changes.xml                                                       |   10 
 opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties                        |    2 
 opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LoadBalancerEventListener.java              |   40 +++
 opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java         |   40 --
 opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Proxy.java                 |    9 
 opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LoadBalancingAlgorithm.java                 |   41 ++
 opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/FailoverLoadBalancingAlgorithm.java         |  149 -------------
 opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithmTestCase.java |   41 ++-
 opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPListenerTestCase.java      |   21 -
 opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Connections.java                            |   75 ++++++
 opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java                    |   15 
 opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ConnectionFactoryTestCase.java        |   52 +--
 opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RoundRobinLoadBalancingAlgorithm.java       |  150 ------------
 13 files changed, 242 insertions(+), 403 deletions(-)

diff --git a/opendj-sdk/opendj-core/clirr-ignored-api-changes.xml b/opendj-sdk/opendj-core/clirr-ignored-api-changes.xml
index dda2712..6938092 100644
--- a/opendj-sdk/opendj-core/clirr-ignored-api-changes.xml
+++ b/opendj-sdk/opendj-core/clirr-ignored-api-changes.xml
@@ -577,4 +577,14 @@
     <method>java.util.Set asSetOf(org.forgerock.opendj.ldap.Function, java.lang.Object[])</method>
     <justification>Method needs to be final in order to use SafeVarArgs annotation</justification>
   </difference>
+  <difference>
+    <className>org/forgerock/opendj/ldap/FailoverLoadBalancingAlgorithm</className>
+    <differenceType>1001</differenceType>
+    <justification>Class instances are now created using Connections.newFailoverLoadBalancer</justification>
+  </difference>
+  <difference>
+    <className>org/forgerock/opendj/ldap/RoundRobinLoadBalancingAlgorithm</className>
+    <differenceType>1001</differenceType>
+    <justification>Class instances are now created using Connections.newRoundRobinLoadBalancer</justification>
+  </difference>
 </differences>
diff --git a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java
index 1e939f4..1c30dad 100644
--- a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java
+++ b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java
@@ -36,6 +36,7 @@
 
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
+import org.forgerock.util.Options;
 import org.forgerock.util.Reject;
 import org.forgerock.util.AsyncFunction;
 import org.forgerock.util.promise.Promise;
@@ -169,7 +170,7 @@
                         logger.debug(LocalizableMessage.raw("Starting monitoring thread"));
                         monitoringFuture =
                                 scheduler.get().scheduleWithFixedDelay(new MonitorRunnable(), 0,
-                                        monitoringInterval, monitoringIntervalTimeUnit);
+                                        monitoringIntervalMS, TimeUnit.MILLISECONDS);
                     }
                 }
             }
@@ -219,26 +220,6 @@
 
     private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
 
-    /**
-     * A default event listener which just logs the event.
-     */
-    private static final LoadBalancerEventListener DEFAULT_LISTENER = new LoadBalancerEventListener() {
-
-        @Override
-        public void handleConnectionFactoryOnline(ConnectionFactory factory) {
-            // Transition from offline to online.
-            // TODO: I18N
-            logger.info(LocalizableMessage.raw("Connection factory '%s' is now operational", factory));
-        }
-
-        @Override
-        public void handleConnectionFactoryOffline(ConnectionFactory factory, LdapException error) {
-            // TODO: I18N
-            logger.warn(LocalizableMessage.raw("Connection factory '%s' is no longer operational: %s",
-                    factory, error.getMessage()));
-        }
-    };
-
     private final List<MonitoredConnectionFactory> monitoredFactories;
     private final ReferenceCountedObject<ScheduledExecutorService>.Reference scheduler;
     private final Object stateLock = new Object();
@@ -265,28 +246,25 @@
      * Guarded by stateLock.
      */
     private int offlineFactoriesCount;
-    private final long monitoringInterval;
-    private final TimeUnit monitoringIntervalTimeUnit;
+    private final long monitoringIntervalMS;
+
     /**
      * Guarded by stateLock.
      */
     private ScheduledFuture<?> monitoringFuture;
     private final AtomicBoolean isClosed = new AtomicBoolean();
 
-    AbstractLoadBalancingAlgorithm(final Collection<? extends ConnectionFactory> factories,
-            final LoadBalancerEventListener listener, final long interval, final TimeUnit unit,
-            final ScheduledExecutorService scheduler) {
-        Reject.ifNull(factories, unit);
+    AbstractLoadBalancingAlgorithm(final Collection<? extends ConnectionFactory> factories, final Options options) {
+        Reject.ifNull(factories, options);
 
         this.monitoredFactories = new ArrayList<>(factories.size());
         int i = 0;
         for (final ConnectionFactory f : factories) {
             this.monitoredFactories.add(new MonitoredConnectionFactory(f, i++));
         }
-        this.scheduler = DEFAULT_SCHEDULER.acquireIfNull(scheduler);
-        this.monitoringInterval = interval;
-        this.monitoringIntervalTimeUnit = unit;
-        this.listener = listener != null ? listener : DEFAULT_LISTENER;
+        this.scheduler = DEFAULT_SCHEDULER.acquireIfNull(options.get(LOAD_BALANCER_SCHEDULER));
+        this.monitoringIntervalMS = options.get(LOAD_BALANCER_MONITORING_INTERVAL).to(TimeUnit.MILLISECONDS);
+        this.listener = options.get(LOAD_BALANCER_EVENT_LISTENER);
     }
 
     @Override
diff --git a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Connections.java b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Connections.java
index 38c6fb7..da5300a 100644
--- a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Connections.java
+++ b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/Connections.java
@@ -31,6 +31,7 @@
 
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.util.Collection;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
@@ -364,15 +365,79 @@
     }
 
     /**
-     * Creates a new load balancer which will obtain connections using the
-     * provided load balancing algorithm.
+     * Creates a new "round-robin" load-balance which will load-balance connections across the provided set of
+     * connection factories. A round robin load balancing algorithm distributes connection requests across a list of
+     * connection factories one at a time. When the end of the list is reached, the algorithm starts again from the
+     * beginning.
+     * <p/>
+     * This algorithm is typically used for load-balancing <i>within</i> data centers, where load must be distributed
+     * equally across multiple data sources. This algorithm contrasts with the {@link FailoverLoadBalancingAlgorithm}
+     * which is used for load-balancing <i>between</i> data centers.
+     * <p/>
+     * If a problem occurs that temporarily prevents connections from being obtained for one of the connection
+     * factories, then this algorithm automatically "fails over" to the next 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.
+     *
+     * @param factories
+     *         The connection factories.
+     * @param options
+     *         This configuration options for the load-balancer. See {@link LoadBalancingAlgorithm} for common options.
+     * @return The new round-robin load balancer.
+     * @see #newFailoverLoadBalancer(Collection, Options)
+     * @see LoadBalancingAlgorithm
+     */
+    public static ConnectionFactory newRoundRobinLoadBalancer(
+            final Collection<? extends ConnectionFactory> factories, final Options options) {
+        return new LoadBalancer(new RoundRobinLoadBalancingAlgorithm(factories, options));
+    }
+
+    /**
+     * Creates a new "fail-over" load-balance which will load-balance connections across the provided set of connection
+     * factories. A fail-over load balancing algorithm provides fault tolerance across multiple underlying connection
+     * factories.
+     * <p/>
+     * This algorithm is typically used for load-balancing <i>between</i> data centers, where there is preference to
+     * always forward connection requests to the <i>closest available</i> data center. This algorithm contrasts with the
+     * {@link RoundRobinLoadBalancingAlgorithm} which is used for load-balancing <i>within</i> a data center.
+     * <p/>
+     * This algorithm selects connection factories based on the order in which they were provided during construction.
+     * More specifically, an attempt to obtain a connection factory will always return the <i>first operational</i>
+     * connection factory in the list. Applications should, therefore, organize the connection factories such that the
+     * <i>preferred</i> (usually the closest) connection factories appear before those which are less preferred.
+     * <p/>
+     * If a problem occurs that temporarily prevents connections from being obtained for one of the connection
+     * factories, then this algorithm automatically "fails over" to the next 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.
+     *
+     * @param factories
+     *         The connection factories.
+     * @param options
+     *         This configuration options for the load-balancer. See {@link LoadBalancingAlgorithm} for common options.
+     * @return The new fail-over load balancer.
+     * @see #newRoundRobinLoadBalancer(Collection, Options)
+     * @see LoadBalancingAlgorithm
+     */
+    public static ConnectionFactory newFailoverLoadBalancer(
+            final Collection<? extends ConnectionFactory> factories, final Options options) {
+        return new LoadBalancer(new FailoverLoadBalancingAlgorithm(factories, options));
+    }
+
+    /**
+     * Creates a new load balancer which will obtain connections using the provided load balancing algorithm.
      *
      * @param algorithm
-     *            The load balancing algorithm which will be used to obtain the
-     *            next
+     *         The load balancing algorithm which will be used to obtain the next
      * @return The new load balancer.
      * @throws NullPointerException
-     *             If {@code algorithm} was {@code null}.
+     *         If {@code algorithm} was {@code null}.
      */
     public static ConnectionFactory newLoadBalancer(final LoadBalancingAlgorithm algorithm) {
         return new LoadBalancer(algorithm);
diff --git a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/FailoverLoadBalancingAlgorithm.java b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/FailoverLoadBalancingAlgorithm.java
index 2ce96b0..7290b01 100644
--- a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/FailoverLoadBalancingAlgorithm.java
+++ b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/FailoverLoadBalancingAlgorithm.java
@@ -22,169 +22,32 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
- *      Portions copyright 2013 ForgeRock AS.
+ *      Portions copyright 2013-2015 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
 
 import java.util.Collection;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
+
+import org.forgerock.util.Options;
 
 /**
  * A fail-over load balancing algorithm provides fault tolerance across multiple
  * underlying connection factories.
- * <p>
- * This algorithm is typically used for load-balancing <i>between</i> data
- * centers, where there is preference to always forward connection requests to
- * the <i>closest available</i> data center. This algorithm contrasts with the
- * {@link RoundRobinLoadBalancingAlgorithm} which is used for load-balancing
- * <i>within</i> a data center.
- * <p>
- * This algorithm selects connection factories based on the order in which they
- * were provided during construction. More specifically, an attempt to obtain a
- * connection factory will always return the <i>first operational</i> connection
- * factory in the list. Applications should, therefore, organize the connection
- * factories such that the <i>preferred</i> (usually the closest) connection
- * factories appear before those which are less preferred.
- * <p>
- * If a problem occurs that temporarily prevents connections from being obtained
- * for one of the connection factories, then this algorithm automatically
- * "fails over" to the next 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.
- *
- * @see RoundRobinLoadBalancingAlgorithm
- * @see Connections#newLoadBalancer(LoadBalancingAlgorithm)
  */
-public final class FailoverLoadBalancingAlgorithm extends AbstractLoadBalancingAlgorithm {
-
-    /**
-     * Creates a new fail-over load balancing algorithm which will monitor
-     * offline connection factories every 1 second using the default scheduler.
-     *
-     * @param factories
-     *            The ordered collection of connection factories.
-     */
-    public FailoverLoadBalancingAlgorithm(final Collection<? extends ConnectionFactory> factories) {
-        this(factories, null, 1, TimeUnit.SECONDS, null);
+final class FailoverLoadBalancingAlgorithm extends AbstractLoadBalancingAlgorithm {
+    FailoverLoadBalancingAlgorithm(final Collection<? extends ConnectionFactory> factories, final Options options) {
+        super(factories, options);
     }
 
-    /**
-     * Creates a new fail-over load balancing algorithm which will monitor
-     * offline connection factories every 1 second using the default scheduler.
-     *
-     * @param factories
-     *            The ordered collection of connection factories.
-     * @param listener
-     *            The event listener which should be notified whenever a
-     *            connection factory changes state from online to offline or
-     *            vice-versa.
-     */
-    public FailoverLoadBalancingAlgorithm(final Collection<? extends ConnectionFactory> factories,
-            final LoadBalancerEventListener listener) {
-        this(factories, listener, 1, TimeUnit.SECONDS, null);
-    }
-
-    /**
-     * Creates a new fail-over load balancing algorithm which will monitor
-     * offline connection factories using the specified frequency using the
-     * default scheduler.
-     *
-     * @param factories
-     *            The connection factories.
-     * @param listener
-     *            The event listener which should be notified whenever a
-     *            connection factory changes state from online to offline or
-     *            vice-versa.
-     * @param interval
-     *            The interval between attempts to poll offline factories.
-     * @param unit
-     *            The time unit for the interval between attempts to poll
-     *            offline factories.
-     */
-    public FailoverLoadBalancingAlgorithm(final Collection<? extends ConnectionFactory> factories,
-            final LoadBalancerEventListener listener, final long interval, final TimeUnit unit) {
-        this(factories, listener, interval, unit, null);
-    }
-
-    /**
-     * Creates a new fail-over load balancing algorithm which will monitor
-     * offline connection factories using the specified frequency and scheduler.
-     *
-     * @param factories
-     *            The connection factories.
-     * @param listener
-     *            The event listener which should be notified whenever a
-     *            connection factory changes state from online to offline or
-     *            vice-versa.
-     * @param interval
-     *            The interval between attempts to poll offline factories.
-     * @param unit
-     *            The time unit for the interval between attempts to poll
-     *            offline factories.
-     * @param scheduler
-     *            The scheduler which should for periodically monitoring dead
-     *            connection factories to see if they are usable again.
-     */
-    public FailoverLoadBalancingAlgorithm(final Collection<? extends ConnectionFactory> factories,
-            final LoadBalancerEventListener listener, final long interval, final TimeUnit unit,
-            final ScheduledExecutorService scheduler) {
-        super(factories, listener, interval, unit, scheduler);
-    }
-
-    /**
-     * Creates a new fail-over load balancing algorithm which will monitor
-     * offline connection factories using the specified frequency using the
-     * default scheduler.
-     *
-     * @param factories
-     *            The connection factories.
-     * @param interval
-     *            The interval between attempts to poll offline factories.
-     * @param unit
-     *            The time unit for the interval between attempts to poll
-     *            offline factories.
-     */
-    public FailoverLoadBalancingAlgorithm(final Collection<? extends ConnectionFactory> factories,
-            final long interval, final TimeUnit unit) {
-        this(factories, null, interval, unit, null);
-    }
-
-    /**
-     * Creates a new fail-over load balancing algorithm which will monitor
-     * offline connection factories using the specified frequency and scheduler.
-     *
-     * @param factories
-     *            The connection factories.
-     * @param interval
-     *            The interval between attempts to poll offline factories.
-     * @param unit
-     *            The time unit for the interval between attempts to poll
-     *            offline factories.
-     * @param scheduler
-     *            The scheduler which should for periodically monitoring dead
-     *            connection factories to see if they are usable again.
-     */
-    public FailoverLoadBalancingAlgorithm(final Collection<? extends ConnectionFactory> factories,
-            final long interval, final TimeUnit unit, final ScheduledExecutorService scheduler) {
-        this(factories, null, interval, unit, scheduler);
-    }
-
-    /** {@inheritDoc} */
     @Override
     String getAlgorithmName() {
         return "Failover";
     }
 
-    /** {@inheritDoc} */
     @Override
     int getInitialConnectionFactoryIndex() {
         // Always start with the first connection factory.
         return 0;
     }
-
 }
diff --git a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LoadBalancerEventListener.java b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LoadBalancerEventListener.java
index 833a0dd..fb1c1db 100644
--- a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LoadBalancerEventListener.java
+++ b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LoadBalancerEventListener.java
@@ -20,13 +20,18 @@
  *
  * CDDL HEADER END
  *
- *      Copyright 2013-2014 ForgeRock AS.
+ *      Copyright 2013-2015 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
 
+import static com.forgerock.opendj.ldap.CoreMessages.LOAD_BALANCER_EVENT_LISTENER_LOG_OFFLINE;
+import static com.forgerock.opendj.ldap.CoreMessages.LOAD_BALANCER_EVENT_LISTENER_LOG_ONLINE;
+
 import java.util.EventListener;
 
+import org.forgerock.i18n.slf4j.LocalizedLogger;
+
 /**
  * An object that registers to be notified when a connection factory associated
  * with a load-balancer changes state from offline to online or vice-versa.
@@ -34,8 +39,41 @@
  * <b>NOTE:</b> load-balancer implementations must ensure that only one event is
  * sent at a time. Event listener implementations should not need to be thread
  * safe.
+ *
+ * @see LoadBalancingAlgorithm#LOAD_BALANCER_EVENT_LISTENER
  */
 public interface LoadBalancerEventListener extends EventListener {
+    /**
+     * An event listener implementation which logs events to the LoadBalancingAlgorithm logger. This event listener is
+     * the default implementation configured using the {@link LoadBalancingAlgorithm#LOAD_BALANCER_EVENT_LISTENER}
+     * option.
+     */
+    LoadBalancerEventListener LOG_EVENTS = new LoadBalancerEventListener() {
+        private final LocalizedLogger logger = LocalizedLogger.getLocalizedLogger(LoadBalancingAlgorithm.class);
+
+        @Override
+        public void handleConnectionFactoryOnline(final ConnectionFactory factory) {
+            logger.info(LOAD_BALANCER_EVENT_LISTENER_LOG_ONLINE.get(factory));
+        }
+
+        @Override
+        public void handleConnectionFactoryOffline(final ConnectionFactory factory, final LdapException error) {
+            logger.warn(LOAD_BALANCER_EVENT_LISTENER_LOG_OFFLINE.get(factory, error.getMessage()));
+        }
+    };
+
+    /** An event listener implementation which ignores all events. */
+    LoadBalancerEventListener NO_OP = new LoadBalancerEventListener() {
+        @Override
+        public void handleConnectionFactoryOnline(final ConnectionFactory factory) {
+            // Do nothing.
+        }
+
+        @Override
+        public void handleConnectionFactoryOffline(final ConnectionFactory factory, final LdapException error) {
+            // Do nothing.
+        }
+    };
 
     /**
      * Invoked when the load-balancer is unable to obtain a connection from the
diff --git a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LoadBalancingAlgorithm.java b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LoadBalancingAlgorithm.java
index 8833e0f..eebdead 100644
--- a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LoadBalancingAlgorithm.java
+++ b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/LoadBalancingAlgorithm.java
@@ -22,35 +22,58 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
- *      Portions Copyright 2013-2014 ForgeRock AS.
+ *      Portions Copyright 2013-2015 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
 
+import static org.forgerock.util.time.Duration.duration;
+
 import java.io.Closeable;
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.forgerock.util.Option;
+import org.forgerock.util.time.Duration;
 
 /**
- * A load balancing algorithm distributes connection requests across one or more
- * underlying connection factories in an implementation defined manner.
+ * A load balancing algorithm distributes connection requests across one or more underlying connection factories in an
+ * implementation defined manner.
  *
- * @see Connections#newLoadBalancer(LoadBalancingAlgorithm) newLoadBalancer
+ * @see Connections#newLoadBalancer(LoadBalancingAlgorithm)
  */
 public interface LoadBalancingAlgorithm extends Closeable {
+    /**
+     * Specifies the interval between successive attempts to reconnect to offline load-balanced connection factories.
+     * The default configuration is to attempt to reconnect every second.
+     */
+    Option<Duration> LOAD_BALANCER_MONITORING_INTERVAL = Option.withDefault(duration("1 seconds"));
 
     /**
-     * Releases any resources associated with this algorithm, including any
-     * associated connection factories.
+     * Specifies the event listener which should be notified whenever a load-balanced connection factory changes state
+     * from online to offline or vice-versa. By default events will be logged to the {@code LoadBalancingAlgorithm}
+     * logger using the {@link LoadBalancerEventListener#LOG_EVENTS} listener.
+     */
+    Option<LoadBalancerEventListener> LOAD_BALANCER_EVENT_LISTENER =
+            Option.of(LoadBalancerEventListener.class, LoadBalancerEventListener.LOG_EVENTS);
+
+    /**
+     * Specifies the scheduler which will be used for periodically reconnecting to offline connection factories. A
+     * system-wide scheduler will be used by default.
+     */
+    Option<ScheduledExecutorService> LOAD_BALANCER_SCHEDULER = Option.of(ScheduledExecutorService.class, null);
+
+    /**
+     * Releases any resources associated with this algorithm, including any associated connection factories.
      */
     @Override
     void close();
 
     /**
-     * Returns a connection factory which should be used in order to satisfy the
-     * next connection request.
+     * Returns a connection factory which should be used in order to satisfy the next connection request.
      *
      * @return The connection factory.
      * @throws LdapException
-     *             If no connection factories are available for use.
+     *         If no connection factories are available for use.
      */
     ConnectionFactory getConnectionFactory() throws LdapException;
 }
diff --git a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RoundRobinLoadBalancingAlgorithm.java b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RoundRobinLoadBalancingAlgorithm.java
index d51d51c..997fdaf 100644
--- a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RoundRobinLoadBalancingAlgorithm.java
+++ b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/RoundRobinLoadBalancingAlgorithm.java
@@ -22,167 +22,35 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
- *      Portions copyright 2013 ForgeRock AS.
+ *      Portions copyright 2013-2015 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
 
 import java.util.Collection;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.forgerock.util.Options;
+
 /**
- * A round robin load balancing algorithm distributes connection requests across
- * a list of connection factories one at a time. When the end of the list is
- * reached, the algorithm starts again from the beginning.
- * <p>
- * This algorithm is typically used for load-balancing <i>within</i> data
- * centers, where load must be distributed equally across multiple data sources.
- * This algorithm contrasts with the {@link FailoverLoadBalancingAlgorithm}
- * which is used for load-balancing <i>between</i> data centers.
- * <p>
- * If a problem occurs that temporarily prevents connections from being obtained
- * for one of the connection factories, then this algorithm automatically
- * "fails over" to the next 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.
- *
- * @see FailoverLoadBalancingAlgorithm
- * @see Connections#newLoadBalancer(LoadBalancingAlgorithm)
+ * A round robin load balancing algorithm distributes connection requests across a list of
+ * connection factories one at a time. When the end of the list is reached, the algorithm starts again from the
+ * beginning.
  */
-public final class RoundRobinLoadBalancingAlgorithm extends AbstractLoadBalancingAlgorithm {
+final class RoundRobinLoadBalancingAlgorithm extends AbstractLoadBalancingAlgorithm {
     private final int maxIndex;
     private final AtomicInteger nextIndex = new AtomicInteger(-1);
 
-    /**
-     * Creates a new round robin load balancing algorithm which will monitor
-     * offline connection factories every 1 second using the default scheduler.
-     *
-     * @param factories
-     *            The ordered collection of connection factories.
-     */
-    public RoundRobinLoadBalancingAlgorithm(final Collection<? extends ConnectionFactory> factories) {
-        this(factories, null, 1, TimeUnit.SECONDS, null);
-    }
-
-    /**
-     * Creates a new round robin load balancing algorithm which will monitor
-     * offline connection factories every 1 second using the default scheduler.
-     *
-     * @param factories
-     *            The ordered collection of connection factories.
-     * @param listener
-     *            The event listener which should be notified whenever a
-     *            connection factory changes state from online to offline or
-     *            vice-versa.
-     */
-    public RoundRobinLoadBalancingAlgorithm(
-            final Collection<? extends ConnectionFactory> factories,
-            final LoadBalancerEventListener listener) {
-        this(factories, listener, 1, TimeUnit.SECONDS, null);
-    }
-
-    /**
-     * Creates a new round robin load balancing algorithm which will monitor
-     * offline connection factories using the specified frequency using the
-     * default scheduler.
-     *
-     * @param factories
-     *            The connection factories.
-     * @param listener
-     *            The event listener which should be notified whenever a
-     *            connection factory changes state from online to offline or
-     *            vice-versa.
-     * @param interval
-     *            The interval between attempts to poll offline factories.
-     * @param unit
-     *            The time unit for the interval between attempts to poll
-     *            offline factories.
-     */
-    public RoundRobinLoadBalancingAlgorithm(
-            final Collection<? extends ConnectionFactory> factories,
-            final LoadBalancerEventListener listener, final long interval, final TimeUnit unit) {
-        this(factories, null, interval, unit, null);
-    }
-
-    /**
-     * Creates a new round robin load balancing algorithm which will monitor
-     * offline connection factories using the specified frequency and scheduler.
-     *
-     * @param factories
-     *            The connection factories.
-     * @param listener
-     *            The event listener which should be notified whenever a
-     *            connection factory changes state from online to offline or
-     *            vice-versa.
-     * @param interval
-     *            The interval between attempts to poll offline factories.
-     * @param unit
-     *            The time unit for the interval between attempts to poll
-     *            offline factories.
-     * @param scheduler
-     *            The scheduler which should for periodically monitoring dead
-     *            connection factories to see if they are usable again.
-     */
-    public RoundRobinLoadBalancingAlgorithm(
-            final Collection<? extends ConnectionFactory> factories,
-            final LoadBalancerEventListener listener, final long interval, final TimeUnit unit,
-            final ScheduledExecutorService scheduler) {
-        super(factories, listener, interval, unit, scheduler);
+    RoundRobinLoadBalancingAlgorithm(final Collection<? extends ConnectionFactory> factories, final Options options) {
+        super(factories, options);
         this.maxIndex = factories.size();
     }
 
-    /**
-     * Creates a new round robin load balancing algorithm which will monitor
-     * offline connection factories using the specified frequency using the
-     * default scheduler.
-     *
-     * @param factories
-     *            The connection factories.
-     * @param interval
-     *            The interval between attempts to poll offline factories.
-     * @param unit
-     *            The time unit for the interval between attempts to poll
-     *            offline factories.
-     */
-    public RoundRobinLoadBalancingAlgorithm(
-            final Collection<? extends ConnectionFactory> factories, final long interval,
-            final TimeUnit unit) {
-        this(factories, null, interval, unit, null);
-    }
-
-    /**
-     * Creates a new round robin load balancing algorithm which will monitor
-     * offline connection factories using the specified frequency and scheduler.
-     *
-     * @param factories
-     *            The connection factories.
-     * @param interval
-     *            The interval between attempts to poll offline factories.
-     * @param unit
-     *            The time unit for the interval between attempts to poll
-     *            offline factories.
-     * @param scheduler
-     *            The scheduler which should for periodically monitoring dead
-     *            connection factories to see if they are usable again.
-     */
-    public RoundRobinLoadBalancingAlgorithm(
-            final Collection<? extends ConnectionFactory> factories, final long interval,
-            final TimeUnit unit, final ScheduledExecutorService scheduler) {
-        this(factories, null, interval, unit, scheduler);
-    }
-
-    /** {@inheritDoc} */
     @Override
     String getAlgorithmName() {
         return "RoundRobin";
     }
 
-    /** {@inheritDoc} */
     @Override
     int getInitialConnectionFactoryIndex() {
         // A round robin pool of one connection factories is unlikely in
diff --git a/opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties b/opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
index 535c4ea..e054fd5 100755
--- a/opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
+++ b/opendj-sdk/opendj-core/src/main/resources/com/forgerock/opendj/ldap/core.properties
@@ -1669,3 +1669,5 @@
 
 LDAP_CONNECTION_CONNECT_TIMEOUT=The connection attempt to server %s has failed \
  because the connection timeout period of %d ms was exceeded
+LOAD_BALANCER_EVENT_LISTENER_LOG_ONLINE=Connection factory '%s' is now operational
+LOAD_BALANCER_EVENT_LISTENER_LOG_OFFLINE=Connection factory '%s' is no longer operational: %s
diff --git a/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithmTestCase.java b/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithmTestCase.java
index 405d87a..d13164a 100644
--- a/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithmTestCase.java
+++ b/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithmTestCase.java
@@ -21,27 +21,35 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2014 ForgeRock AS
+ *      Copyright 2014-2015 ForgeRock AS
  */
 package org.forgerock.opendj.ldap;
 
-import java.util.concurrent.TimeUnit;
+import static java.util.Arrays.asList;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+import static org.forgerock.opendj.ldap.Connections.newRoundRobinLoadBalancer;
+import static org.forgerock.opendj.ldap.LdapException.newLdapException;
+import static org.forgerock.opendj.ldap.LoadBalancingAlgorithm.LOAD_BALANCER_EVENT_LISTENER;
+import static org.forgerock.opendj.ldap.LoadBalancingAlgorithm.LOAD_BALANCER_MONITORING_INTERVAL;
+import static org.forgerock.opendj.ldap.LoadBalancingAlgorithm.LOAD_BALANCER_SCHEDULER;
+import static org.forgerock.util.Options.defaultOptions;
+import static org.forgerock.util.promise.Promises.newExceptionPromise;
+import static org.forgerock.util.promise.Promises.newResultPromise;
+import static org.forgerock.util.time.Duration.duration;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
 import java.util.logging.Level;
 
+import org.forgerock.util.Options;
 import org.forgerock.util.promise.Promise;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import static java.util.Arrays.*;
-
-import static org.fest.assertions.Assertions.*;
-import static org.fest.assertions.Fail.*;
-import static org.forgerock.opendj.ldap.Connections.*;
-import static org.forgerock.opendj.ldap.LdapException.*;
-import static org.forgerock.util.promise.Promises.*;
-import static org.mockito.Mockito.*;
-
 @SuppressWarnings("javadoc")
 public class AbstractLoadBalancingAlgorithmTestCase extends SdkTestCase {
     private static ConnectionFactory mockAsync(final ConnectionFactory mock) {
@@ -105,8 +113,7 @@
         final LdapException secondError = newLdapException(ResultCode.CLIENT_SIDE_SERVER_DOWN);
         when(second.getConnection()).thenThrow(secondError);
 
-        final ConnectionFactory loadBalancer =
-                newLoadBalancer(new RoundRobinLoadBalancingAlgorithm(asList(first, second)));
+        final ConnectionFactory loadBalancer = newRoundRobinLoadBalancer(asList(first, second), defaultOptions());
 
         /*
          * Belt and braces check to ensure that factory methods don't return
@@ -147,9 +154,11 @@
 
         final LoadBalancerEventListener listener = mock(LoadBalancerEventListener.class);
         final MockScheduler scheduler = new MockScheduler();
-        final ConnectionFactory loadBalancer =
-                newLoadBalancer(new RoundRobinLoadBalancingAlgorithm(
-                        asList(firstAsync, secondAsync), listener, 1, TimeUnit.SECONDS, scheduler));
+        final Options options = defaultOptions()
+                                   .set(LOAD_BALANCER_EVENT_LISTENER, listener)
+                                   .set(LOAD_BALANCER_MONITORING_INTERVAL, duration("1 second"))
+                                   .set(LOAD_BALANCER_SCHEDULER, scheduler);
+        final ConnectionFactory loadBalancer = newRoundRobinLoadBalancer(asList(firstAsync, secondAsync), options);
 
         /*
          * Belt and braces check to ensure that factory methods don't return
diff --git a/opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ConnectionFactoryTestCase.java b/opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ConnectionFactoryTestCase.java
index 8e49f98..a38122f 100644
--- a/opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ConnectionFactoryTestCase.java
+++ b/opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/ConnectionFactoryTestCase.java
@@ -234,40 +234,26 @@
         factories[7][0] = newFixedConnectionPool(onlineServer, 10);
 
         // Round robin.
-        factories[8][0] =
-                Connections.newLoadBalancer(new RoundRobinLoadBalancingAlgorithm(Arrays.asList(
-                        onlineServer, offlineServer1)));
+        factories[8][0] = newRoundRobinLoadBalancer(asList(onlineServer, offlineServer1), defaultOptions());
         factories[9][0] = factories[8][0];
         factories[10][0] = factories[8][0];
-        factories[11][0] =
-                Connections.newLoadBalancer(new RoundRobinLoadBalancingAlgorithm(Arrays.asList(
-                        offlineServer1, onlineServer)));
-        factories[12][0] =
-                Connections.newLoadBalancer(new RoundRobinLoadBalancingAlgorithm(Arrays.asList(
-                        offlineServer1, offlineServer2, onlineServer)));
-        factories[13][0] =
-                Connections.newLoadBalancer(new RoundRobinLoadBalancingAlgorithm(Arrays
-                        .<ConnectionFactory> asList(Connections.newFixedConnectionPool(
-                                offlineServer1, 10), Connections.newFixedConnectionPool(
-                                onlineServer, 10))));
+        factories[11][0] = newRoundRobinLoadBalancer(asList(offlineServer1, onlineServer), defaultOptions());
+        factories[12][0] = newRoundRobinLoadBalancer(asList(offlineServer1, offlineServer2, onlineServer),
+                                                     defaultOptions());
+        factories[13][0] = newRoundRobinLoadBalancer(asList(newFixedConnectionPool(offlineServer1, 10),
+                                                            newFixedConnectionPool(onlineServer, 10)),
+                                                     defaultOptions());
 
         // Fail-over.
-        factories[14][0] =
-                Connections.newLoadBalancer(new FailoverLoadBalancingAlgorithm(Arrays.asList(
-                        onlineServer, offlineServer1)));
+        factories[14][0] = newFailoverLoadBalancer(asList(onlineServer, offlineServer1), defaultOptions());
         factories[15][0] = factories[14][0];
         factories[16][0] = factories[14][0];
-        factories[17][0] =
-                Connections.newLoadBalancer(new FailoverLoadBalancingAlgorithm(Arrays.asList(
-                        offlineServer1, onlineServer)));
-        factories[18][0] =
-                Connections.newLoadBalancer(new FailoverLoadBalancingAlgorithm(Arrays.asList(
-                        offlineServer1, offlineServer2, onlineServer)));
-        factories[19][0] =
-                Connections.newLoadBalancer(new FailoverLoadBalancingAlgorithm(Arrays
-                        .<ConnectionFactory> asList(Connections.newFixedConnectionPool(
-                                offlineServer1, 10), Connections.newFixedConnectionPool(
-                                onlineServer, 10))));
+        factories[17][0] = newFailoverLoadBalancer(asList(offlineServer1, onlineServer), defaultOptions());
+        factories[18][0] = newFailoverLoadBalancer(asList(offlineServer1, offlineServer2, onlineServer),
+                                                   defaultOptions());
+        factories[19][0] = newFailoverLoadBalancer(asList(newFixedConnectionPool(offlineServer1, 10),
+                                                          newFixedConnectionPool(onlineServer, 10)),
+                                                   defaultOptions());
 
         factories[20][0] = newFixedConnectionPool(onlineServer, 10);
 
@@ -698,10 +684,12 @@
             + "closing the connection factory causes NPE")
     public void testFactoryCloseBeforeConnectionClose() throws Exception {
         InetSocketAddress socketAddress = getServerSocketAddress();
-        final ConnectionFactory factory =
-                newLoadBalancer(new FailoverLoadBalancingAlgorithm(Arrays.asList(newFixedConnectionPool(
-                        newHeartBeatConnectionFactory(new LDAPConnectionFactory(
-                                socketAddress.getHostName(), socketAddress.getPort())), 2))));
+        final LDAPConnectionFactory ldap = new LDAPConnectionFactory(socketAddress.getHostName(),
+                                                                     socketAddress.getPort(),
+                                                                     defaultOptions()
+                                                                            .set(HEARTBEAT_ENABLED, true));
+        final ConnectionPool pool = newFixedConnectionPool(ldap, 2);
+        final ConnectionFactory factory = newFailoverLoadBalancer(singletonList(pool), defaultOptions());
         Connection conn = null;
         try {
             conn = factory.getConnection();
diff --git a/opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPListenerTestCase.java b/opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPListenerTestCase.java
index a463997..8cb84b6 100644
--- a/opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPListenerTestCase.java
+++ b/opendj-sdk/opendj-grizzly/src/test/java/org/forgerock/opendj/grizzly/GrizzlyLDAPListenerTestCase.java
@@ -45,7 +45,6 @@
 import org.forgerock.opendj.ldap.ProviderNotFoundException;
 import org.forgerock.opendj.ldap.ResultCode;
 import org.forgerock.opendj.ldap.LdapResultHandler;
-import org.forgerock.opendj.ldap.RoundRobinLoadBalancingAlgorithm;
 import org.forgerock.opendj.ldap.SdkTestCase;
 import org.forgerock.opendj.ldap.SearchResultHandler;
 import org.forgerock.opendj.ldap.ServerConnection;
@@ -72,9 +71,11 @@
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import static java.util.Arrays.asList;
 import static org.fest.assertions.Assertions.*;
 import static org.fest.assertions.Fail.*;
 import static org.forgerock.opendj.ldap.Connections.newFixedConnectionPool;
+import static org.forgerock.opendj.ldap.Connections.newRoundRobinLoadBalancer;
 import static org.forgerock.opendj.ldap.LdapException.*;
 import static org.forgerock.opendj.ldap.LDAPListener.*;
 import static org.forgerock.opendj.ldap.TestCaseUtils.*;
@@ -326,11 +327,10 @@
 
             // Round robin.
             final ConnectionFactory loadBalancer =
-                    Connections.newLoadBalancer(new RoundRobinLoadBalancingAlgorithm(Arrays
-                            .<ConnectionFactory> asList(Connections.newFixedConnectionPool(
-                                    offlineServer1, 10), Connections.newFixedConnectionPool(
-                                    offlineServer2, 10), Connections.newFixedConnectionPool(
-                                    onlineServer, 10))));
+                    newRoundRobinLoadBalancer(asList(newFixedConnectionPool(offlineServer1, 10),
+                                                     newFixedConnectionPool(offlineServer2, 10),
+                                                     newFixedConnectionPool(onlineServer, 10)),
+                                              defaultOptions());
 
             final MockServerConnection proxyServerConnection = new MockServerConnection();
             final MockServerConnectionFactory proxyServerConnectionFactory =
@@ -406,11 +406,10 @@
 
             // Round robin.
             final ConnectionFactory loadBalancer =
-                    Connections.newLoadBalancer(new RoundRobinLoadBalancingAlgorithm(Arrays
-                            .<ConnectionFactory> asList(Connections.newFixedConnectionPool(
-                                    offlineServer1, 10), Connections.newFixedConnectionPool(
-                                    offlineServer2, 10), Connections.newFixedConnectionPool(
-                                    onlineServer, 10))));
+                    newRoundRobinLoadBalancer(asList(newFixedConnectionPool(offlineServer1, 10),
+                                                     newFixedConnectionPool(offlineServer2, 10),
+                                                     newFixedConnectionPool(onlineServer, 10)),
+                                              defaultOptions());
 
             final MockServerConnection proxyServerConnection = new MockServerConnection() {
 
diff --git a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Proxy.java b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Proxy.java
index 0baf2db..30177b6 100644
--- a/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Proxy.java
+++ b/opendj-sdk/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Proxy.java
@@ -44,7 +44,6 @@
 import org.forgerock.opendj.ldap.LDAPListener;
 import org.forgerock.opendj.ldap.RequestContext;
 import org.forgerock.opendj.ldap.RequestHandlerFactory;
-import org.forgerock.opendj.ldap.RoundRobinLoadBalancingAlgorithm;
 import org.forgerock.opendj.ldap.ServerConnectionFactory;
 import org.forgerock.opendj.ldap.requests.BindRequest;
 import org.forgerock.util.Options;
@@ -116,12 +115,8 @@
         // --- JCite pools ---
 
         // --- JCite load balancer ---
-        final RoundRobinLoadBalancingAlgorithm algorithm =
-                new RoundRobinLoadBalancingAlgorithm(factories);
-        final RoundRobinLoadBalancingAlgorithm bindAlgorithm =
-                new RoundRobinLoadBalancingAlgorithm(bindFactories);
-        final ConnectionFactory factory = Connections.newLoadBalancer(algorithm);
-        final ConnectionFactory bindFactory = Connections.newLoadBalancer(bindAlgorithm);
+        final ConnectionFactory factory = Connections.newRoundRobinLoadBalancer(factories, factoryOptions);
+        final ConnectionFactory bindFactory = Connections.newRoundRobinLoadBalancer(bindFactories, bindFactoryOptions);
         // --- JCite load balancer ---
 
         // --- JCite backend ---
diff --git a/opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java b/opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
index 24e1fa7..10b8ee0 100644
--- a/opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
+++ b/opendj-sdk/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
@@ -15,9 +15,13 @@
  */
 package org.forgerock.opendj.rest2ldap;
 
+import static java.util.Arrays.asList;
 import static org.forgerock.json.resource.ResourceException.newResourceException;
 import static org.forgerock.opendj.ldap.Connections.newCachedConnectionPool;
+import static org.forgerock.opendj.ldap.Connections.newFailoverLoadBalancer;
+import static org.forgerock.opendj.ldap.Connections.newRoundRobinLoadBalancer;
 import static org.forgerock.opendj.ldap.LDAPConnectionFactory.*;
+import static org.forgerock.opendj.ldap.LoadBalancingAlgorithm.LOAD_BALANCER_MONITORING_INTERVAL;
 import static org.forgerock.opendj.ldap.requests.Requests.newSearchRequest;
 import static org.forgerock.opendj.ldap.schema.CoreSchema.getEntryUUIDAttributeType;
 import static org.forgerock.opendj.rest2ldap.ReadOnUpdatePolicy.CONTROLS;
@@ -26,7 +30,6 @@
 import java.io.IOException;
 import java.security.GeneralSecurityException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -51,7 +54,6 @@
 import org.forgerock.opendj.ldap.DN;
 import org.forgerock.opendj.ldap.Entry;
 import org.forgerock.opendj.ldap.EntryNotFoundException;
-import org.forgerock.opendj.ldap.FailoverLoadBalancingAlgorithm;
 import org.forgerock.opendj.ldap.Filter;
 import org.forgerock.opendj.ldap.LDAPConnectionFactory;
 import org.forgerock.opendj.ldap.LdapException;
@@ -59,7 +61,6 @@
 import org.forgerock.opendj.ldap.MultipleEntriesFoundException;
 import org.forgerock.opendj.ldap.RDN;
 import org.forgerock.opendj.ldap.ResultCode;
-import org.forgerock.opendj.ldap.RoundRobinLoadBalancingAlgorithm;
 import org.forgerock.opendj.ldap.SSLContextBuilder;
 import org.forgerock.opendj.ldap.SearchScope;
 import org.forgerock.opendj.ldap.TimeoutResultException;
@@ -989,6 +990,8 @@
                                        .set(HEARTBEAT_ENABLED, true)
                                        .set(HEARTBEAT_INTERVAL, heartBeatInterval)
                                        .set(HEARTBEAT_TIMEOUT, heartBeatTimeout)
+                                       .set(LOAD_BALANCER_MONITORING_INTERVAL, heartBeatInterval);
+
         // Parse pool parameters,
         final int connectionPoolSize =
                 Math.max(configuration.get("connectionPoolSize").defaultTo(10).asInteger(), 1);
@@ -1066,8 +1069,7 @@
 
         // Create fail-over.
         if (secondary != null) {
-            return Connections.newLoadBalancer(new FailoverLoadBalancingAlgorithm(Arrays.asList(
-                    primary, secondary), heartBeatIntervalSeconds, TimeUnit.SECONDS));
+            return newFailoverLoadBalancer(asList(primary, secondary), options);
         } else {
             return primary;
         }
@@ -1112,8 +1114,7 @@
             }
         }
         if (servers.size() > 1) {
-            return Connections.newLoadBalancer(new RoundRobinLoadBalancingAlgorithm(servers,
-                    heartBeatIntervalSeconds, TimeUnit.SECONDS));
+            return newRoundRobinLoadBalancer(servers, options);
         } else {
             return servers.get(0);
         }

--
Gitblit v1.10.0