001    /*
002     * Copyright 2009-2014 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2009-2014 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 which 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.
094       *
095       * @param  connection  The connection to be examined.
096       *
097       * @throws  LDAPException  If a problem is detected which suggests that the
098       *                         provided connection is not suitable for use.
099       */
100      public void ensureNewConnectionValid(final LDAPConnection connection)
101             throws LDAPException
102      {
103        // No processing is performed in this default implementation.
104      }
105    
106    
107    
108      /**
109       * Performs any desired processing to determine whether the provided
110       * connection is available to be checked out and used for processing
111       * operations.  This method will be invoked by the
112       * {@code LDAPConnectionPool#getConnection()} method before handing out a
113       * connection.  This method should return normally if the connection is
114       * believed to be valid, or should throw an {@code LDAPException} if a problem
115       * is detected.
116       *
117       * @param  connection  The connection to be examined.
118       *
119       * @throws  LDAPException  If a problem is detected which suggests that the
120       *                         provided connection is not suitable for use.
121       */
122      public void ensureConnectionValidForCheckout(final LDAPConnection connection)
123             throws LDAPException
124      {
125        // No processing is performed in this default implementation.
126      }
127    
128    
129    
130      /**
131       * Performs any desired processing to determine whether the provided
132       * connection is valid and should be released back to the pool to be used for
133       * processing other operations.  This method will be invoked by the
134       * {@code LDAPConnectionPool#releaseConnection(LDAPConnection)} method before
135       * making the connection available for use in processing other operations.
136       * This method should return normally if the connection is believed to be
137       * valid, or should throw an {@code LDAPException} if a problem is detected.
138       *
139       * @param  connection  The connection to be examined.
140       *
141       * @throws  LDAPException  If a problem is detected which suggests that the
142       *                         provided connection is not suitable for use.
143       */
144      public void ensureConnectionValidForRelease(final LDAPConnection connection)
145             throws LDAPException
146      {
147        // No processing is performed in this default implementation.
148      }
149    
150    
151    
152      /**
153       * Performs any desired processing to determine whether the provided
154       * connection is valid and should continue to be made available for
155       * processing operations.  This method will be periodically invoked by a
156       * background thread used to test availability of connections within the pool.
157       * This method should return normally if the connection is believed to be
158       * valid, or should throw an {@code LDAPException} if a problem is detected.
159       *
160       * @param  connection  The connection to be examined.
161       *
162       * @throws  LDAPException  If a problem is detected which suggests that the
163       *                         provided connection is not suitable for use.
164       */
165      public void ensureConnectionValidForContinuedUse(
166                       final LDAPConnection connection)
167             throws LDAPException
168      {
169        // No processing is performed in this default implementation.
170      }
171    
172    
173    
174      /**
175       * Indicates whether the provided connection may still be considered valid
176       * after an attempt to process an operation yielded the given exception.  This
177       * method will be invoked by the
178       * {@code LDAPConnectionPool#releaseConnectionAfterException} method, and it
179       * may also be manually invoked by external callers if an exception is
180       * encountered while processing an operation on a connection checked out from
181       * the pool.  It may make a determination based solely on the provided
182       * exception, or it may also attempt to use the provided connection to further
183       * test its validity.  This method should return normally if the connection is
184       * believed to be valid, or should throw an {@code LDAPException} if a problem
185       * is detected.
186       *
187       * @param  connection  The connection to be examined.
188       * @param  exception   The exception that was caught while processing an
189       *                     operation on the connection.
190       *
191       * @throws  LDAPException  If a problem is detected which suggests that the
192       *                         provided connection is not suitable for use.
193       */
194      public void ensureConnectionValidAfterException(
195                       final LDAPConnection connection,
196                       final LDAPException exception)
197             throws LDAPException
198      {
199        if (! ResultCode.isConnectionUsable(exception.getResultCode()))
200        {
201          throw new LDAPException(ResultCode.SERVER_DOWN,
202               ERR_POOL_HEALTH_CHECK_CONN_INVALID_AFTER_EXCEPTION.get(
203                    getExceptionMessage(exception)),
204               exception);
205        }
206      }
207    
208    
209    
210      /**
211       * Retrieves a string representation of this LDAP connection pool health
212       * check.
213       *
214       * @return  A string representation of this LDAP connection pool health check.
215       */
216      @Override()
217      public final String toString()
218      {
219        final StringBuilder buffer = new StringBuilder();
220        toString(buffer);
221        return buffer.toString();
222      }
223    
224    
225    
226      /**
227       * Appends a string representation of this LDAP connection pool health check
228       * to the provided buffer.
229       *
230       * @param  buffer  The buffer to which the information should be appended.
231       */
232      public void toString(final StringBuilder buffer)
233      {
234        buffer.append("LDAPConnectionPoolHealthCheck()");
235      }
236    }