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 }