PerUserPoolDataSource.java
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.commons.dbcp2.datasources;
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.sql.Connection;
- import java.sql.SQLException;
- import java.time.Duration;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.NoSuchElementException;
- import java.util.function.Supplier;
- import javax.naming.NamingException;
- import javax.naming.Reference;
- import javax.naming.StringRefAddr;
- import javax.sql.ConnectionPoolDataSource;
- import org.apache.commons.dbcp2.SwallowedExceptionLogger;
- import org.apache.commons.dbcp2.Utils;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.apache.commons.pool2.ObjectPool;
- import org.apache.commons.pool2.impl.EvictionPolicy;
- import org.apache.commons.pool2.impl.GenericObjectPool;
- /**
- * <p>
- * A pooling {@code DataSource} appropriate for deployment within J2EE environment. There are many configuration
- * options, most of which are defined in the parent class. This datasource uses individual pools per user, and some
- * properties can be set specifically for a given user, if the deployment environment can support initialization of
- * mapped properties. So for example, a pool of admin or write-access Connections can be guaranteed a certain number of
- * connections, separate from a maximum set for users with read-only connections.
- * </p>
- *
- * <p>
- * User passwords can be changed without re-initializing the datasource. When a
- * {@code getConnection(userName, password)} request is processed with a password that is different from those used
- * to create connections in the pool associated with {@code userName}, an attempt is made to create a new
- * connection using the supplied password and if this succeeds, the existing pool is cleared and a new pool is created
- * for connections using the new password.
- * </p>
- *
- * @since 2.0
- */
- public class PerUserPoolDataSource extends InstanceKeyDataSource {
- private static final long serialVersionUID = 7872747993848065028L;
- private static final Log log = LogFactory.getLog(PerUserPoolDataSource.class);
- private static <K, V> HashMap<K, V> createMap() {
- // Should there be a default size different from what this ctor provides?
- return new HashMap<>();
- }
- /**
- * Maps user names to a data source property: BlockWhenExhausted.
- */
- private Map<String, Boolean> perUserBlockWhenExhausted;
- /**
- * Maps user names to a data source property: EvictionPolicyClassName.
- */
- private Map<String, String> perUserEvictionPolicyClassName;
- /**
- * Maps user names to a data source property: Lifo.
- */
- private Map<String, Boolean> perUserLifo;
- /**
- * Maps user names to a data source property: MaxIdle.
- */
- private Map<String, Integer> perUserMaxIdle;
- /**
- * Maps user names to a data source property: MaxTotal.
- */
- private Map<String, Integer> perUserMaxTotal;
- /**
- * Maps user names to a data source property: MaxWaitDuration.
- */
- private Map<String, Duration> perUserMaxWaitDuration;
- /**
- * Maps user names to a data source property: MinEvictableIdleDuration.
- */
- private Map<String, Duration> perUserMinEvictableIdleDuration;
- /**
- * Maps user names to a data source property: MinIdle.
- */
- private Map<String, Integer> perUserMinIdle;
- /**
- * Maps user names to a data source property: NumTestsPerEvictionRun.
- */
- private Map<String, Integer> perUserNumTestsPerEvictionRun;
- /**
- * Maps user names to a data source property: SoftMinEvictableIdleDuration.
- */
- private Map<String, Duration> perUserSoftMinEvictableIdleDuration;
- /**
- * Maps user names to a data source property: TestOnCreate.
- */
- private Map<String, Boolean> perUserTestOnCreate;
- /**
- * Maps user names to a data source property: TestOnBorrow.
- */
- private Map<String, Boolean> perUserTestOnBorrow;
- /**
- * Maps user names to a data source property: TestOnReturn.
- */
- private Map<String, Boolean> perUserTestOnReturn;
- /**
- * Maps user names to a data source property: TestWhileIdle.
- */
- private Map<String, Boolean> perUserTestWhileIdle;
- /**
- * Maps user names to a data source property: DurationBetweenEvictionRuns.
- */
- private Map<String, Duration> perUserDurationBetweenEvictionRuns;
- /**
- * Maps user names to a data source property: DefaultAutoCommit.
- */
- private Map<String, Boolean> perUserDefaultAutoCommit;
- /**
- * Maps user names to a data source property: DefaultTransactionIsolation.
- */
- private Map<String, Integer> perUserDefaultTransactionIsolation;
- /**
- * Maps user names to a data source property: DefaultReadOnly.
- */
- private Map<String, Boolean> perUserDefaultReadOnly;
- /**
- * Map to keep track of Pools for a given user.
- */
- private transient Map<PoolKey, PooledConnectionManager> managers = createMap();
- /**
- * Constructs a new instance.
- */
- public PerUserPoolDataSource() {
- }
- /**
- * Clears pool(s) maintained by this data source.
- *
- * @see org.apache.commons.pool2.ObjectPool#clear()
- * @since 2.3.0
- */
- @SuppressWarnings("resource") // does not allocate a pool
- public void clear() {
- managers.values().forEach(manager -> {
- try {
- getCPDSConnectionFactoryPool(manager).clear();
- } catch (final Exception ignored) {
- // ignore and try to close others.
- }
- });
- InstanceKeyDataSourceFactory.removeInstance(getInstanceKey());
- }
- /**
- * Closes pool(s) maintained by this data source.
- *
- * @see org.apache.commons.pool2.ObjectPool#close()
- */
- @Override
- public void close() {
- managers.values().forEach(manager -> Utils.closeQuietly(getCPDSConnectionFactoryPool(manager)));
- InstanceKeyDataSourceFactory.removeInstance(getInstanceKey());
- }
- /**
- * Converts a map with Long milliseconds values to another map with Duration values.
- */
- private Map<String, Duration> convertMap(final Map<String, Duration> currentMap, final Map<String, Long> longMap) {
- final Map<String, Duration> durationMap = createMap();
- longMap.forEach((k, v) -> durationMap.put(k, toDurationOrNull(v)));
- if (currentMap == null) {
- return durationMap;
- }
- currentMap.clear();
- currentMap.putAll(durationMap);
- return currentMap;
- }
- /**
- * Gets the user specific default value in a map for the specified user's pool.
- *
- * @param userName The user name key.
- * @return The user specific value.
- */
- private <V> V get(final Map<String, V> map, final String userName) {
- return map != null ? map.get(userName) : null;
- }
- /**
- * Gets the user specific default value in a map for the specified user's pool.
- *
- * @param userName The user name key.
- * @return The user specific value.
- */
- private <V> V get(final Map<String, V> map, final String userName, final Supplier<V> defaultSupplier) {
- final V v = get(map, userName);
- return v != null ? v : defaultSupplier.get();
- }
- @Override
- protected PooledConnectionManager getConnectionManager(final UserPassKey upKey) {
- return managers.get(getPoolKey(upKey.getUserName()));
- }
- /**
- * Gets the underlying pre-allocated pool (does NOT allocate).
- *
- * @param manager A CPDSConnectionFactory.
- * @return the underlying pool.
- */
- private ObjectPool<PooledConnectionAndInfo> getCPDSConnectionFactoryPool(final PooledConnectionManager manager) {
- return ((CPDSConnectionFactory) manager).getPool();
- }
- /**
- * Gets the number of active connections in the default pool.
- *
- * @return The number of active connections in the default pool.
- */
- public int getNumActive() {
- return getNumActive(null);
- }
- /**
- * Gets the number of active connections in the pool for a given user.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- @SuppressWarnings("resource")
- public int getNumActive(final String userName) {
- final ObjectPool<PooledConnectionAndInfo> pool = getPool(getPoolKey(userName));
- return pool == null ? 0 : pool.getNumActive();
- }
- /**
- * Gets the number of idle connections in the default pool.
- *
- * @return The number of idle connections in the default pool.
- */
- public int getNumIdle() {
- return getNumIdle(null);
- }
- /**
- * Gets the number of idle connections in the pool for a given user.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- @SuppressWarnings("resource")
- public int getNumIdle(final String userName) {
- final ObjectPool<PooledConnectionAndInfo> pool = getPool(getPoolKey(userName));
- return pool == null ? 0 : pool.getNumIdle();
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getBlockWhenExhausted()} for the specified user's pool
- * or the default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- public boolean getPerUserBlockWhenExhausted(final String userName) {
- return get(perUserBlockWhenExhausted, userName, this::getDefaultBlockWhenExhausted);
- }
- /**
- * Gets the user specific default value for {@link Connection#setAutoCommit(boolean)} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- public Boolean getPerUserDefaultAutoCommit(final String userName) {
- return get(perUserDefaultAutoCommit, userName);
- }
- /**
- * Gets the user specific default value for {@link Connection#setReadOnly(boolean)} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- public Boolean getPerUserDefaultReadOnly(final String userName) {
- return get(perUserDefaultReadOnly, userName);
- }
- /**
- * Gets the user specific default value for {@link Connection#setTransactionIsolation(int)} for the specified user's
- * pool.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- public Integer getPerUserDefaultTransactionIsolation(final String userName) {
- return get(perUserDefaultTransactionIsolation, userName);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getDurationBetweenEvictionRuns()} for the specified
- * user's pool or the default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- * @since 2.10.0
- */
- public Duration getPerUserDurationBetweenEvictionRuns(final String userName) {
- return get(perUserDurationBetweenEvictionRuns, userName, this::getDefaultDurationBetweenEvictionRuns);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getEvictionPolicyClassName()} for the specified user's
- * pool or the default if no user specific value is defined.
- * <p>
- * The class must implement {@link EvictionPolicy}.
- * </p>
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- public String getPerUserEvictionPolicyClassName(final String userName) {
- return get(perUserEvictionPolicyClassName, userName, this::getDefaultEvictionPolicyClassName);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getLifo()} for the specified user's pool or the default
- * if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- public boolean getPerUserLifo(final String userName) {
- return get(perUserLifo, userName, this::getDefaultLifo);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getMaxIdle()} for the specified user's pool or the
- * default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- public int getPerUserMaxIdle(final String userName) {
- return get(perUserMaxIdle, userName, this::getDefaultMaxIdle);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getMaxTotal()} for the specified user's pool or the
- * default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- public int getPerUserMaxTotal(final String userName) {
- return get(perUserMaxTotal, userName, this::getDefaultMaxTotal);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getMaxWaitDuration()} for the specified user's pool or
- * the default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- * @since 2.10.0
- */
- public Duration getPerUserMaxWaitDuration(final String userName) {
- return get(perUserMaxWaitDuration, userName, this::getDefaultMaxWait);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getMaxWaitDuration()} for the specified user's pool or
- * the default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- * @deprecated Use {@link #getPerUserMaxWaitDuration}.
- */
- @Deprecated
- public long getPerUserMaxWaitMillis(final String userName) {
- return getPerUserMaxWaitDuration(userName).toMillis();
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getMinEvictableIdleDuration()} for the specified
- * user's pool or the default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value, never null.
- * @since 2.10.0
- */
- public Duration getPerUserMinEvictableIdleDuration(final String userName) {
- return get(perUserMinEvictableIdleDuration, userName, this::getDefaultMinEvictableIdleDuration);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getMinEvictableIdleDuration()} for the specified
- * user's pool or the default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- * @deprecated Use {@link #getPerUserMinEvictableIdleDuration(String)}.
- */
- @Deprecated
- public long getPerUserMinEvictableIdleTimeMillis(final String userName) {
- return getPerUserMinEvictableIdleDuration(userName).toMillis();
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getMinIdle()} for the specified user's pool or the
- * default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- public int getPerUserMinIdle(final String userName) {
- return get(perUserMinIdle, userName, this::getDefaultMinIdle);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getNumTestsPerEvictionRun()} for the specified user's
- * pool or the default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- public int getPerUserNumTestsPerEvictionRun(final String userName) {
- return get(perUserNumTestsPerEvictionRun, userName, this::getDefaultNumTestsPerEvictionRun);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getSoftMinEvictableIdleDuration()} for the specified
- * user's pool or the default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- * @since 2.10.0
- */
- public Duration getPerUserSoftMinEvictableIdleDuration(final String userName) {
- return get(perUserSoftMinEvictableIdleDuration, userName, this::getDefaultSoftMinEvictableIdleDuration);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getSoftMinEvictableIdleDuration()} for the specified
- * user's pool or the default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- * @deprecated Use {@link #getPerUserSoftMinEvictableIdleDuration(String)}.
- */
- @Deprecated
- public long getPerUserSoftMinEvictableIdleTimeMillis(final String userName) {
- return getPerUserSoftMinEvictableIdleDuration(userName).toMillis();
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getTestOnBorrow()} for the specified user's pool or the
- * default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- public boolean getPerUserTestOnBorrow(final String userName) {
- return get(perUserTestOnBorrow, userName, this::getDefaultTestOnBorrow);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getTestOnCreate()} for the specified user's pool or the
- * default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- public boolean getPerUserTestOnCreate(final String userName) {
- return get(perUserTestOnCreate, userName, this::getDefaultTestOnCreate);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getTestOnReturn()} for the specified user's pool or the
- * default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- public boolean getPerUserTestOnReturn(final String userName) {
- return get(perUserTestOnReturn, userName, this::getDefaultTestOnReturn);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getTestWhileIdle()} for the specified user's pool or
- * the default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- */
- public boolean getPerUserTestWhileIdle(final String userName) {
- return get(perUserTestWhileIdle, userName, this::getDefaultTestWhileIdle);
- }
- /**
- * Gets the user specific value for {@link GenericObjectPool#getDurationBetweenEvictionRuns()} for the specified
- * user's pool or the default if no user specific value is defined.
- *
- * @param userName
- * The user name key.
- * @return The user specific value.
- * @deprecated Use {@link #getPerUserDurationBetweenEvictionRuns(String)}.
- */
- @Deprecated
- public long getPerUserTimeBetweenEvictionRunsMillis(final String userName) {
- return getPerUserDurationBetweenEvictionRuns(userName).toMillis();
- }
- /**
- * Returns the object pool associated with the given PoolKey.
- *
- * @param poolKey
- * PoolKey identifying the pool
- * @return the GenericObjectPool pooling connections for the userName and datasource specified by the PoolKey
- */
- private ObjectPool<PooledConnectionAndInfo> getPool(final PoolKey poolKey) {
- final CPDSConnectionFactory mgr = (CPDSConnectionFactory) managers.get(poolKey);
- return mgr == null ? null : mgr.getPool();
- }
- @SuppressWarnings("resource") // does not allocate a pool
- @Override
- protected PooledConnectionAndInfo getPooledConnectionAndInfo(final String userName, final String password) throws SQLException {
- final PoolKey key = getPoolKey(userName);
- ObjectPool<PooledConnectionAndInfo> pool;
- PooledConnectionManager manager;
- synchronized (this) {
- manager = managers.get(key);
- if (manager == null) {
- try {
- registerPool(userName, password);
- manager = managers.get(key);
- } catch (final NamingException e) {
- throw new SQLException("RegisterPool failed", e);
- }
- }
- pool = getCPDSConnectionFactoryPool(manager);
- }
- PooledConnectionAndInfo info = null;
- try {
- info = pool.borrowObject();
- } catch (final NoSuchElementException ex) {
- throw new SQLException("Could not retrieve connection info from pool", ex);
- } catch (final Exception e) {
- // See if failure is due to CPDSConnectionFactory authentication failure
- try {
- testCPDS(userName, password);
- } catch (final Exception ex) {
- throw new SQLException("Could not retrieve connection info from pool", ex);
- }
- // New password works, so kill the old pool, create a new one, and borrow
- manager.closePool(userName);
- synchronized (this) {
- managers.remove(key);
- }
- try {
- registerPool(userName, password);
- pool = getPool(key);
- } catch (final NamingException ne) {
- throw new SQLException("RegisterPool failed", ne);
- }
- try {
- info = pool.borrowObject();
- } catch (final Exception ex) {
- throw new SQLException("Could not retrieve connection info from pool", ex);
- }
- }
- return info;
- }
- /**
- * Creates a pool key from the provided parameters.
- *
- * @param userName
- * User name
- * @return The pool key
- */
- private PoolKey getPoolKey(final String userName) {
- return new PoolKey(getDataSourceName(), userName);
- }
- /**
- * Returns a {@code PerUserPoolDataSource} {@link Reference}.
- */
- @Override
- public Reference getReference() throws NamingException {
- final Reference ref = new Reference(getClass().getName(), PerUserPoolDataSourceFactory.class.getName(), null);
- ref.add(new StringRefAddr("instanceKey", getInstanceKey()));
- return ref;
- }
- <K, V> Map<K, V> put(Map<K, V> map, final K key, final V value) {
- if (map == null) {
- map = createMap();
- }
- map.put(key, value);
- return map;
- }
- /**
- * Deserializes an instance from an ObjectInputStream.
- *
- * @param in The source ObjectInputStream.
- * @throws IOException Any of the usual Input/Output related exceptions.
- * @throws ClassNotFoundException A class of a serialized object cannot be found.
- */
- @SuppressWarnings("resource")
- private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
- in.defaultReadObject();
- this.managers = readObjectImpl().managers;
- }
- private PerUserPoolDataSource readObjectImpl() throws IOException, ClassNotFoundException {
- try {
- return (PerUserPoolDataSource) new PerUserPoolDataSourceFactory().getObjectInstance(getReference(), null, null, null);
- } catch (final NamingException e) {
- throw new IOException("NamingException: " + e);
- }
- }
- private synchronized void registerPool(final String userName, final String password) throws NamingException, SQLException {
- final ConnectionPoolDataSource cpds = testCPDS(userName, password);
- // Set up the factory we will use (passing the pool associates
- // the factory with the pool, so we do not have to do so
- // explicitly)
- final CPDSConnectionFactory factory = new CPDSConnectionFactory(cpds, getValidationQuery(), getValidationQueryTimeoutDuration(),
- isRollbackAfterValidation(), userName, password);
- factory.setMaxConn(getMaxConnDuration());
- // Create an object pool to contain our PooledConnections
- @SuppressWarnings("resource")
- final GenericObjectPool<PooledConnectionAndInfo> pool = new GenericObjectPool<>(factory);
- factory.setPool(pool);
- pool.setBlockWhenExhausted(getPerUserBlockWhenExhausted(userName));
- pool.setEvictionPolicyClassName(getPerUserEvictionPolicyClassName(userName));
- pool.setLifo(getPerUserLifo(userName));
- pool.setMaxIdle(getPerUserMaxIdle(userName));
- pool.setMaxTotal(getPerUserMaxTotal(userName));
- pool.setMaxWait(getPerUserMaxWaitDuration(userName));
- pool.setMinEvictableIdleDuration(getPerUserMinEvictableIdleDuration(userName));
- pool.setMinIdle(getPerUserMinIdle(userName));
- pool.setNumTestsPerEvictionRun(getPerUserNumTestsPerEvictionRun(userName));
- pool.setSoftMinEvictableIdleDuration(getPerUserSoftMinEvictableIdleDuration(userName));
- pool.setTestOnCreate(getPerUserTestOnCreate(userName));
- pool.setTestOnBorrow(getPerUserTestOnBorrow(userName));
- pool.setTestOnReturn(getPerUserTestOnReturn(userName));
- pool.setTestWhileIdle(getPerUserTestWhileIdle(userName));
- pool.setDurationBetweenEvictionRuns(getPerUserDurationBetweenEvictionRuns(userName));
- pool.setSwallowedExceptionListener(new SwallowedExceptionLogger(log));
- final PoolKey poolKey = getPoolKey(userName);
- if (managers.containsKey(poolKey)) {
- pool.close();
- throw new IllegalStateException("Pool already contains an entry for this user/password: " + userName);
- }
- managers.put(poolKey, factory);
- }
- private <K, V> Map<K, V> replaceAll(final Map<K, V> currentMap, final Map<K, V> newMap) {
- if (currentMap == null) {
- return new HashMap<>(newMap);
- }
- currentMap.clear();
- currentMap.putAll(newMap);
- return currentMap;
- }
- void setPerUserBlockWhenExhausted(final Map<String, Boolean> newMap) {
- assertInitializationAllowed();
- perUserBlockWhenExhausted = replaceAll(perUserBlockWhenExhausted, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getBlockWhenExhausted()} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- */
- public void setPerUserBlockWhenExhausted(final String userName, final Boolean value) {
- assertInitializationAllowed();
- perUserBlockWhenExhausted = put(perUserBlockWhenExhausted, userName, value);
- }
- void setPerUserDefaultAutoCommit(final Map<String, Boolean> newMap) {
- assertInitializationAllowed();
- perUserDefaultAutoCommit = replaceAll(perUserDefaultAutoCommit, newMap);
- }
- /**
- * Sets a user specific default value for {@link Connection#setAutoCommit(boolean)} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- */
- public void setPerUserDefaultAutoCommit(final String userName, final Boolean value) {
- assertInitializationAllowed();
- perUserDefaultAutoCommit = put(perUserDefaultAutoCommit, userName, value);
- }
- void setPerUserDefaultReadOnly(final Map<String, Boolean> newMap) {
- assertInitializationAllowed();
- perUserDefaultReadOnly = replaceAll(perUserDefaultReadOnly, newMap);
- }
- /**
- * Sets a user specific default value for {@link Connection#setReadOnly(boolean)} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- */
- public void setPerUserDefaultReadOnly(final String userName, final Boolean value) {
- assertInitializationAllowed();
- perUserDefaultReadOnly = put(perUserDefaultReadOnly, userName, value);
- }
- void setPerUserDefaultTransactionIsolation(final Map<String, Integer> newMap) {
- assertInitializationAllowed();
- perUserDefaultTransactionIsolation = replaceAll(perUserDefaultTransactionIsolation, newMap);
- }
- /**
- * Sets a user specific default value for {@link Connection#setTransactionIsolation(int)} for the specified user's
- * pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- */
- public void setPerUserDefaultTransactionIsolation(final String userName, final Integer value) {
- assertInitializationAllowed();
- perUserDefaultTransactionIsolation = put(perUserDefaultTransactionIsolation, userName, value);
- }
- void setPerUserDurationBetweenEvictionRuns(final Map<String, Duration> newMap) {
- assertInitializationAllowed();
- perUserDurationBetweenEvictionRuns = replaceAll(perUserDurationBetweenEvictionRuns, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getDurationBetweenEvictionRuns()} for the specified
- * user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- * @since 2.10.0
- */
- public void setPerUserDurationBetweenEvictionRuns(final String userName, final Duration value) {
- assertInitializationAllowed();
- perUserDurationBetweenEvictionRuns = put(perUserDurationBetweenEvictionRuns, userName, value);
- }
- void setPerUserEvictionPolicyClassName(final Map<String, String> newMap) {
- assertInitializationAllowed();
- perUserEvictionPolicyClassName = replaceAll(perUserEvictionPolicyClassName, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getEvictionPolicyClassName()} for the specified user's
- * pool.
- * <p>
- * The class must implement {@link EvictionPolicy}.
- * </p>
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- */
- public void setPerUserEvictionPolicyClassName(final String userName, final String value) {
- assertInitializationAllowed();
- perUserEvictionPolicyClassName = put(perUserEvictionPolicyClassName, userName, value);
- }
- void setPerUserLifo(final Map<String, Boolean> newMap) {
- assertInitializationAllowed();
- perUserLifo = replaceAll(perUserLifo, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getLifo()} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- */
- public void setPerUserLifo(final String userName, final Boolean value) {
- assertInitializationAllowed();
- perUserLifo = put(perUserLifo, userName, value);
- }
- void setPerUserMaxIdle(final Map<String, Integer> newMap) {
- assertInitializationAllowed();
- perUserMaxIdle = replaceAll(perUserMaxIdle, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getMaxIdle()} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- */
- public void setPerUserMaxIdle(final String userName, final Integer value) {
- assertInitializationAllowed();
- perUserMaxIdle = put(perUserMaxIdle, userName, value);
- }
- void setPerUserMaxTotal(final Map<String, Integer> newMap) {
- assertInitializationAllowed();
- perUserMaxTotal = replaceAll(perUserMaxTotal, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getMaxTotal()} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- */
- public void setPerUserMaxTotal(final String userName, final Integer value) {
- assertInitializationAllowed();
- perUserMaxTotal = put(perUserMaxTotal, userName, value);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getMaxWaitDuration()} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- * @since 2.10.0
- */
- public void setPerUserMaxWait(final String userName, final Duration value) {
- assertInitializationAllowed();
- perUserMaxWaitDuration = put(perUserMaxWaitDuration, userName, value);
- }
- void setPerUserMaxWaitDuration(final Map<String, Duration> newMap) {
- assertInitializationAllowed();
- perUserMaxWaitDuration = replaceAll(perUserMaxWaitDuration, newMap);
- }
- void setPerUserMaxWaitMillis(final Map<String, Long> newMap) {
- assertInitializationAllowed();
- perUserMaxWaitDuration = convertMap(perUserMaxWaitDuration, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getMaxWaitDuration()} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- * @deprecated Use {@link #setPerUserMaxWait(String, Duration)}.
- */
- @Deprecated
- public void setPerUserMaxWaitMillis(final String userName, final Long value) {
- setPerUserMaxWait(userName, toDurationOrNull(value));
- }
- void setPerUserMinEvictableIdle(final Map<String, Duration> newMap) {
- assertInitializationAllowed();
- perUserMinEvictableIdleDuration = replaceAll(perUserMinEvictableIdleDuration, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getMinEvictableIdleDuration()} for the specified user's
- * pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- * @since 2.10.0
- */
- public void setPerUserMinEvictableIdle(final String userName, final Duration value) {
- assertInitializationAllowed();
- perUserMinEvictableIdleDuration = put(perUserMinEvictableIdleDuration, userName, value);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getMinEvictableIdleDuration()} for the specified user's
- * pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- * @deprecated Use {@link #setPerUserMinEvictableIdle(String, Duration)}.
- */
- @Deprecated
- public void setPerUserMinEvictableIdleTimeMillis(final String userName, final Long value) {
- setPerUserMinEvictableIdle(userName, toDurationOrNull(value));
- }
- void setPerUserMinIdle(final Map<String, Integer> newMap) {
- assertInitializationAllowed();
- perUserMinIdle = replaceAll(perUserMinIdle, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getMinIdle()} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- */
- public void setPerUserMinIdle(final String userName, final Integer value) {
- assertInitializationAllowed();
- perUserMinIdle = put(perUserMinIdle, userName, value);
- }
- void setPerUserNumTestsPerEvictionRun(final Map<String, Integer> newMap) {
- assertInitializationAllowed();
- perUserNumTestsPerEvictionRun = replaceAll(perUserNumTestsPerEvictionRun, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getNumTestsPerEvictionRun()} for the specified user's
- * pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- */
- public void setPerUserNumTestsPerEvictionRun(final String userName, final Integer value) {
- assertInitializationAllowed();
- perUserNumTestsPerEvictionRun = put(perUserNumTestsPerEvictionRun, userName, value);
- }
- void setPerUserSoftMinEvictableIdle(final Map<String, Duration> newMap) {
- assertInitializationAllowed();
- perUserSoftMinEvictableIdleDuration = replaceAll(perUserSoftMinEvictableIdleDuration, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getSoftMinEvictableIdleDuration()} for the specified
- * user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- * @since 2.10.0
- */
- public void setPerUserSoftMinEvictableIdle(final String userName, final Duration value) {
- assertInitializationAllowed();
- perUserSoftMinEvictableIdleDuration = put(perUserSoftMinEvictableIdleDuration, userName, value);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getSoftMinEvictableIdleDuration()} for the specified
- * user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- * @deprecated Use {@link #setPerUserSoftMinEvictableIdle(String, Duration)}.
- */
- @Deprecated
- public void setPerUserSoftMinEvictableIdleTimeMillis(final String userName, final Long value) {
- setPerUserSoftMinEvictableIdle(userName, toDurationOrNull(value));
- }
- void setPerUserTestOnBorrow(final Map<String, Boolean> newMap) {
- assertInitializationAllowed();
- perUserTestOnBorrow = replaceAll(perUserTestOnBorrow, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getTestOnBorrow()} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- */
- public void setPerUserTestOnBorrow(final String userName, final Boolean value) {
- assertInitializationAllowed();
- perUserTestOnBorrow = put(perUserTestOnBorrow, userName, value);
- }
- void setPerUserTestOnCreate(final Map<String, Boolean> newMap) {
- assertInitializationAllowed();
- perUserTestOnCreate = replaceAll(perUserTestOnCreate, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getTestOnCreate()} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- */
- public void setPerUserTestOnCreate(final String userName, final Boolean value) {
- assertInitializationAllowed();
- perUserTestOnCreate = put(perUserTestOnCreate, userName, value);
- }
- void setPerUserTestOnReturn(final Map<String, Boolean> newMap) {
- assertInitializationAllowed();
- perUserTestOnReturn = replaceAll(perUserTestOnReturn, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getTestOnReturn()} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- */
- public void setPerUserTestOnReturn(final String userName, final Boolean value) {
- assertInitializationAllowed();
- perUserTestOnReturn = put(perUserTestOnReturn, userName, value);
- }
- void setPerUserTestWhileIdle(final Map<String, Boolean> newMap) {
- assertInitializationAllowed();
- perUserTestWhileIdle = replaceAll(perUserTestWhileIdle, newMap);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getTestWhileIdle()} for the specified user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- */
- public void setPerUserTestWhileIdle(final String userName, final Boolean value) {
- assertInitializationAllowed();
- perUserTestWhileIdle = put(perUserTestWhileIdle, userName, value);
- }
- /**
- * Sets a user specific value for {@link GenericObjectPool#getDurationBetweenEvictionRuns()} for the specified
- * user's pool.
- *
- * @param userName
- * The user name key.
- * @param value
- * The user specific value.
- * @deprecated Use {@link #setPerUserDurationBetweenEvictionRuns(String, Duration)}.
- */
- @Deprecated
- public void setPerUserTimeBetweenEvictionRunsMillis(final String userName, final Long value) {
- setPerUserDurationBetweenEvictionRuns(userName, toDurationOrNull(value));
- }
- @Override
- protected void setupDefaults(final Connection con, final String userName) throws SQLException {
- Boolean defaultAutoCommit = isDefaultAutoCommit();
- if (userName != null) {
- final Boolean userMax = getPerUserDefaultAutoCommit(userName);
- if (userMax != null) {
- defaultAutoCommit = userMax;
- }
- }
- Boolean defaultReadOnly = isDefaultReadOnly();
- if (userName != null) {
- final Boolean userMax = getPerUserDefaultReadOnly(userName);
- if (userMax != null) {
- defaultReadOnly = userMax;
- }
- }
- int defaultTransactionIsolation = getDefaultTransactionIsolation();
- if (userName != null) {
- final Integer userMax = getPerUserDefaultTransactionIsolation(userName);
- if (userMax != null) {
- defaultTransactionIsolation = userMax;
- }
- }
- if (defaultAutoCommit != null && con.getAutoCommit() != defaultAutoCommit) {
- con.setAutoCommit(defaultAutoCommit);
- }
- if (defaultTransactionIsolation != UNKNOWN_TRANSACTIONISOLATION) {
- con.setTransactionIsolation(defaultTransactionIsolation);
- }
- if (defaultReadOnly != null && con.isReadOnly() != defaultReadOnly) {
- con.setReadOnly(defaultReadOnly);
- }
- }
- private Duration toDurationOrNull(final Long millis) {
- return millis == null ? null : Duration.ofMillis(millis);
- }
- }