You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by yu...@apache.org on 2018/04/25 04:36:45 UTC
directory-fortress-core git commit: fixing buggy logic and implement
HA at ldap connection provider
Repository: directory-fortress-core
Updated Branches:
refs/heads/trivial/support-ha-client 5d7ed4a5b -> 621883ef6
fixing buggy logic and implement HA at ldap connection provider
Project: http://git-wip-us.apache.org/repos/asf/directory-fortress-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-fortress-core/commit/621883ef
Tree: http://git-wip-us.apache.org/repos/asf/directory-fortress-core/tree/621883ef
Diff: http://git-wip-us.apache.org/repos/asf/directory-fortress-core/diff/621883ef
Branch: refs/heads/trivial/support-ha-client
Commit: 621883ef64fa186b51855f3f390ceefc7ea13080
Parents: 5d7ed4a
Author: yudhi.k.surtan <yu...@gdn-commerce.com>
Authored: Wed Apr 25 11:36:33 2018 +0700
Committer: yudhi.k.surtan <yu...@gdn-commerce.com>
Committed: Wed Apr 25 11:36:33 2018 +0700
----------------------------------------------------------------------
.../core/ldap/LdapConnectionProvider.java | 206 +++++++++----------
.../core/ldap/LdapHAConnectionPool.java | 37 +++-
2 files changed, 127 insertions(+), 116 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/621883ef/src/main/java/org/apache/directory/fortress/core/ldap/LdapConnectionProvider.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/LdapConnectionProvider.java b/src/main/java/org/apache/directory/fortress/core/ldap/LdapConnectionProvider.java
index 046c18b..4699576 100644
--- a/src/main/java/org/apache/directory/fortress/core/ldap/LdapConnectionProvider.java
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/LdapConnectionProvider.java
@@ -58,6 +58,7 @@ import org.slf4j.LoggerFactory;
public class LdapConnectionProvider
{
+ private static final int DEFAULT_LDAP_TIMEOUT = 2000;
private static final String CLS_NM = LdapConnectionProvider.class.getName();
private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
@@ -72,17 +73,18 @@ public class LdapConnectionProvider
/**
* The Admin connection pool
*/
- private static LdapConnectionPool adminPool;
+// private static LdapConnectionPool adminPool;
+ private static LdapHAConnectionPool adminPool;
/**
* The Log connection pool
*/
- private static LdapConnectionPool logPool;
+ private static LdapHAConnectionPool logPool;
/**
* The User connection pool
*/
- private static LdapConnectionPool userPool;
+ private static LdapHAConnectionPool userPool;
private static volatile LdapConnectionProvider sINSTANCE = null;
@@ -99,10 +101,12 @@ public class LdapConnectionProvider
{
if ( sINSTANCE == null )
{
+ LOG.info( "construct a new ldap connection provider" );
sINSTANCE = new LdapConnectionProvider();
}
}
}
+ LOG.info( "return existing ldap connection provider" );
return sINSTANCE;
}
@@ -133,81 +137,12 @@ public class LdapConnectionProvider
int logmax = Config.getInstance().getInt( LDAP_LOG_POOL_MAX, 10 );
LOG.info( "LDAP POOL: host=[{}], port=[{}], min=[{}], max=[{}]", host, port, min, max );
- LdapConnectionConfig config = new LdapConnectionConfig();
- config.setLdapHost( host );
- config.setLdapPort( port );
- config.setName( Config.getInstance().getProperty( GlobalIds.LDAP_ADMIN_POOL_UID, "" ) );
-
- config.setUseSsl( IS_SSL );
- //config.setTrustManagers( new NoVerificationTrustManager() );
-
- if ( Config.getInstance().getBoolean( ENABLE_LDAP_STARTTLS, false ) )
- {
- config.setUseTls( true );
- }
-
- if ( IS_SSL && StringUtils.isNotEmpty( Config.getInstance().getProperty( GlobalIds.TRUST_STORE ) ) &&
- StringUtils.isNotEmpty( Config.getInstance().getProperty( GlobalIds.TRUST_STORE_PW ) ) )
- {
- // validate certificates but allow self-signed certs if within this truststore:
- config.setTrustManagers( new LdapClientTrustStoreManager( Config.getInstance().getProperty( GlobalIds
- .TRUST_STORE ), Config.getInstance().getProperty( GlobalIds.TRUST_STORE_PW ).toCharArray(), null,
- true ) );
- }
-
- String adminPw;
- if ( EncryptUtil.isEnabled() )
- {
- adminPw = EncryptUtil.getInstance().decrypt( Config.getInstance().getProperty( GlobalIds
- .LDAP_ADMIN_POOL_PW, true ) );
- }
- else
- {
- adminPw = Config.getInstance().getProperty( GlobalIds.LDAP_ADMIN_POOL_PW, true );
- }
-
- config.setCredentials( adminPw );
- try
- {
- List<String> listExOps = new ArrayList<>();
- listExOps.add( "org.openldap.accelerator.impl.createSession.RbacCreateSessionFactory" );
- listExOps.add( "org.openldap.accelerator.impl.checkAccess.RbacCheckAccessFactory" );
- listExOps.add( "org.openldap.accelerator.impl.addRole.RbacAddRoleFactory" );
- listExOps.add( "org.openldap.accelerator.impl.dropRole.RbacDropRoleFactory" );
- listExOps.add( "org.openldap.accelerator.impl.deleteSession.RbacDeleteSessionFactory" );
- listExOps.add( "org.openldap.accelerator.impl.sessionRoles.RbacSessionRolesFactory" );
- LdapApiService ldapApiService = new StandaloneLdapApiService( new ArrayList<String>(), listExOps );
-
- if ( !LdapApiServiceFactory.isInitialized() )
- {
- LdapApiServiceFactory.initialize( ldapApiService );
- }
- config.setLdapApiService( ldapApiService );
- }
- catch ( Exception ex )
- {
- String error = "Exception caught initializing Admin Pool: " + ex;
- throw new CfgRuntimeException( GlobalErrIds.FT_APACHE_LDAP_POOL_INIT_FAILED, error, ex );
- }
-
- PoolableObjectFactory<LdapConnection> poolFactory = new ValidatingPoolableLdapConnectionFactory( config );
-
- // Create the Admin pool
- adminPool = new LdapConnectionPool( poolFactory );
- adminPool.setTestOnBorrow( true );
- adminPool.setWhenExhaustedAction( GenericObjectPool.WHEN_EXHAUSTED_GROW );
- adminPool.setMaxActive( max );
- adminPool.setMinIdle( min );
- adminPool.setMaxIdle( -1 );
- //adminPool.setMaxWait( 0 );
-
- // Create the User pool
- userPool = new LdapConnectionPool( poolFactory );
- userPool.setTestOnBorrow( true );
- userPool.setWhenExhaustedAction( GenericObjectPool.WHEN_EXHAUSTED_GROW );
- userPool.setMaxActive( max );
- userPool.setMinIdle( min );
- userPool.setMaxIdle( -1 );
+ LdapConnectionConfig[] ldapConnectionConfigs = populateLdapConnectionConfigs( host, port, IS_SSL, Config.getInstance().getProperty( GlobalIds.LDAP_ADMIN_POOL_UID, "" ), Config.getInstance().getProperty( GlobalIds
+ .LDAP_ADMIN_POOL_PW, true ), Config.getInstance().getBoolean( ENABLE_LDAP_STARTTLS, false ), Config.getInstance().getProperty( GlobalIds
+ .TRUST_STORE ), Config.getInstance().getProperty( GlobalIds.TRUST_STORE_PW ) );
+
+ adminPool = new LdapHAConnectionPool( ldapConnectionConfigs, HAConnectionStrategy.ROUND_ROBIN, true, GenericObjectPool.WHEN_EXHAUSTED_GROW, max, min, -1, 2 );
+ userPool = new LdapHAConnectionPool( ldapConnectionConfigs, HAConnectionStrategy.ROUND_ROBIN, true, GenericObjectPool.WHEN_EXHAUSTED_GROW, max, min, -1, 2 );
// This pool of access log connections is used by {@link org.apache.directory.fortress.AuditMgr}.
// To enable, set {@code log.admin.user} && {@code log.admin.pw} inside fortress.properties file:
@@ -216,39 +151,13 @@ public class LdapConnectionProvider
// Initializing the log pool in static block requires static props set within fortress.properties.
// To make this dynamic requires moving this code outside of static block AND storing the connection
// metadata inside fortress config node (in ldap).
- LdapConnectionConfig logConfig = new LdapConnectionConfig();
- logConfig.setLdapHost( host );
- logConfig.setLdapPort( port );
- logConfig.setName( Config.getInstance().getProperty( GlobalIds.LDAP_ADMIN_POOL_UID, "" ) );
-
- logConfig.setUseSsl( IS_SSL );
-
- if ( IS_SSL && StringUtils.isNotEmpty( Config.getInstance().getProperty( GlobalIds.TRUST_STORE ) ) &&
- StringUtils.isNotEmpty( Config.getInstance().getProperty( GlobalIds.TRUST_STORE_PW, true ) ) )
- {
- // validate certificates but allow self-signed certs if within this truststore:
- logConfig.setTrustManagers( new LdapClientTrustStoreManager( Config.getInstance().getProperty(
- GlobalIds.TRUST_STORE ), Config.getInstance().getProperty( GlobalIds.TRUST_STORE_PW, true ).toCharArray
- (), null, true ) );
- }
-
- logConfig.setName( Config.getInstance().getProperty( LDAP_LOG_POOL_UID, "" ) );
- String logPw;
- if ( EncryptUtil.isEnabled() )
- {
- logPw = EncryptUtil.getInstance().decrypt( Config.getInstance().getProperty( LDAP_LOG_POOL_PW, true ) );
- }
- else
- {
- logPw = Config.getInstance().getProperty( LDAP_LOG_POOL_PW, true );
- }
- logConfig.setCredentials( logPw );
- poolFactory = new ValidatingPoolableLdapConnectionFactory( logConfig );
- logPool = new LdapConnectionPool( poolFactory );
- logPool.setTestOnBorrow( true );
- logPool.setWhenExhaustedAction( GenericObjectPool.WHEN_EXHAUSTED_GROW );
- logPool.setMaxActive( logmax );
- logPool.setMinIdle( logmin );
+ LdapConnectionConfig logConfigs[] = populateLdapConnectionConfigs( host, port, IS_SSL,
+ Config.getInstance().getProperty( LDAP_LOG_POOL_UID, "" ),
+ Config.getInstance().getProperty( LDAP_LOG_POOL_PW, true ),
+ Config.getInstance().getBoolean( ENABLE_LDAP_STARTTLS, false ), Config.getInstance().getProperty( GlobalIds.TRUST_STORE ), Config.getInstance().getProperty( GlobalIds.TRUST_STORE_PW, true ) );
+
+
+ logPool = new LdapHAConnectionPool( logConfigs, HAConnectionStrategy.ROUND_ROBIN, true, GenericObjectPool.WHEN_EXHAUSTED_GROW, logmax, logmin, -1, 2 );
}
}
@@ -370,7 +279,7 @@ public class LdapConnectionProvider
{
try
{
- LOG.info( "Closing admin pool" );
+ LOG.trace( "Closing admin pool" );
adminPool.close();
}
catch ( Exception e )
@@ -380,7 +289,7 @@ public class LdapConnectionProvider
try
{
- LOG.info( "Closing user pool" );
+ LOG.trace( "Closing user pool" );
userPool.close();
}
catch ( Exception e )
@@ -390,7 +299,7 @@ public class LdapConnectionProvider
try
{
- LOG.info( "Closing log pool" );
+ LOG.trace( "Closing log pool" );
logPool.close();
}
catch ( Exception e )
@@ -398,4 +307,73 @@ public class LdapConnectionProvider
LOG.warn( "Error closing log pool: " + e.getMessage() );
}
}
+
+ private LdapConnectionConfig[] populateLdapConnectionConfigs(String host, int port, boolean isSSL, String ldapAdminId, String ldapAdminPassword, boolean isEnableLdapStartTLS, String trustStore, String trustStorePassword) {
+ String[] hosts = null;
+ if(host.contains( "," )) {
+ hosts = host.split( "," );
+ } else {
+ hosts = new String[1];
+ hosts[0] = host;
+ }
+ LdapConnectionConfig[] configs = new LdapConnectionConfig[hosts.length];
+ for(int i = 0; i < hosts.length ; i++) {
+ configs[i] = new LdapConnectionConfig();
+ configs[i].setLdapHost( hosts[i] );
+ configs[i].setLdapPort( port );
+ configs[i].setName( ldapAdminId );
+ //TODO: later need to include at the configuration level to adjust the value.
+ configs[i].setTimeout( DEFAULT_LDAP_TIMEOUT );
+ configs[i].setUseSsl( isSSL );
+ //config.setTrustManagers( new NoVerificationTrustManager() );
+
+ if ( isEnableLdapStartTLS )
+ {
+ configs[i].setUseTls( true );
+ }
+
+ if ( isSSL && StringUtils.isNotEmpty( trustStore ) &&
+ StringUtils.isNotEmpty( trustStorePassword ) )
+ {
+ // validate certificates but allow self-signed certs if within this truststore:
+ configs[i].setTrustManagers( new LdapClientTrustStoreManager( trustStore, trustStorePassword.toCharArray(), null,
+ true ) );
+ }
+
+ String adminPw;
+ if ( EncryptUtil.isEnabled() )
+ {
+ adminPw = EncryptUtil.getInstance().decrypt( ldapAdminPassword );
+ }
+ else
+ {
+ adminPw = ldapAdminPassword;
+ }
+
+ configs[i].setCredentials( adminPw );
+ try
+ {
+ List<String> listExOps = new ArrayList<>();
+ listExOps.add( "org.openldap.accelerator.impl.createSession.RbacCreateSessionFactory" );
+ listExOps.add( "org.openldap.accelerator.impl.checkAccess.RbacCheckAccessFactory" );
+ listExOps.add( "org.openldap.accelerator.impl.addRole.RbacAddRoleFactory" );
+ listExOps.add( "org.openldap.accelerator.impl.dropRole.RbacDropRoleFactory" );
+ listExOps.add( "org.openldap.accelerator.impl.deleteSession.RbacDeleteSessionFactory" );
+ listExOps.add( "org.openldap.accelerator.impl.sessionRoles.RbacSessionRolesFactory" );
+ LdapApiService ldapApiService = new StandaloneLdapApiService( new ArrayList<String>(), listExOps );
+
+ if ( !LdapApiServiceFactory.isInitialized() )
+ {
+ LdapApiServiceFactory.initialize( ldapApiService );
+ }
+ configs[i].setLdapApiService( ldapApiService );
+ }
+ catch ( Exception ex )
+ {
+ String error = "Exception caught initializing Admin Pool: " + ex;
+ throw new CfgRuntimeException( GlobalErrIds.FT_APACHE_LDAP_POOL_INIT_FAILED, error, ex );
+ }
+ }
+ return configs;
+ }
}
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/621883ef/src/main/java/org/apache/directory/fortress/core/ldap/LdapHAConnectionPool.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ldap/LdapHAConnectionPool.java b/src/main/java/org/apache/directory/fortress/core/ldap/LdapHAConnectionPool.java
index 238c399..5eaa5b0 100644
--- a/src/main/java/org/apache/directory/fortress/core/ldap/LdapHAConnectionPool.java
+++ b/src/main/java/org/apache/directory/fortress/core/ldap/LdapHAConnectionPool.java
@@ -1,7 +1,10 @@
package org.apache.directory.fortress.core.ldap;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.pool.impl.GenericObjectPool;
@@ -44,16 +47,36 @@ public class LdapHAConnectionPool
connectionPools = new LdapConnectionPool[configs.length];
for ( int i = 0; i < configs.length; i++ )
{
- connectionPools[i] = new LdapConnectionPool( new ValidatingPoolableLdapConnectionFactory( configs[i] ) );
+ ValidatingPoolableLdapConnectionFactory validatingPoolableLdapConnectionFactory = new ValidatingPoolableLdapConnectionFactory( configs[i] );
+ connectionPools[i] = new LdapConnectionPool( validatingPoolableLdapConnectionFactory );
connectionPools[i].setTestOnBorrow( true );
connectionPools[i].setWhenExhaustedAction( GenericObjectPool.WHEN_EXHAUSTED_GROW );
connectionPools[i].setMaxActive( maxActive );
connectionPools[i].setMinIdle( minIdle );
connectionPools[i].setMaxIdle( maxIdle );
+ connectionPools[i].setTestWhileIdle( true );
}
this.connectionStrategy = connectionStrategy;
}
+ public void close() throws Exception {
+ List<Exception> exceptions = new ArrayList<>();
+ String closingProcessId = UUID.randomUUID().toString().toUpperCase();
+ for(LdapConnectionPool connectionPool : connectionPools) {
+ try
+ {
+ connectionPool.close();
+ } catch ( Exception e )
+ {
+ LOG.error( "could not close connection pool, process id : " + closingProcessId, e );
+ exceptions.add( e );
+ }
+ }
+ if(!exceptions.isEmpty()) {
+ throw new Exception("there some close connection error, check your log for process id : " + closingProcessId);
+ }
+ }
+
public LdapConnection getConnection() throws LdapException
{
LdapConnection connection;
@@ -82,6 +105,7 @@ public class LdapHAConnectionPool
try
{
int poolIndex = masterNodeIndex.get();
+ LOG.trace( "active passive poolIndex : " + poolIndex );
borrowedConnection = connectionPools[poolIndex].borrowObject();
allowedRetriesCounter.set( allowedRetries );
CONNECTION_POOL_LOOKUP_TABLE.put( borrowedConnection.toString(), connectionPools[poolIndex] );
@@ -114,13 +138,16 @@ public class LdapHAConnectionPool
try
{
int poolIndex = getCurrentRequestNode();
+ LOG.trace( "round robin poolIndex : " + poolIndex );
borrowedConnection = connectionPools[poolIndex].borrowObject();
allowedRetriesCounter.set( allowedRetries );
+ LOG.trace( "putting " + borrowedConnection.toString() + " to the lookup pool" );
CONNECTION_POOL_LOOKUP_TABLE.put( borrowedConnection.toString(), connectionPools[poolIndex] );
} catch ( LdapException | RuntimeException e )
{
if ( allowedRetriesCounter.decrementAndGet() > 0 )
{
+ LOG.trace( "retrying connection left " + allowedRetriesCounter.get());
return getConnectionByStrategy();
} else
{
@@ -140,7 +167,13 @@ public class LdapHAConnectionPool
private int getCurrentRequestNode()
{
- return requestCounter.getAndIncrement() % availableNodes;
+ int current = requestCounter.getAndIncrement();
+ LOG.trace( "current : "+ current );
+ if(Integer.MAX_VALUE == current) {
+ requestCounter.set( 0 );
+ current = 0;
+ }
+ return current % availableNodes;
}
public void releaseConnection( LdapConnection connection )