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.impl.GenericObjectPool;
25  import org.apache.directory.api.ldap.codec.api.LdapApiService;
26  import org.apache.directory.api.ldap.model.exception.LdapException;
27  import org.slf4j.Logger;
28  import org.slf4j.LoggerFactory;
29  
30  
31  /**
32   * A pool implementation for LdapConnection objects.
33   * 
34   * This class is just a wrapper around the commons GenericObjectPool, and has
35   * a more meaningful name to represent the pool type.
36   * 
37   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
38   */
39  public class LdapConnectionPool extends GenericObjectPool<LdapConnection>
40  {
41      private static Logger LOG = LoggerFactory.getLogger( LdapConnectionPool.class );
42  
43      private PoolableLdapConnectionFactory factory;
44  
45  
46      /**
47       * Instantiates a new LDAP connection pool.
48       *
49       * @param connectionConfig The connection configuration
50       * @param apiService The api service (codec)
51       * @param timeout The connection timeout in millis
52       */
53      public LdapConnectionPool( LdapConnectionConfig connectionConfig,
54          LdapApiService apiService, long timeout )
55      {
56          this( connectionConfig, apiService, timeout, null );    
57      }
58      
59      
60      /**
61       * Instantiates a new LDAP connection pool.
62       *
63       * @param connectionConfig The connection configuration
64       * @param apiService The api service (codec)
65       * @param timeout The connection timeout in millis
66       * @param poolConfig The pool configuration
67       */
68      public LdapConnectionPool( LdapConnectionConfig connectionConfig,
69          LdapApiService apiService, long timeout, Config poolConfig )
70      {
71          this( newPoolableConnectionFactory( connectionConfig, apiService, timeout ), poolConfig );
72      }
73  
74  
75      /**
76       * Instantiates a new LDAP connection pool.
77       *
78       * @param factory The LDAP connection factory
79       */
80      public LdapConnectionPool( PoolableLdapConnectionFactory factory )
81      {
82          this( factory, null );
83      }
84  
85      /**
86       * Instantiates a new LDAP connection pool.
87       *
88       * @param factory The LDAP connection factory
89       * @param poolConfig The pool configuration
90       */
91      public LdapConnectionPool( PoolableLdapConnectionFactory factory, Config poolConfig )
92      {
93          super( factory, poolConfig == null ? new Config() : poolConfig );
94          this.factory = factory;
95      }
96  
97  
98      /**
99       * Returns the LdapApiService instance used by this connection pool.
100      *
101      * @return The LdapApiService instance used by this connection pool.
102      */
103     public LdapApiService getLdapApiService()
104     {
105         return factory.getLdapApiService();
106     }
107 
108 
109     /**
110      * Gives a LdapConnection fetched from the pool.
111      *
112      * @return an LdapConnection object from pool
113      * @throws Exception if an error occurs while obtaining a connection from the factory
114      */
115     public LdapConnection getConnection() throws LdapException
116     {
117         LdapConnection connection;
118         try
119         {
120             connection = super.borrowObject();
121         }
122         catch ( LdapException e )
123         {
124             throw ( e );
125         }
126         catch ( RuntimeException e )
127         {
128             throw ( e );
129         }
130         catch ( Exception e )
131         {
132             // wrap in runtime, but this should NEVER happen per published 
133             // contract as it only throws what the makeObject throws and our 
134             // PoolableLdapConnectionFactory only throws LdapException
135             LOG.error( "An unexpected exception was thrown: ", e );
136             throw new RuntimeException( e );
137         }
138         return connection;
139     }
140 
141 
142     /**
143      * Returns an LdapConnection from the pool that is not bound to an
144      * identity.  This type of connection is useful when you want to bind
145      * yourself for authentication/authorization purposes.
146      *
147      * @return An unbound LdapConnection from the pool
148      * @throws Exception If an error occurs while obtaining a connection 
149      * from the factory
150      */
151     public LdapConnection getUnboundConnection() throws LdapException
152     {
153         LdapConnection connection = getConnection();
154         connection.unBind();
155         return connection;
156     }
157 
158 
159     private static PoolableLdapConnectionFactory newPoolableConnectionFactory(
160         LdapConnectionConfig connectionConfig, LdapApiService apiService,
161         long timeout )
162     {
163         DefaultLdapConnectionFactory connectionFactory =
164             new DefaultLdapConnectionFactory( connectionConfig );
165         connectionFactory.setLdapApiService( apiService );
166         connectionFactory.setTimeOut( timeout );
167         return new PoolableLdapConnectionFactory( connectionFactory );
168     }
169 
170 
171     /**
172      * Places the given LdapConnection back in the pool.
173      * 
174      * @param connection the LdapConnection to be released
175      * @throws Exception if an error occurs while releasing the connection
176      */
177     public void releaseConnection( LdapConnection connection ) throws LdapException
178     {
179         try
180         {
181             super.returnObject( connection );
182         }
183         catch ( LdapException e )
184         {
185             throw ( e );
186         }
187         catch ( RuntimeException e )
188         {
189             throw ( e );
190         }
191         catch ( Exception e )
192         {
193             // wrap in runtime, but this should NEVER happen as it only throws 
194             // what the passivateObject throws and our 
195             // PoolableLdapConnectionFactory only throws LdapException
196             LOG.error( "An unexpected exception was thrown: ", e );
197             throw new RuntimeException( e );
198         }
199     }
200 }