Hi,

Nevermind, I found the issue.
I'll respond so you don't waste your time on this, and perhaps others find use 
to my comment.
The documentation is also a bit ambiguous.

The problem was that I specifically did an 'unbind'. I thought that would be 
safe.. before doing a 'bind' with another user on the same connection.
However, this is something you should specifically NOT do.
The unbind operation sets the 'connected' flag on false:
[1864]LDAPNetworkConnection: connected.set( false );
Therefore, the connection closes, and will be probably 4 min in TIME_WAIT.
A new one will be made by the next 'bind' operation.

The docs tells us this:
(http://directory.apache.org/api/user-guide/2.2-binding-unbinding.html)
"Once the user has finished interacting with the server, they can unbind, 
destroying the session held on the server. This operation does not close the 
connection, because, again bind != connection!"
However, this is not entirely true because a bit further down in the same 
documentation-page the docs tell:
" This is a trivial operation : you just send an UnbindRequest to the server, 
which will invalidate your session.
It's important to know that when you issue an Unbind, the connection is dropped"

Kind Regards,
Robin

-----Original Message-----
From: Berg, R. van den (Robin) [mailto:robin.van.den.b...@ing.nl.INVALID]
Sent: Friday, May 19, 2017 3:23 PM
To: api@directory.apache.org
Subject: LDAP API - Too much ldap connections with LdapConnectionPool

Hi!

I stumbled on a problem regarding connectionpooling.
What I would like to do is have a particular connectionpool that does NOT 
exceed, let's say 2 connections for this example.
If they are all occupied, I want to wait for a particular timeout before 
throwing an exception. 'whenExhaustedAction  
WHEN_EXHAUSTED_BLOCK<http://grepcode.com/file/repo1.maven.org/maven2/commons-pool/commons-pool/1.6/org/apache/commons/pool/impl/GenericObjectPool.java#GenericObjectPool.0WHEN_EXHAUSTED_BLOCK>'

The only thing I want to do with these connections is perform a 'bind' 
operation to check username/password.
I specifically do not want to close the connection to prevent this overhead.

I started off with the developer guide/introduction.
I noticed that I got a LOT of open connections on my machine, even though I set 
maxIdle = maxActive = 2.
I don't know if I did something wrong in configuring this, or if this is some 
kind of bug.
I made a piece of code that uses a pool to get a connection and do 20 
'bind'-operations in parallel (different threads) I ended up with 22 
connections that were open even after my jvm closed.
The weird thing, for every factory.getConnection() a connection has been made, 
but was not used!

Does somebody have a clue what I did wrong, or is this a bug?

Thanks in advance!
Kind Regards,
Robin
====code===
public class TestApacheLDAP {
    public static void main(String[] args) throws Exception {
        LdapConnectionConfig config = new LdapConnectionConfig();
        config.setLdapHost("secretldapserver");
        config.setLdapPort(389);

        DefaultLdapConnectionFactory factory = new 
DefaultLdapConnectionFactory(config);
        factory.setTimeOut(1000L);

        GenericObjectPool.Config poolConfig = new GenericObjectPool.Config();
        poolConfig.lifo = true;
        poolConfig.maxActive = 2;
        poolConfig.maxIdle = 2;
        poolConfig.maxWait = -1L;
        poolConfig.minEvictableIdleTimeMillis = 1000L * 2L;
        poolConfig.minIdle = 0;
        poolConfig.numTestsPerEvictionRun = 3;
        poolConfig.softMinEvictableIdleTimeMillis = -1L;
        poolConfig.testOnBorrow = false;
        poolConfig.testOnReturn = false;
        poolConfig.testWhileIdle = false;
        poolConfig.timeBetweenEvictionRunsMillis = -1L;
        poolConfig.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK;

        LdapConnectionPool pool = new LdapConnectionPool(
                new DefaultPoolableLdapConnectionFactory(factory), poolConfig);

        final ExecutorService executorService = Executors.newCachedThreadPool();

        final AtomicInteger failures = new AtomicInteger();
        final AtomicInteger success = new AtomicInteger();
        final List<String> connectionHashes = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            executorService.submit(() -> {
                try {
                    LdapConnection connection = pool.getConnection();
                    connection.unBind();
                    connection.bind("uid=xxxxxxx,ou=xxxx,o=xxxxx,c=xx", 
"mycorrectpassword");
                    if (connection.isAuthenticated()) {
                        success.getAndIncrement();
                    }
                    connectionHashes.add(String.valueOf(connection.hashCode()));
                    pool.releaseConnection(connection);
                } catch (LdapException e) {
                    failures.getAndIncrement();
                    e.printStackTrace();
                }
            });
        }

        Thread.sleep(10_000);

        System.out.println("=====================================");
        System.out.println(" failures: " + failures + " success: " + success);
        System.out.println(" used connections: " + connectionHashes);
        final Map<String, Long> count = 
connectionHashes.stream().collect(Collectors.groupingBy(e -> e, 
Collectors.counting()));
        count.forEach((s, aLong) -> System.out.println("connection " + s + ", 
times used:" + aLong));
        System.out.println("=====================================");

        System.exit(0);
    }
}
Output:
=====================================
failures: 0 success: 20
used connections: [509471061, 1713606446, 1713606446, 509471061, 1713606446, 
509471061, 1713606446, 509471061, 1713606446, 509471061, 1713606446, 509471061, 
1713606446, 1713606446, 509471061, 1713606446, 509471061, 1713606446, 
509471061, 1713606446] connection 509471061, times used: 9 connection 
1713606446, times used: 11 netstat -anp | grep ":389\|:636"
tcp6       0      0 10.0.2.15:46648         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46658         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46670         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46688         ipfromldap:389        ESTABLISHED 
15532/java
tcp6       0      0 10.0.2.15:46676         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46668         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46654         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46666         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46650         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46660         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46664         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46656         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46686         ipfromldap:389        ESTABLISHED 
15532/java
tcp6       0      0 10.0.2.15:46678         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46672         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46682         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46662         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46680         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46652         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46674         ipfromldap:389        TIME_WAIT   -
tcp6       0      0 10.0.2.15:46684         ipfromldap:389        TIME_WAIT   -

----------------------------------------------------------------
ATTENTION:
The information in this e-mail is confidential and only meant for the intended 
recipient. If you are not the intended recipient, don't use or disclose it in 
any way. Please let the sender know and delete the message immediately.
------------------------------------------------------------------------------------------------------

----------------------------------------------------------------
ATTENTION:
The information in this e-mail is confidential and only meant for the intended 
recipient. If you are not the intended recipient, don't use or disclose it in 
any way. Please let the sender know and delete the message immediately.
------------------------------------------------------------------------------------------------------

Reply via email to