Commit 94e68b6b authored by Brian Major's avatar Brian Major
Browse files

s1890 - Allowed for the AC web service to be in READONLY and OFFLINE modes

parent 09fc6d35
Loading
Loading
Loading
Loading
+86 −14
Original line number Original line Diff line number Diff line
@@ -100,6 +100,13 @@ public class LdapConnectionPool
{
{
    private static final Logger logger = Logger.getLogger(LdapConnectionPool.class);
    private static final Logger logger = Logger.getLogger(LdapConnectionPool.class);


    private enum SystemState
    {
        ONLINE,
        READONLY,
        OFFLINE
    };

    Profiler profiler = new Profiler(LdapConnectionPool.class);
    Profiler profiler = new Profiler(LdapConnectionPool.class);


    protected LdapConfig currentConfig;
    protected LdapConfig currentConfig;
@@ -107,8 +114,10 @@ public class LdapConnectionPool
    private LDAPConnectionPool pool;
    private LDAPConnectionPool pool;
    private Object poolMonitor = new Object();
    private Object poolMonitor = new Object();
    private LDAPConnectionOptions connectionOptions;
    private LDAPConnectionOptions connectionOptions;
    private boolean readOnly;
    SystemState systemState = SystemState.ONLINE;


    public LdapConnectionPool(LdapConfig config, LdapPool poolConfig, String poolName, boolean boundPool)
    public LdapConnectionPool(LdapConfig config, LdapPool poolConfig, String poolName, boolean boundPool, boolean readOnly)
    {
    {
        if (config == null)
        if (config == null)
            throw new IllegalArgumentException("config required");
            throw new IllegalArgumentException("config required");
@@ -122,19 +131,49 @@ public class LdapConnectionPool
        connectionOptions.setAutoReconnect(true);
        connectionOptions.setAutoReconnect(true);
        currentConfig = config;
        currentConfig = config;
        this.poolName = poolName;
        this.poolName = poolName;
        this.readOnly = readOnly;

        systemState = getSystemState(config);
        logger.debug("Construct pool: " + poolName + ". system state: " + systemState);
        if (SystemState.ONLINE.equals(systemState) || (SystemState.READONLY.equals(systemState) && readOnly))
        {
            synchronized (poolMonitor)
            synchronized (poolMonitor)
            {
            {
                if (!boundPool)
                if (!boundPool)
                    pool = createPool(config, poolConfig, poolName, null, null);
                    pool = createPool(config, poolConfig, poolName, null, null);
                else
                else
                    pool = createPool(config, poolConfig, poolName, config.getAdminUserDN(), config.getAdminPasswd());
                    pool = createPool(config, poolConfig, poolName, config.getAdminUserDN(), config.getAdminPasswd());

                if (pool != null)
                {
                    logger.debug(poolName + " statistics after create:\n" + pool.getConnectionPoolStatistics());
                    logger.debug(poolName + " statistics after create:\n" + pool.getConnectionPoolStatistics());
                    profiler.checkpoint("Create read only pool.");
                    profiler.checkpoint("Create read only pool.");
                }
                }
            }
            }
        }
        else
        {
            logger.debug("Not creating pool " + poolName + " because system state is " + systemState);
        }
    }


    public LDAPConnection getConnection() throws TransientException
    public LDAPConnection getConnection() throws TransientException
    {
    {

        logger.debug("Get connection: " + poolName + ". system state: " + systemState);
        if (SystemState.OFFLINE.equals(systemState))
        {
            throw new TransientException("The system is down for maintenance.", 600);
        }

        if (SystemState.READONLY.equals(systemState))
        {
            if (!readOnly)
            {
                throw new TransientException("The system is in read-only mode.", 600);
            }
        }

        try
        try
        {
        {
            LDAPConnection conn = null;
            LDAPConnection conn = null;
@@ -168,10 +207,13 @@ public class LdapConnectionPool
    }
    }


    public void releaseConnection(LDAPConnection conn)
    public void releaseConnection(LDAPConnection conn)
    {
        if (pool != null)
        {
        {
            pool.releaseConnection(conn);
            pool.releaseConnection(conn);
            logger.debug(poolName + " pool statistics after release:\n" + pool.getConnectionPoolStatistics());
            logger.debug(poolName + " pool statistics after release:\n" + pool.getConnectionPoolStatistics());
        }
        }
    }


    public LdapConfig getCurrentConfig()
    public LdapConfig getCurrentConfig()
    {
    {
@@ -179,11 +221,14 @@ public class LdapConnectionPool
    }
    }


    public void shutdown()
    public void shutdown()
    {
        if (pool != null)
        {
        {
            logger.debug("Closing pool...");
            logger.debug("Closing pool...");
            pool.close();
            pool.close();
            profiler.checkpoint("Pool closed.");
            profiler.checkpoint("Pool closed.");
        }
        }
    }


    public String getName()
    public String getName()
    {
    {
@@ -191,7 +236,6 @@ public class LdapConnectionPool
    }
    }


    private LDAPConnectionPool createPool(LdapConfig config, LdapPool poolConfig, String poolName, String bindID, String bindPW)
    private LDAPConnectionPool createPool(LdapConfig config, LdapPool poolConfig, String poolName, String bindID, String bindPW)

    {
    {
        try
        try
        {
        {
@@ -245,4 +289,32 @@ public class LdapConnectionPool
    }
    }




    /**
     * Check if in read-only or offline mode.
     *
     * A read max connection size of zero implies offline mode.
     * A read-wrtie max connection size of zero implies read-only mode.
     */
    private SystemState getSystemState(LdapConfig config)
    {

        if (config.getReadOnlyPool().getMaxSize() == 0)
        {
            return SystemState.OFFLINE;
        }

        if (config.getUnboundReadOnlyPool().getMaxSize() == 0)
        {
            return SystemState.OFFLINE;
        }

        if (config.getReadWritePool().getMaxSize() == 0)
        {
            return SystemState.READONLY;
        }

        return SystemState.ONLINE;
    }


}
}
+4 −3
Original line number Original line Diff line number Diff line
@@ -147,7 +147,7 @@ class LdapConnections
        {
        {
            if (readOnlyPool == null)
            if (readOnlyPool == null)
            {
            {
                readOnlyPool = new LdapConnectionPool(config, config.getReadOnlyPool(), LdapPersistence.POOL_READONLY, true);
                readOnlyPool = new LdapConnectionPool(config, config.getReadOnlyPool(), LdapPersistence.POOL_READONLY, true, true);
            }
            }
            if (manualConfigReadOnlyConn == null)
            if (manualConfigReadOnlyConn == null)
            {
            {
@@ -186,7 +186,7 @@ class LdapConnections
        {
        {
            if (readWritePool == null)
            if (readWritePool == null)
            {
            {
                readWritePool = new LdapConnectionPool(config, config.getReadWritePool(), LdapPersistence.POOL_READWRITE, true);
                readWritePool = new LdapConnectionPool(config, config.getReadWritePool(), LdapPersistence.POOL_READWRITE, true, false);
            }
            }
            if (manualConfigReadWriteConn == null)
            if (manualConfigReadWriteConn == null)
            {
            {
@@ -225,7 +225,7 @@ class LdapConnections
        {
        {
            if (unboundReadOnlyPool == null)
            if (unboundReadOnlyPool == null)
            {
            {
                unboundReadOnlyPool = new LdapConnectionPool(config, config.getUnboundReadOnlyPool(), LdapPersistence.POOL_UNBOUNDREADONLY, false);
                unboundReadOnlyPool = new LdapConnectionPool(config, config.getUnboundReadOnlyPool(), LdapPersistence.POOL_UNBOUNDREADONLY, false, true);
            }
            }
            if (manualConfigUnboundReadOnlyConn == null)
            if (manualConfigUnboundReadOnlyConn == null)
            {
            {
@@ -317,4 +317,5 @@ class LdapConnections
            return config;
            return config;
    }
    }



}
}
+25 −24
Original line number Original line Diff line number Diff line
@@ -70,7 +70,13 @@ package ca.nrc.cadc.ac.server.ldap;


import java.security.AccessControlException;
import java.security.AccessControlException;
import java.security.Principal;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.security.auth.Subject;


import org.apache.log4j.Logger;
import org.apache.log4j.Logger;


@@ -87,11 +93,6 @@ import ca.nrc.cadc.auth.AuthMethod;
import ca.nrc.cadc.auth.AuthenticationUtil;
import ca.nrc.cadc.auth.AuthenticationUtil;
import ca.nrc.cadc.auth.DNPrincipal;
import ca.nrc.cadc.auth.DNPrincipal;
import ca.nrc.cadc.net.TransientException;
import ca.nrc.cadc.net.TransientException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.security.auth.Subject;


public class LdapGroupPersistence<T extends Principal> extends LdapPersistence implements GroupPersistence<T>
public class LdapGroupPersistence<T extends Principal> extends LdapPersistence implements GroupPersistence<T>
{
{
+11 −6
Original line number Original line Diff line number Diff line
@@ -115,7 +115,7 @@ public abstract class LdapPersistence
            ConnectionPools pools = lookupPools();
            ConnectionPools pools = lookupPools();
            if (pools == null || pools.isClosed())
            if (pools == null || pools.isClosed())
                throw new IllegalStateException("Pools are closed.");
                throw new IllegalStateException("Pools are closed.");
            poolCheck(pools);
            pools = poolCheck(pools);
            return pools.getPools().get(poolName);
            return pools.getPools().get(poolName);
        }
        }
        catch (NamingException e)
        catch (NamingException e)
@@ -240,11 +240,11 @@ public abstract class LdapPersistence
    {
    {
        Map<String,LdapConnectionPool> poolMap = new HashMap<String,LdapConnectionPool>(3);
        Map<String,LdapConnectionPool> poolMap = new HashMap<String,LdapConnectionPool>(3);
        poolMap.put(POOL_READONLY, new LdapConnectionPool(
        poolMap.put(POOL_READONLY, new LdapConnectionPool(
            config, config.getReadOnlyPool(), POOL_READONLY, true));
            config, config.getReadOnlyPool(), POOL_READONLY, true, true));
        poolMap.put(POOL_READWRITE, new LdapConnectionPool(
        poolMap.put(POOL_READWRITE, new LdapConnectionPool(
            config, config.getReadWritePool(), POOL_READWRITE, true));
            config, config.getReadWritePool(), POOL_READWRITE, true, false));
        poolMap.put(POOL_UNBOUNDREADONLY, new LdapConnectionPool(
        poolMap.put(POOL_UNBOUNDREADONLY, new LdapConnectionPool(
            config, config.getUnboundReadOnlyPool(), POOL_UNBOUNDREADONLY, false));
            config, config.getUnboundReadOnlyPool(), POOL_UNBOUNDREADONLY, false, true));
        profiler.checkpoint("Created 3 LDAP connection pools");
        profiler.checkpoint("Created 3 LDAP connection pools");
        return new ConnectionPools(poolMap, config);
        return new ConnectionPools(poolMap, config);
    }
    }
@@ -262,7 +262,7 @@ public abstract class LdapPersistence
        }
        }
    }
    }


    private void poolCheck(ConnectionPools pools) throws TransientException
    private ConnectionPools poolCheck(ConnectionPools pools) throws TransientException
    {
    {
        if (timeToCheckPools(pools))
        if (timeToCheckPools(pools))
        {
        {
@@ -278,6 +278,7 @@ public abstract class LdapPersistence
                logger.debug("Detected ldap configuration change, rebuilding pools");
                logger.debug("Detected ldap configuration change, rebuilding pools");
                boolean poolRecreated = false;
                boolean poolRecreated = false;
                final ConnectionPools oldPools = pools;
                final ConnectionPools oldPools = pools;
                ConnectionPools newPools = null;


                synchronized (jndiMonitor)
                synchronized (jndiMonitor)
                {
                {
@@ -287,7 +288,7 @@ public abstract class LdapPersistence
                    {
                    {
                        try
                        try
                        {
                        {
                            ConnectionPools newPools = createPools(newConfig);
                            newPools = createPools(newConfig);
                            newPools.setLastPoolCheck(System.currentTimeMillis());
                            newPools.setLastPoolCheck(System.currentTimeMillis());
                            InitialContext ic = new InitialContext();
                            InitialContext ic = new InitialContext();
                            try
                            try
@@ -326,9 +327,13 @@ public abstract class LdapPersistence
                    };
                    };
                    Thread closePoolsThread = new Thread(closeOldPools);
                    Thread closePoolsThread = new Thread(closeOldPools);
                    closePoolsThread.start();
                    closePoolsThread.start();

                    return newPools;
                }
                }
            }
            }
        }
        }
        // just return the existing pools
        return pools;
    }
    }


    private boolean timeToCheckPools(ConnectionPools pools)
    private boolean timeToCheckPools(ConnectionPools pools)
+15 −15
Original line number Original line Diff line number Diff line
@@ -72,6 +72,8 @@ import java.security.AccessControlException;
import java.security.Principal;
import java.security.Principal;
import java.util.Collection;
import java.util.Collection;


import javax.security.auth.Subject;

import org.apache.log4j.Logger;
import org.apache.log4j.Logger;


import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.User;
@@ -85,8 +87,6 @@ import ca.nrc.cadc.auth.HttpPrincipal;
import ca.nrc.cadc.net.TransientException;
import ca.nrc.cadc.net.TransientException;
import ca.nrc.cadc.profiler.Profiler;
import ca.nrc.cadc.profiler.Profiler;


import javax.security.auth.Subject;

public class LdapUserPersistence<T extends Principal> extends LdapPersistence implements UserPersistence<T>
public class LdapUserPersistence<T extends Principal> extends LdapPersistence implements UserPersistence<T>
{
{
    private static final Logger logger = Logger.getLogger(LdapUserPersistence.class);
    private static final Logger logger = Logger.getLogger(LdapUserPersistence.class);
Loading