View Javadoc
1   /*
2    *   Licensed to the Apache Software Foundation (ASF) under one
3    *   or more contributor license agreements.  See the NOTICE file
4    *   distributed with this work for additional information
5    *   regarding copyright ownership.  The ASF licenses this file
6    *   to you under the Apache License, Version 2.0 (the
7    *   "License"); you may not use this file except in compliance
8    *   with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing,
13   *   software distributed under the License is distributed on an
14   *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *   KIND, either express or implied.  See the License for the
16   *   specific language governing permissions and limitations
17   *   under the License.
18   *
19   */
20  
21  package org.apache.directory.ldap.client.api;
22  
23  
24  import org.apache.commons.pool.PoolableObjectFactory;
25  import org.apache.commons.pool.impl.GenericObjectPool;
26  import org.apache.directory.api.ldap.codec.api.LdapApiService;
27  import org.apache.directory.api.ldap.model.exception.LdapException;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  
31  
32  /**
33   * A pool implementation for LdapConnection objects.
34   * 
35   * This class is just a wrapper around the commons GenericObjectPool, and has
36   * a more meaningful name to represent the pool type.
37   * 
38   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
39   */
40  public class LdapConnectionPool extends GenericObjectPool<LdapConnection>
41  {
42      private static Logger LOG = LoggerFactory.getLogger( LdapConnectionPool.class );
43  
44      private PoolableObjectFactory<LdapConnection> factory;
45  
46  
47      /**
48       * Instantiates a new LDAP connection pool.
49       *
50       * @param connectionConfig The connection configuration
51       * @param apiService The api service (codec)
52       * @param timeout The connection timeout in millis
53       */
54      public LdapConnectionPool( LdapConnectionConfig connectionConfig,
55          LdapApiService apiService, long timeout )
56      {
57          this( connectionConfig, apiService, timeout, null );
58      }
59  
60  
61      /**
62       * Instantiates a new LDAP connection pool.
63       *
64       * @param connectionConfig The connection configuration
65       * @param apiService The api service (codec)
66       * @param timeout The connection timeout in millis
67       * @param poolConfig The pool configuration
68       */
69      public LdapConnectionPool( LdapConnectionConfig connectionConfig,
70          LdapApiService apiService, long timeout, Config poolConfig )
71      {
72          this( newPoolableConnectionFactory( connectionConfig, apiService, timeout ), poolConfig );
73      }
74  
75  
76      /**
77       * Instantiates a new LDAP connection pool.
78       *
79       * @param factory The LDAP connection factory
80       */
81      public LdapConnectionPool( PoolableObjectFactory<LdapConnection> factory )
82      {
83          this( factory, null );
84      }
85  
86  
87      /**
88       * Instantiates a new LDAP connection pool.
89       *
90       * @param factory The LDAP connection factory
91       * @param poolConfig The pool configuration
92       */
93      public LdapConnectionPool( PoolableObjectFactory<LdapConnection> factory, Config poolConfig )
94      {
95          super( factory, poolConfig == null ? new Config() : poolConfig );
96          this.factory = factory;
97      }
98  
99  
100     /**
101      * Returns the LdapApiService instance used by this connection pool.
102      *
103      * @return The LdapApiService instance used by this connection pool.
104      */
105     public LdapApiService getLdapApiService()
106     {
107         return ( ( AbstractPoolableLdapConnectionFactory ) factory ).getLdapApiService();
108     }
109 
110 
111     /**
112      * Gives a LdapConnection fetched from the pool.
113      *
114      * @return an LdapConnection object from pool
115      * @throws Exception if an error occurs while obtaining a connection from the factory
116      */
117     public LdapConnection getConnection() throws LdapException
118     {
119         LdapConnection connection;
120 
121         try
122         {
123             connection = super.borrowObject();
124             LOG.trace( "borrowed connection {}", connection );
125         }
126         catch ( LdapException e )
127         {
128             throw ( e );
129         }
130         catch ( RuntimeException e )
131         {
132             throw ( e );
133         }
134         catch ( Exception e )
135         {
136             // wrap in runtime, but this should NEVER happen per published 
137             // contract as it only throws what the makeObject throws and our 
138             // PoolableLdapConnectionFactory only throws LdapException
139             LOG.error( "An unexpected exception was thrown: ", e );
140             throw new RuntimeException( e );
141         }
142 
143         return connection;
144     }
145 
146 
147     private static ValidatingPoolableLdapConnectionFactory newPoolableConnectionFactory(
148         LdapConnectionConfig connectionConfig, LdapApiService apiService,
149         long timeout )
150     {
151         DefaultLdapConnectionFactory connectionFactory =
152             new DefaultLdapConnectionFactory( connectionConfig );
153         connectionFactory.setLdapApiService( apiService );
154         connectionFactory.setTimeOut( timeout );
155         return new ValidatingPoolableLdapConnectionFactory( connectionFactory );
156     }
157 
158 
159     /**
160      * Places the given LdapConnection back in the pool.
161      * 
162      * @param connection the LdapConnection to be released
163      * @throws Exception if an error occurs while releasing the connection
164      */
165     public void releaseConnection( LdapConnection connection ) throws LdapException
166     {
167         try
168         {
169             super.returnObject( connection );
170             LOG.trace( "returned connection {}", connection );
171         }
172         catch ( LdapException e )
173         {
174             throw ( e );
175         }
176         catch ( RuntimeException e )
177         {
178             throw ( e );
179         }
180         catch ( Exception e )
181         {
182             // wrap in runtime, but this should NEVER happen as it only throws 
183             // what the passivateObject throws and our 
184             // PoolableLdapConnectionFactory only throws LdapException
185             LOG.error( "An unexpected exception was thrown: ", e );
186             throw new RuntimeException( e );
187         }
188     }
189 }