Commit fa5cab35 authored by Brian Major's avatar Brian Major
Browse files

Merge branch 'ac2' of mach277:/home/majorb/git/opencadc into ac2

parents 3bb99c3f 9ac9ef83
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -9,12 +9,16 @@ readOnly.servers = proc5-03.cadc.dao.nrc.ca
readOnly.poolInitSize = 1
readOnly.poolMaxSize = 1
readOnly.poolPolicy = roundRobin
readOnly.maxWait = 30000
readOnly.createIfNeeded = false

# Read-write connection pool
readWrite.servers = proc5-03.cadc.dao.nrc.ca
readWrite.poolInitSize = 1
readWrite.poolMaxSize = 1
readWrite.poolPolicy = roundRobin
readWrite.maxWait = 30000
readWrite.createIfNeeded = false

# server configuration -- applies to all servers
dbrcHost = devLdap
+4 −0
Original line number Diff line number Diff line
@@ -10,12 +10,16 @@ readOnly.servers = <list of ldap servers for readonly access>
readOnly.poolInitSize = <number of initial connections in the readonly pool>
readOnly.poolMaxSize = <maximum number of connections in the readonly pool>
readOnly.poolPolicy = <roundRobin || fewestConnections>
readOnly.maxWait = <timeout wait time in milliseconds>
readOnly.createIfNeeded = <true || false> Go beyond poolMaxSize

# Read-write connection pool
readWrite.servers = <list of ldap servers for readwrite access>
readWrite.poolInitSize = <number of initial connections in the readwrite pool>
readWrite.poolMaxSize = <maximum number of connections in the readwrite pool>
readWrite.poolPolicy = <roundRobin || fewestConnections>
readWrite.maxWait = <timeout wait time in milliseconds>
readWrite.createIfNeeded = <true || false> Go beyond poolMaxSize

# server configuration -- applies to all servers
dbrcHost = <prodLdap || devLdap>
+22 −1
Original line number Diff line number Diff line
@@ -79,7 +79,6 @@ import ca.nrc.cadc.db.ConnectionConfig;
import ca.nrc.cadc.db.DBConfig;
import ca.nrc.cadc.util.MultiValuedProperties;
import ca.nrc.cadc.util.PropertiesReader;
import ca.nrc.cadc.util.StringUtil;

