001 /*
002 * Copyright 2009-2016 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2009-2016 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021 package com.unboundid.ldap.sdk;
022
023
024
025
026 import static com.unboundid.ldap.sdk.LDAPMessages.*;
027 import static com.unboundid.util.StaticUtils.*;
028
029
030
031 /**
032 * This class provides an API that may be used to determine whether connections
033 * associated with a connection pool are valid and suitable for use. It
034 * provides the ability to check the validity of a connection at the following
035 * times:
036 * <UL>
037 * <LI>Whenever a new connection is created for use in the pool, the
038 * {@code ensureNewConnectionValid(LDAPConnection)} method will be called
039 * before making that connection available. The default implementation
040 * provided in this class does not perform any kind of processing, but
041 * subclasses may override this behavior if desired.</LI>
042 * <LI>Whenever a connection is checked out from the pool (including
043 * connections checked out internally for operations performed in the
044 * pool), the {@code ensureConnectionValidForCheckout(LDAPConnection)}
045 * method will be called. The default implementation provided in this
046 * class does not perform any kind of processing, but subclasses may
047 * override this behavior if desired.</LI>
048 * <LI>Whenever a connection is released back to the pool (including
049 * connections checked out internally for operations performed in the
050 * pool), the {@code ensureConnectionValidForRelease(LDAPConnection)}
051 * method will be called. The default implementation provided in this
052 * class does not perform any kind of processing, but subclasses may
053 * override this behavior if desired.</LI>
054 * <LI>The {@code ensureConnectionValidForContinuedUse(LDAPConnection)}
055 * method will be invoked periodically by a background thread created by
056 * the connection pool to determine whether available connections within
057 * the pool are still valid. The default implementation provided in this
058 * class does not perform any kind of processing, but subclasses may
059 * override this behavior if desired.</LI>
060 * <LI>The {@code ensureConnectionValidAfterException} method may be invoked
061 * if an exception is caught while processing an operation with a
062 * connection that is part of a connection pool. The default
063 * implementation provided in this class only examines the result code of
064 * the provided exception and uses the
065 * {@code ResultCode#isConnectionUsable(ResultCode)} method to make the
066 * determination, but subclasses may override this behavior if
067 * desired.</LI>
068 * </UL>
069 * Note that health check implementations should be designed so that they are
070 * suitable for use with connections having any authentication state. The
071 * {@code ensureNewConnectionValid(LDAPConnection)} method will be invoked on
072 * unauthenticated connections, and the remaining health check methods will be
073 * invoked using whatever credentials are assigned to connections in the
074 * associated connection pool.
075 */
076 public class LDAPConnectionPoolHealthCheck
077 {
078 /**
079 * Creates a new instance of this LDAP connection pool health check.
080 */
081 public LDAPConnectionPoolHealthCheck()
082 {
083 // No implementation is required.
084 }
085
086
087
088 /**
089 * Performs any desired processing to determine whether the provided new
090 * connection is available to be checked out and used for processing
091 * operations. This method will be invoked by either {@code ServerSet} used
092 * by the connection pool (if it supports enhanced health checking) or by the
093 * connection pool itself at the time that a new connection is created. No
094 * authentication will have been performed on this connection at the time the
095 * health check is invoked.
096 *
097 * @param connection The connection to be examined.
098 *
099 * @throws LDAPException If a problem is detected that suggests that the
100 * provided connection is not suitable for use.
101 */
102 public void ensureNewConnectionValid(final LDAPConnection connection)
103 throws LDAPException
104 {
105 // No processing is performed in this default implementation.
106 }
107
108
109
110 /**
111 * Performs any desired processing to determine whether the provided
112 * connection is valid after processing a bind operation with the provided
113 * result.
114 * <BR><BR>
115 * This method will be invoked under the following circumstances:
116 * <UL>
117 * <LI>
118 * If you create a connection pool with a {@code ServerSet} and a
119 * non-{@code null} {@code BindRequest}, then this health check method
120 * will be invoked for every new connection created by the pool after
121 * processing that {@code BindRequest} on the connection. If you create a
122 * connection pool with a {@code ServerSet} but a {@code null}
123 * {@code BindRequest}, then no authentication will be attempted (and
124 * therefore this health check method will not be invoked for)
125 * newly-created connections.
126 * </LI>
127 * <LI>
128 * If you create a connection pool with an {@code LDAPConnection} after
129 * having performed a bind operation on that connection, then every new
130 * connection created by the pool will attempt to perform the same type of
131 * bind operation and this health check method will be invoked after that
132 * bind attempt has completed. If you create a connection pool with an
133 * {@code LDAPConnection} that has not been authenticated, then no
134 * authentication will be attempted (and therefore this health check
135 * method will not be invoked for) newly-created connections.
136 * </LI>
137 * <LI>
138 * If you call a connection pool's {@code bindAndRevertAuthentication}
139 * method, then this health check method will be called after the second
140 * bind operation (the one used to revert authentication) has completed.
141 * In this case, this health check method will be called even if the
142 * connection pool was created with a {@code null} {@code BindRequest} or
143 * with an unauthenticated {@code LDAPConnection}. In that case, the
144 * bind operation used to revert authentication will be a
145 * {@code SimpleBindRequest} with an empty DN and password.
146 * </LI>
147 * <LI>
148 * If you call a connection pool's
149 * {@code releaseAndReAuthenticateConnection} method, then this health
150 * check method will be called after the bind operation has completed. As
151 * with {@code bindAndRevertAuthentication}, this health check method will
152 * be called even if the connection pool was created with a {@code null}
153 * {@code BindRequest} or with an unauthenticated {@code LDAPConnection}.
154 * </LI>
155 * </UL>
156 * <BR><BR>
157 * Note that this health check method may be invoked even if the bind
158 * attempt was not successful. This is useful because it allows the health
159 * check to intercept a failed authentication attempt and differentiate it
160 * from other types of failures in the course of trying to create or check out
161 * a connection. In the event that it is invoked with a {@code BindResult}
162 * that has a result code other than {@code ResultCode#SUCCESS}, if this
163 * method throws an exception then that exception will be propagated to the
164 * caller. If this method does not throw an exception when provided with a
165 * non-{@code SUCCESS} result, then the connection pool itself will throw an
166 * exception using the information in the bind result.
167 *
168 * @param connection The connection to be examined.
169 * @param bindResult The bind result obtained from the authentication
170 * process.
171 *
172 * @throws LDAPException If a problem is detected that suggests that the
173 * provided connection is not suitable for use.
174 */
175 public void ensureConnectionValidAfterAuthentication(
176 final LDAPConnection connection,
177 final BindResult bindResult)
178 throws LDAPException
179 {
180 // No processing is performed in this default implementation.
181 }
182
183
184
185 /**
186 * Performs any desired processing to determine whether the provided
187 * connection is available to be checked out and used for processing
188 * operations. This method will be invoked by the
189 * {@code LDAPConnectionPool#getConnection()} method before handing out a
190 * connection. This method should return normally if the connection is
191 * believed to be valid, or should throw an {@code LDAPException} if a problem
192 * is detected.
193 *
194 * @param connection The connection to be examined.
195 *
196 * @throws LDAPException If a problem is detected that suggests that the
197 * provided connection is not suitable for use.
198 */
199 public void ensureConnectionValidForCheckout(final LDAPConnection connection)
200 throws LDAPException
201 {
202 // No processing is performed in this default implementation.
203 }
204
205
206
207 /**
208 * Performs any desired processing to determine whether the provided
209 * connection is valid and should be released back to the pool to be used for
210 * processing other operations. This method will be invoked by the
211 * {@code LDAPConnectionPool#releaseConnection(LDAPConnection)} method before
212 * making the connection available for use in processing other operations.
213 * This method should return normally if the connection is believed to be
214 * valid, or should throw an {@code LDAPException} if a problem is detected.
215 *
216 * @param connection The connection to be examined.
217 *
218 * @throws LDAPException If a problem is detected that suggests that the
219 * provided connection is not suitable for use.
220 */
221 public void ensureConnectionValidForRelease(final LDAPConnection connection)
222 throws LDAPException
223 {
224 // No processing is performed in this default implementation.
225 }
226
227
228
229 /**
230 * Performs any desired processing to determine whether the provided
231 * connection is valid and should continue to be made available for
232 * processing operations. This method will be periodically invoked by a
233 * background thread used to test availability of connections within the pool.
234 * This method should return normally if the connection is believed to be
235 * valid, or should throw an {@code LDAPException} if a problem is detected.
236 *
237 * @param connection The connection to be examined.
238 *
239 * @throws LDAPException If a problem is detected that suggests that the
240 * provided connection is not suitable for use.
241 */
242 public void ensureConnectionValidForContinuedUse(
243 final LDAPConnection connection)
244 throws LDAPException
245 {
246 // No processing is performed in this default implementation.
247 }
248
249
250
251 /**
252 * Indicates whether the provided connection may still be considered valid
253 * after an attempt to process an operation yielded the given exception. This
254 * method will be invoked by the
255 * {@code LDAPConnectionPool#releaseConnectionAfterException} method, and it
256 * may also be manually invoked by external callers if an exception is
257 * encountered while processing an operation on a connection checked out from
258 * the pool. It may make a determination based solely on the provided
259 * exception, or it may also attempt to use the provided connection to further
260 * test its validity. This method should return normally if the connection is
261 * believed to be valid, or should throw an {@code LDAPException} if a problem
262 * is detected.
263 *
264 * @param connection The connection to be examined.
265 * @param exception The exception that was caught while processing an
266 * operation on the connection.
267 *
268 * @throws LDAPException If a problem is detected that suggests that the
269 * provided connection is not suitable for use.
270 */
271 public void ensureConnectionValidAfterException(
272 final LDAPConnection connection,
273 final LDAPException exception)
274 throws LDAPException
275 {
276 if (! ResultCode.isConnectionUsable(exception.getResultCode()))
277 {
278 throw new LDAPException(ResultCode.SERVER_DOWN,
279 ERR_POOL_HEALTH_CHECK_CONN_INVALID_AFTER_EXCEPTION.get(
280 getExceptionMessage(exception)),
281 exception);
282 }
283 }
284
285
286
287 /**
288 * Retrieves a string representation of this LDAP connection pool health
289 * check.
290 *
291 * @return A string representation of this LDAP connection pool health check.
292 */
293 @Override()
294 public final String toString()
295 {
296 final StringBuilder buffer = new StringBuilder();
297 toString(buffer);
298 return buffer.toString();
299 }
300
301
302
303 /**
304 * Appends a string representation of this LDAP connection pool health check
305 * to the provided buffer.
306 *
307 * @param buffer The buffer to which the information should be appended.
308 */
309 public void toString(final StringBuilder buffer)
310 {
311 buffer.append("LDAPConnectionPoolHealthCheck()");
312 }
313 }