Monday, October 24, 2011

Spring LDAP Pool implementation

If you need to use a pool to hold your LDAP connections, then you will setup the ldap bean properties in your beans.xml like so:
 <bean id="contextSource"  
     class="org.springframework.ldap.pool.factory.PoolingContextSource">  
     <property name="contextSource" ref="contextSourceTarget" />  
     <property name="dirContextValidator" ref="dirContextValidator" />  
     <property name="testOnBorrow" value="true" />  
     <property name="testWhileIdle" value="true" />  
     <property name="timeBetweenEvictionRunsMillis" value="${ldapPool.timeBetweenEvictionRunsMillis}" />  
     <property name="minEvictableIdleTimeMillis" value="${ldapPool.minEvictableIdleTimeMillis}" />  
     <property name="maxActive" value="${ldapPool.maxActiveConnections}" />  
     <!-- Open up "minIdle" connections when first request comes in -->  
     <property name="minIdle" value="${ldapPool.initialPoolSize}" />  
     <!-- maxIdle: set this, or it uses the default of 8 -->  
     <property name="maxIdle" value="${ldapPool.maxActiveConnections}" />  
     <!-- Round robin -->  
     <property name="lifo" value="false" />  
   </bean>  
   <bean id="dirContextValidator" class="org.springframework.ldap.pool.validation.DefaultDirContextValidator" />  
   <bean id="contextSourceTarget" class="org.springframework.ldap.core.support.LdapContextSource">  
     <property name="url" value="${ldapConfig.url}" />  
     <property name="base" value="${ldapConfig.base}" />  
     <property name="userDn" value="${ldapConfig.userDN}" />  
     <property name="password" value="${ldapConfig.password}" />  
     <property name="pooled" value="false" />  
   </bean>  
   <bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">  
     <constructor-arg ref="contextSource" />  
   </bean>  
   <bean id="myDao" class="com....DAOImpl">  
     <property name="ldapTemplate" ref="ldapTemplate" />  
   </bean>  
This has been well defined in the spring ldap tutorials.

We had requirements to be able to open up a fixed number of connections to the ldap server on startup of the pool.  In other words pre-populate the pool with the connections.
Since the spring ldap pool is using the apache commons pool - in particular the GenericKeyedObjectPool, we came across the minIdle property.
"minIdle sets a target value for the minimum number of idle objects (per key) that should always be available. If this parameter is set to a positive number and timeBetweenEvictionRunsMillis > 0, each time the idle object eviction thread runs, it will try to create enough idle instances so that there will be minIdle idle instances available under each key. This parameter is also used by preparePool if true is provided as that method's populateImmediately parameter. The default setting for this parameter is 0."
Setting the minIdle property didn't seem to do anything.  It looked like the preparePool method was not being invoked.
So, the work around was to extend the org.springframework.ldap.pool.factory.PoolingContextSource and calling the preparePool method on the keyedObjectPool object.

Another issue we found was that the lifo property of the apache commons pool configuration was not supported.  Now since we had already extended the PoolingContextSource class, it was trivial to set the lifo property on the pool.

In case you have a pool of more than 8 active connections, you should set the maxIdle property.  If this is not set you will never see the pool size increase more than 8.  Also, you will see connections being closed and new ones being opened and put in the pool when the load (requests) increase more than 8.  (The implementation uses a default of 8)



No comments:

Post a Comment