/**
 * Reads and stores the LDAP configuration information. The information
@@ -99,6 +98,8 @@ public class LdapConfig
    public static final String POOL_INIT_SIZE = "poolInitSize";
    public static final String POOL_MAX_SIZE = "poolMaxSize";
    public static final String POOL_POLICY = "poolPolicy";
    public static final String MAX_WAIT = "maxWait";
    public static final String CREATE_IF_NEEDED = "createIfNeeded";

    public static final String LDAP_DBRC_ENTRY = "dbrcHost";
    public static final String LDAP_PORT = "port";
@@ -122,6 +123,8 @@ public class LdapConfig
        private int initSize;
        private int maxSize;
        private PoolPolicy policy;
        private long maxWait;
        private boolean createIfNeeded;

        public List<String> getServers()
        {
@@ -139,6 +142,14 @@ public class LdapConfig
        {
            return policy;
        }
        public long getMaxWait()
        {
            return maxWait;
        }
        public boolean getCreateIfNeeded()
        {
            return createIfNeeded;
        }

        @Override
        public boolean equals(Object other)
@@ -160,6 +171,12 @@ public class LdapConfig
            if ( !(l.policy.equals(policy)))
                return false;

            if ( !(l.maxWait == maxWait))
                return false;

            if ( !(l.createIfNeeded == createIfNeeded))
                return false;

            return true;
        }
    };
@@ -208,11 +225,15 @@ public class LdapConfig
        ldapConfig.readOnlyPool.initSize = Integer.valueOf(getProperty(pr, READONLY_PREFIX + POOL_INIT_SIZE));
        ldapConfig.readOnlyPool.maxSize = Integer.valueOf(getProperty(pr, READONLY_PREFIX + POOL_MAX_SIZE));
        ldapConfig.readOnlyPool.policy = PoolPolicy.valueOf(getProperty(pr, READONLY_PREFIX + POOL_POLICY));
        ldapConfig.readOnlyPool.maxWait = Long.valueOf(getProperty(pr, READONLY_PREFIX + MAX_WAIT));
        ldapConfig.readOnlyPool.createIfNeeded = Boolean.valueOf(getProperty(pr, READONLY_PREFIX + CREATE_IF_NEEDED));

        ldapConfig.readWritePool.servers = getMultiProperty(pr, READWRITE_PREFIX + POOL_SERVERS);
        ldapConfig.readWritePool.initSize = Integer.valueOf(getProperty(pr, READWRITE_PREFIX + POOL_INIT_SIZE));
        ldapConfig.readWritePool.maxSize = Integer.valueOf(getProperty(pr, READWRITE_PREFIX + POOL_MAX_SIZE));
        ldapConfig.readWritePool.policy = PoolPolicy.valueOf(getProperty(pr, READWRITE_PREFIX + POOL_POLICY));
        ldapConfig.readWritePool.maxWait = Long.valueOf(getProperty(pr, READONLY_PREFIX + MAX_WAIT));
        ldapConfig.readWritePool.createIfNeeded = Boolean.valueOf(getProperty(pr, READONLY_PREFIX + CREATE_IF_NEEDED));

        ldapConfig.dbrcHost = getProperty(pr, LDAP_DBRC_ENTRY);
        ldapConfig.port = Integer.valueOf(getProperty(pr, LDAP_PORT));
+66 −35
Original line number Diff line number Diff line
@@ -73,10 +73,12 @@ import org.apache.log4j.Logger;

import ca.nrc.cadc.ac.server.ldap.LdapConfig.LdapPool;
import ca.nrc.cadc.ac.server.ldap.LdapConfig.PoolPolicy;
import ca.nrc.cadc.net.TransientException;
import ca.nrc.cadc.profiler.Profiler;

import com.unboundid.ldap.sdk.FewestConnectionsServerSet;
import com.unboundid.ldap.sdk.LDAPConnection;
import com.unboundid.ldap.sdk.LDAPConnectionOptions;
import com.unboundid.ldap.sdk.LDAPConnectionPool;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.LDAPReadWriteConnectionPool;
@@ -102,59 +104,76 @@ public class LdapConnectionPool
    protected LdapConfig currentConfig;
    private LDAPReadWriteConnectionPool pool;
    private Object poolMonitor = new Object();
    private LDAPConnectionOptions connectionOptions;

    private long lastPoolCheck = System.currentTimeMillis();

    LdapConnectionPool()
    {
        this.currentConfig = LdapConfig.getLdapConfig();
        pool = createPool(currentConfig);
        profiler.checkpoint("Create pool");
        this(LdapConfig.getLdapConfig());
    }

    LdapConnectionPool(LdapConfig config)
    {
        connectionOptions = new LDAPConnectionOptions();
        connectionOptions.setUseSynchronousMode(true);
        connectionOptions.setAutoReconnect(true);
        this.currentConfig = config;
        pool = createPool(currentConfig);
        profiler.checkpoint("Create pool");
    }

    protected LDAPConnection getReadOnlyConnection() throws LDAPException
    protected LDAPConnection getReadOnlyConnection() throws TransientException
    {
        synchronized (poolMonitor)
        {
            poolCheck();
            try
            {
                LDAPConnection conn = pool.getReadConnection();
                logger.debug("Read pool statistics after borrow:\n" + pool.getReadPoolStatistics());
                profiler.checkpoint("get read only connection");
                conn.setConnectionOptions(connectionOptions);

                return conn;
            }
            catch (LDAPException e)
            {
                throw new TransientException("Failed to get read only connection", e);
            }
        }
    }

    protected LDAPConnection getReadWriteConnection() throws LDAPException
    protected LDAPConnection getReadWriteConnection() throws TransientException
    {
        synchronized (poolMonitor)
        {
            poolCheck();
            try
            {
                LDAPConnection conn = pool.getWriteConnection();
                logger.debug("write pool statistics after borrow:\n" + pool.getWritePoolStatistics());
                profiler.checkpoint("get read write connection");

                return conn;
            }
            catch (LDAPException e)
            {
                throw new TransientException("Failed to get read write connection", e);
            }
        }
    }

    protected void releaseReadOnlyConnection(LDAPConnection conn)
    {
        synchronized (poolMonitor)
    {
        pool.releaseReadConnection(conn);
        }
        logger.debug("Read pool statistics after release:\n" + pool.getReadPoolStatistics());
    }

    protected void releaseReadWriteConnection(LDAPConnection conn)
    {
        synchronized (poolMonitor)
    {
        pool.releaseWriteConnection(conn);
        }
        logger.debug("write pool statistics after release:\n" + pool.getWritePoolStatistics());
    }

    protected LdapConfig getCurrentConfig()
@@ -170,10 +189,6 @@ public class LdapConnectionPool
    }

    private void poolCheck()
    {
        if (timeToCheckPool())
        {
            synchronized (poolMonitor)
    {
        if (timeToCheckPool())
        {
@@ -185,15 +200,25 @@ public class LdapConnectionPool
                logger.debug("Detected ldap configuration change, rebuilding pools");
                this.currentConfig = newConfig;

                        pool.close();
                        profiler.checkpoint("Close old pool");
                final LDAPReadWriteConnectionPool oldPool = pool;

                pool = createPool(currentConfig);
                profiler.checkpoint("Rebuild pool");

                // close the old pool in a separate thread
                Runnable closeOldPool = new Runnable()
                {
                    public void run()
                    {
                        logger.debug("Closing old pool...");
                        oldPool.close();
                        logger.debug("Old pool closed.");
                    }
                    lastPoolCheck = System.currentTimeMillis();
                }
                };
                Thread closePoolThread = new Thread(closeOldPool);
                closePoolThread.start();
            }
            lastPoolCheck = System.currentTimeMillis();
        }
    }

@@ -207,6 +232,8 @@ public class LdapConnectionPool
        LDAPConnectionPool ro = createPool(config.getReadOnlyPool(), config);
        LDAPConnectionPool rw = createPool(config.getReadOnlyPool(), config);
        LDAPReadWriteConnectionPool pool = new LDAPReadWriteConnectionPool(ro, rw);
        logger.debug("Read pool statistics after create:\n" + pool.getReadPoolStatistics());
        logger.debug("Write pool statistics after create:\n" + pool.getWritePoolStatistics());
        return pool;
    }

@@ -240,6 +267,9 @@ public class LdapConnectionPool
            LDAPConnectionPool connectionPool = new LDAPConnectionPool(
                serverSet, bindRequest, pool.getInitSize(), pool.getMaxSize());

            connectionPool.setCreateIfNecessary(pool.getCreateIfNeeded());
            connectionPool.setMaxWaitTimeMillis(pool.getMaxWait());

            return connectionPool;
        }
        catch (Exception e)
@@ -249,4 +279,5 @@ public class LdapConnectionPool
        }
    }


}
+59 −8
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ package ca.nrc.cadc.ac.server.ldap;

import org.apache.log4j.Logger;

import ca.nrc.cadc.net.TransientException;
import ca.nrc.cadc.profiler.Profiler;

import com.unboundid.ldap.sdk.LDAPConnection;
@@ -117,48 +118,64 @@ class LdapConnections
        this.pool = pool;
    }

    LDAPConnection getReadOnlyConnection() throws LDAPException
    LDAPConnection getReadOnlyConnection() throws TransientException
    {
        if (persistence != null)
        {
            log.debug("Obtaining auto config read only connection.");
            if (autoConfigReadOnlyConn == null)
            {
                log.debug("Getting new auto config read only connection.");
                autoConfigReadOnlyConn = persistence.getReadOnlyConnection();
                profiler.checkpoint("Get read only connection");
            }
            else
            {
                log.debug("Getting reused auto config read only connection.");
            }
            return autoConfigReadOnlyConn;
        }
        else
        {
            log.debug("Obtaining manual config read only connection.");
            if (manualConfigReadOnlyConn == null)
            {
                log.debug("Getting new manual config read only connection.");
                manualConfigReadOnlyConn = pool.getReadOnlyConnection();
            }
            else
            {
                log.debug("Getting reused manual config read only connection.");
            }
            return manualConfigReadOnlyConn;
        }
    }

    LDAPConnection getReadWriteConnection() throws LDAPException
    LDAPConnection getReadWriteConnection() throws TransientException
    {
        if (persistence != null)
        {
            log.debug("Obtaining auto config read write connection.");
            if (autoConfigReadWriteConn == null)
            {
                log.debug("Getting new auto config read write connection.");
                autoConfigReadWriteConn = persistence.getReadWriteConnection();
                profiler.checkpoint("Get read write connection");
            }
            else
            {
                log.debug("Getting reused auto config read write connection.");
            }
            return autoConfigReadWriteConn;
        }
        else
        {
            log.debug("Obtaining manual config read write connection.");
            if (manualConfigReadWriteConn == null)
            {
                log.debug("Getting new manual config read write connection.");
                manualConfigReadWriteConn = pool.getReadWriteConnection();
            }
            else
            {
                log.debug("Getting reused manual config read write connection.");
            }
            return manualConfigReadWriteConn;
        }
    }
@@ -167,27 +184,61 @@ class LdapConnections
    {
        if (persistence != null)
        {
            log.debug("Releasing auto config connections.");
            if (autoConfigReadOnlyConn != null)
            {
                log.debug("Releasing read only auto config connection.");
                persistence.releaseReadOnlyConnection(autoConfigReadOnlyConn);
                profiler.checkpoint("Release read only connection");
            }
            if (autoConfigReadWriteConn != null)
            {
                log.debug("Releasing read write auto config connection.");
                persistence.releaseReadWriteConnection(autoConfigReadWriteConn);
                profiler.checkpoint("Release read write connection");
            }
        }
        else
        {
            if (manualConfigReadOnlyConn != null)
            {
                log.debug("Releasing read only manual config connection.");
                pool.releaseReadOnlyConnection(manualConfigReadOnlyConn);
            }
            if (manualConfigReadWriteConn != null)
            {
                log.debug("Releasing read write manual config connection.");
                pool.releaseReadWriteConnection(manualConfigReadWriteConn);
            }
        }
    }

    void releaseConnectionsAfterError()
    {
        if (persistence != null)
        {
            if (autoConfigReadOnlyConn != null)
            {
                log.debug("Releasing read only auto config connection.");
                persistence.releaseReadOnlyConnection(autoConfigReadOnlyConn);
                profiler.checkpoint("Release read only connection");
            }
            if (autoConfigReadWriteConn != null)
            {
                log.debug("Releasing read write auto config connection.");
                persistence.releaseReadWriteConnection(autoConfigReadWriteConn);
                profiler.checkpoint("Release read write connection");
            }
        }
        else
        {
            log.debug("Releasing manual config connections.");
            if (manualConfigReadOnlyConn != null)
            {
                log.debug("Releasing read only manual config connection.");
                pool.releaseReadOnlyConnection(manualConfigReadOnlyConn);
            }
            if (manualConfigReadWriteConn != null)
            {
                log.debug("Releasing read write manual config connection.");
                pool.releaseReadWriteConnection(manualConfigReadWriteConn);
            }
        }
Loading