From 8aa26a4d109b60e4f3f4ff441156c9cb4beaf9f7 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 29 Aug 2013 21:48:20 +0000
Subject: [PATCH] Partial fix for OPENDJ-1112: LoadBalancing connection factories need better diagnostic messages
---
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java | 64 +++++++++++++++++++--
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LoadBalancerEventListener.java | 62 ++++++++++++++++++++
2 files changed, 119 insertions(+), 7 deletions(-)
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java
index 2a4aaed..97c5093 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/AbstractLoadBalancingAlgorithm.java
@@ -167,10 +167,12 @@
if (isOperational.getAndSet(false)) {
// Transition from online to offline.
- if (DEBUG_LOG.isLoggable(Level.WARNING)) {
- DEBUG_LOG.warning(String.format(
- "Connection factory '%s' is no longer operational: %s", factory, error
- .getMessage()));
+ synchronized (listenerLock) {
+ try {
+ listener.handleConnectionFactoryOffline(factory, error);
+ } catch (Throwable t) {
+ handleListenerException(t);
+ }
}
synchronized (stateLock) {
@@ -192,9 +194,12 @@
private void notifyOnline() {
if (!isOperational.getAndSet(true)) {
// Transition from offline to online.
- if (DEBUG_LOG.isLoggable(Level.INFO)) {
- DEBUG_LOG.info(String.format("Connection factory'%s' is now operational",
- factory));
+ synchronized (listenerLock) {
+ try {
+ listener.handleConnectionFactoryOnline(factory);
+ } catch (Throwable t) {
+ handleListenerException(t);
+ }
}
synchronized (stateLock) {
@@ -210,6 +215,13 @@
}
}
}
+
+ private void handleListenerException(Throwable t) {
+ if (DEBUG_LOG.isLoggable(Level.SEVERE)) {
+ DEBUG_LOG.log(Level.SEVERE,
+ "A run-time error occurred while processing a load-balancer event", t);
+ }
+ }
}
private final class MonitorRunnable implements Runnable {
@@ -225,6 +237,32 @@
}
}
+ /**
+ * 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.
+ if (DEBUG_LOG.isLoggable(Level.INFO)) {
+ DEBUG_LOG.info(String.format("Connection factory'%s' is now operational",
+ factory));
+ }
+ }
+
+ @Override
+ public void handleConnectionFactoryOffline(ConnectionFactory factory,
+ ErrorResultException error) {
+ if (DEBUG_LOG.isLoggable(Level.WARNING)) {
+ DEBUG_LOG.warning(String.format(
+ "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();
@@ -237,6 +275,17 @@
private volatile ErrorResultException lastFailure = null;
/**
+ * The event listener which should be notified when connection factories go
+ * on or off-line.
+ */
+ private final LoadBalancerEventListener listener;
+
+ /**
+ * Ensures that events are notified one at a time.
+ */
+ private final Object listenerLock = new Object();
+
+ /**
* Guarded by stateLock.
*/
private int offlineFactoriesCount = 0;
@@ -269,6 +318,7 @@
this.scheduler = DEFAULT_SCHEDULER.acquireIfNull(scheduler);
this.monitoringInterval = interval;
this.monitoringIntervalTimeUnit = unit;
+ this.listener = DEFAULT_LISTENER;
}
@Override
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LoadBalancerEventListener.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LoadBalancerEventListener.java
new file mode 100644
index 0000000..6e1fd11
--- /dev/null
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/LoadBalancerEventListener.java
@@ -0,0 +1,62 @@
+/*
+ * 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 legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * 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 legal-notices/CDDLv1_0.txt.
+ * 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 2013 ForgeRock AS.
+ */
+
+package org.forgerock.opendj.ldap;
+
+import java.util.EventListener;
+
+/**
+ * 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.
+ * <p>
+ * <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.
+ */
+public interface LoadBalancerEventListener extends EventListener {
+
+ /**
+ * Invoked when the load-balancer is unable to obtain a connection from the
+ * specified connection factory. The connection factory will be removed from
+ * the load-balancer and monitored periodically in order to determine when
+ * it is available again, at which point an online notification event will
+ * occur.
+ *
+ * @param factory
+ * The connection factory which has failed.
+ * @param error
+ * The last error that occurred.
+ */
+ void handleConnectionFactoryOffline(ConnectionFactory factory, ErrorResultException error);
+
+ /**
+ * Invoked when the load-balancer detects that a previously offline
+ * connection factory is available for use again.
+ *
+ * @param factory
+ * The connection factory which is now available for use.
+ */
+ void handleConnectionFactoryOnline(ConnectionFactory factory);
+}
--
Gitblit v1.10.0