package io.dropwizard.db;
import com.codahale.metrics.MetricRegistry;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.primitives.Ints;
import io.dropwizard.util.Duration;
import io.dropwizard.validation.MinDuration;
import io.dropwizard.validation.ValidationMethod;
import org.apache.tomcat.jdbc.pool.PoolProperties;
import org.hibernate.validator.constraints.NotEmpty;
import javax.annotation.Nullable;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.sql.Connection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
A factory for pooled ManagedDataSource
s.
Configuration Parameters:
Name
Default
Description
driverClass
REQUIRED
The full name of the JDBC driver class.
url
REQUIRED
The URL of the server.
user
none
The username used to connect to the server.
password
none
The password used to connect to the server.
removeAbandoned
false
Remove abandoned connections if they exceed the removeAbandonedTimeout
. If set to true
a connection is considered abandoned and eligible for removal if it has been in use longer than the removeAbandonedTimeout
and the condition for abandonWhenPercentageFull
is met.
removeAbandonedTimeout
60 seconds
The time before a database connection can be considered abandoned.
abandonWhenPercentageFull
0
Connections that have been abandoned (timed out) won't get closed and reported up unless the number of connections in use are above the percentage defined by abandonWhenPercentageFull
. The value should be between 0-100.
alternateUsernamesAllowed
false
Set to true if the call getConnection(username,password)
is allowed. This is used for when the pool is used by an application accessing multiple schemas. There is a performance impact turning this option on, even when not used.
commitOnReturn
false
Set to true if you want the connection pool to commit any pending transaction when a
connection is returned.
rollbackOnReturn
false
Set to true if you want the connection pool to rollback any pending transaction when a
connection is returned.
autoCommitByDefault
JDBC driver's default
The default auto-commit state of the connections.
readOnlyByDefault
JDBC driver's default
The default read-only state of the connections.
properties
none
Any additional JDBC driver parameters.
defaultCatalog
none
The default catalog to use for the connections.
defaultTransactionIsolation
JDBC driver default
The default transaction isolation to use for the connections. Can be one of none
, default
, read-uncommitted
, read-committed
, repeatable-read
, or serializable
.
useFairQueue
true
If true
, calls to getConnection
are handled in a FIFO manner.
initialSize
10
The initial size of the connection pool. May be zero, which will allow you to start the connection pool without requiring the DB to be up. In the latter case the minSize
must also be set to zero.
minSize
10
The minimum size of the connection pool.
maxSize
100
The maximum size of the connection pool.
initializationQuery
none
A custom query to be run when a connection is first created.
logAbandonedConnections
false
If true
, logs stack traces of abandoned connections.
logValidationErrors
false
If true
, logs errors when connections fail validation.
maxConnectionAge
none
If set, connections which have been open for longer than maxConnectionAge
are closed when returned.
maxWaitForConnection
30 seconds
If a request for a connection is blocked for longer than this period, an exception
will be thrown.
minIdleTime
1 minute
The minimum amount of time an connection must sit idle in the pool before it is
eligible for eviction.
validationQuery
SELECT 1
The SQL query that will be used to validate connections from this pool before
returning them to the caller or pool. If specified, this query does not have to
return any data, it just can't throw a SQLException.
validationQueryTimeout
none
The timeout before a connection validation queries fail.
checkConnectionWhileIdle
true
Set to true if query validation should take place while the connection is idle.
checkConnectionOnBorrow
false
Whether or not connections will be validated before being borrowed from the pool. If
the connection fails to validate, it will be dropped from the pool, and another will
be borrowed.
checkConnectionOnConnect
true
Whether or not connections will be validated before being added to the pool. If the
connection fails to validate, it won't be added to the pool.
checkConnectionOnReturn
false
Whether or not connections will be validated after being returned to the pool. If
the connection fails to validate, it will be dropped from the pool.
autoCommentsEnabled
true
Whether or not ORMs should automatically add comments.
evictionInterval
5 seconds
The amount of time to sleep between runs of the idle connection validation, abandoned
cleaner and idle pool resizing.
validationInterval
30 seconds
To avoid excess validation, only run validation once every interval.
validatorClassName
(none)
Name of a class of a custom Validator
implementation, which will be used for validating connections.
jdbcInterceptors
(none)
A semicolon separated list of classnames extending JdbcInterceptor
ignoreExceptionOnPreLoad
false
Flag whether ignore error of connection creation while initializing the pool. Set to
true if you want to ignore error of connection creation while initializing the pool.
Set to false if you want to fail the initialization of the pool by throwing exception.
/**
* A factory for pooled {@link ManagedDataSource}s.
* <p/>
* <b>Configuration Parameters:</b>
* <table>
* <tr>
* <td>Name</td>
* <td>Default</td>
* <td>Description</td>
* </tr>
* <tr>
* <td>{@code driverClass}</td>
* <td><b>REQUIRED</b></td>
* <td>The full name of the JDBC driver class.</td>
* </tr>
* <tr>
* <td>{@code url}</td>
* <td><b>REQUIRED</b></td>
* <td>The URL of the server.</td>
* </tr>
* <tr>
* <td>{@code user}</td>
* <td><b>none</b></td>
* <td>The username used to connect to the server.</td>
* </tr>
* <tr>
* <td>{@code password}</td>
* <td>none</td>
* <td>The password used to connect to the server.</td>
* </tr>
* <tr>
* <td>{@code removeAbandoned}</td>
* <td>{@code false}</td>
* <td>
* Remove abandoned connections if they exceed the {@code removeAbandonedTimeout}.
* If set to {@code true} a connection is considered abandoned and eligible for removal if it has
* been in use longer than the {@code removeAbandonedTimeout} and the condition for
* {@code abandonWhenPercentageFull} is met.
* </td>
* </tr>
* <tr>
* <td>{@code removeAbandonedTimeout}</td>
* <td>60 seconds</td>
* <td>
* The time before a database connection can be considered abandoned.
* </td>
* </tr>
* <tr>
* <td>{@code abandonWhenPercentageFull}</td>
* <td>0</td>
* <td>
* Connections that have been abandoned (timed out) won't get closed and reported up
* unless the number of connections in use are above the percentage defined by
* {@code abandonWhenPercentageFull}. The value should be between 0-100.
* </td>
* </tr>
* <tr>
* <td>{@code alternateUsernamesAllowed}</td>
* <td>{@code false}</td>
* <td>
* Set to true if the call
* {@link javax.sql.DataSource#getConnection(String, String) getConnection(username,password)}
* is allowed. This is used for when the pool is used by an application accessing
* multiple schemas. There is a performance impact turning this option on, even when not
* used.
* </td>
* </tr>
* <tr>
* <td>{@code commitOnReturn}</td>
* <td>{@code false}</td>
* <td>
* Set to true if you want the connection pool to commit any pending transaction when a
* connection is returned.
* </td>
* </tr>
* <tr>
* <td>{@code rollbackOnReturn}</td>
* <td>{@code false}</td>
* <td>
* Set to true if you want the connection pool to rollback any pending transaction when a
* connection is returned.
* </td>
* </tr>
* <tr>
* <td>{@code autoCommitByDefault}</td>
* <td>JDBC driver's default</td>
* <td>The default auto-commit state of the connections.</td>
* </tr>
* <tr>
* <td>{@code readOnlyByDefault}</td>
* <td>JDBC driver's default</td>
* <td>The default read-only state of the connections.</td>
* </tr>
* <tr>
* <td>{@code properties}</td>
* <td>none</td>
* <td>Any additional JDBC driver parameters.</td>
* </tr>
* <tr>
* <td>{@code defaultCatalog}</td>
* <td>none</td>
* <td>The default catalog to use for the connections.</td>
* </tr>
* <tr>
* <td>{@code defaultTransactionIsolation}</td>
* <td>JDBC driver default</td>
* <td>
* The default transaction isolation to use for the connections. Can be one of
* {@code none}, {@code default}, {@code read-uncommitted}, {@code read-committed},
* {@code repeatable-read}, or {@code serializable}.
* </td>
* </tr>
* <tr>
* <td>{@code useFairQueue}</td>
* <td>{@code true}</td>
* <td>
* If {@code true}, calls to {@code getConnection} are handled in a FIFO manner.
* </td>
* </tr>
* <tr>
* <td>{@code initialSize}</td>
* <td>10</td>
* <td>
* The initial size of the connection pool. May be zero, which will allow you to start
* the connection pool without requiring the DB to be up. In the latter case the {@link #minSize}
* must also be set to zero.
* </td>
* </tr>
* <tr>
* <td>{@code minSize}</td>
* <td>10</td>
* <td>
* The minimum size of the connection pool.
* </td>
* </tr>
* <tr>
* <td>{@code maxSize}</td>
* <td>100</td>
* <td>
* The maximum size of the connection pool.
* </td>
* </tr>
* <tr>
* <td>{@code initializationQuery}</td>
* <td>none</td>
* <td>
* A custom query to be run when a connection is first created.
* </td>
* </tr>
* <tr>
* <td>{@code logAbandonedConnections}</td>
* <td>{@code false}</td>
* <td>
* If {@code true}, logs stack traces of abandoned connections.
* </td>
* </tr>
* <tr>
* <td>{@code logValidationErrors}</td>
* <td>{@code false}</td>
* <td>
* If {@code true}, logs errors when connections fail validation.
* </td>
* </tr>
* <tr>
* <td>{@code maxConnectionAge}</td>
* <td>none</td>
* <td>
* If set, connections which have been open for longer than {@code maxConnectionAge} are
* closed when returned.
* </td>
* </tr>
* <tr>
* <td>{@code maxWaitForConnection}</td>
* <td>30 seconds</td>
* <td>
* If a request for a connection is blocked for longer than this period, an exception
* will be thrown.
* </td>
* </tr>
* <tr>
* <td>{@code minIdleTime}</td>
* <td>1 minute</td>
* <td>
* The minimum amount of time an connection must sit idle in the pool before it is
* eligible for eviction.
* </td>
* </tr>
* <tr>
* <td>{@code validationQuery}</td>
* <td>{@code SELECT 1}</td>
* <td>
* The SQL query that will be used to validate connections from this pool before
* returning them to the caller or pool. If specified, this query does not have to
* return any data, it just can't throw a SQLException.
* </td>
* </tr>
* <tr>
* <td>{@code validationQueryTimeout}</td>
* <td>none</td>
* <td>
* The timeout before a connection validation queries fail.
* </td>
* </tr>
* <tr>
* <td>{@code checkConnectionWhileIdle}</td>
* <td>{@code true}</td>
* <td>
* Set to true if query validation should take place while the connection is idle.
* </td>
* </tr>
* <tr>
* <td>{@code checkConnectionOnBorrow}</td>
* <td>{@code false}</td>
* <td>
* Whether or not connections will be validated before being borrowed from the pool. If
* the connection fails to validate, it will be dropped from the pool, and another will
* be borrowed.
* </td>
* </tr>
* <tr>
* <td>{@code checkConnectionOnConnect}</td>
* <td>{@code true}</td>
* <td>
* Whether or not connections will be validated before being added to the pool. If the
* connection fails to validate, it won't be added to the pool.
* </td>
* </tr>
* <tr>
* <td>{@code checkConnectionOnReturn}</td>
* <td>{@code false}</td>
* <td>
* Whether or not connections will be validated after being returned to the pool. If
* the connection fails to validate, it will be dropped from the pool.
* </td>
* </tr>
* <tr>
* <td>{@code autoCommentsEnabled}</td>
* <td>{@code true}</td>
* <td>
* Whether or not ORMs should automatically add comments.
* </td>
* </tr>
* <tr>
* <td>{@code evictionInterval}</td>
* <td>5 seconds</td>
* <td>
* The amount of time to sleep between runs of the idle connection validation, abandoned
* cleaner and idle pool resizing.
* </td>
* </tr>
* <tr>
* <td>{@code validationInterval}</td>
* <td>30 seconds</td>
* <td>
* To avoid excess validation, only run validation once every interval.
* </td>
* </tr>
* <tr>
* <td>{@code validatorClassName}</td>
* <td>(none)</td>
* <td>
* Name of a class of a custom {@link org.apache.tomcat.jdbc.pool.Validator}
* implementation, which will be used for validating connections.
* </td>
* </tr>
* <tr>
* <td>{@code jdbcInterceptors}</td>
* <td>(none)</td>
* <td>
* A semicolon separated list of classnames extending
* {@link org.apache.tomcat.jdbc.pool.JdbcInterceptor}
* </td>
* </tr>
* <tr>
* <td>{@code ignoreExceptionOnPreLoad}</td>
* <td>{@code false}</td>
* <td>
* Flag whether ignore error of connection creation while initializing the pool. Set to
* true if you want to ignore error of connection creation while initializing the pool.
* Set to false if you want to fail the initialization of the pool by throwing exception.
* </td>
* </tr>
* </table>
*/
public class DataSourceFactory implements PooledDataSourceFactory {
@SuppressWarnings("UnusedDeclaration")
public enum TransactionIsolation {
NONE(Connection.TRANSACTION_NONE),
DEFAULT(org.apache.tomcat.jdbc.pool.DataSourceFactory.UNKNOWN_TRANSACTIONISOLATION),
READ_UNCOMMITTED(Connection.TRANSACTION_READ_UNCOMMITTED),
READ_COMMITTED(Connection.TRANSACTION_READ_COMMITTED),
REPEATABLE_READ(Connection.TRANSACTION_REPEATABLE_READ),
SERIALIZABLE(Connection.TRANSACTION_SERIALIZABLE);
private final int value;
TransactionIsolation(int value) {
this.value = value;
}
public int get() {
return value;
}
}
@NotEmpty
private String driverClass = "";
@Min(0)
@Max(100)
private int abandonWhenPercentageFull = 0;
private boolean alternateUsernamesAllowed = false;
private boolean commitOnReturn = false;
private boolean rollbackOnReturn = false;
@Nullable
private Boolean autoCommitByDefault;
@Nullable
private Boolean readOnlyByDefault;
@Nullable
private String user;
@Nullable
private String password;
@NotEmpty
private String url = "";
@NotNull
private Map<String, String> properties = new LinkedHashMap<>();
@Nullable
private String defaultCatalog;
@NotNull
private TransactionIsolation defaultTransactionIsolation = TransactionIsolation.DEFAULT;
private boolean useFairQueue = true;
@Min(0)
private int initialSize = 10;
@Min(0)
private int minSize = 10;
@Min(1)
private int maxSize = 100;
@Nullable
private String initializationQuery;
private boolean logAbandonedConnections = false;
private boolean logValidationErrors = false;
@MinDuration(value = 0, unit = TimeUnit.MILLISECONDS, inclusive = false)
@Nullable
private Duration maxConnectionAge;
@NotNull
@MinDuration(value = 0, unit = TimeUnit.MILLISECONDS, inclusive = false)
private Duration maxWaitForConnection = Duration.seconds(30);
@NotNull
@MinDuration(value = 0, unit = TimeUnit.MILLISECONDS, inclusive = false)
private Duration minIdleTime = Duration.minutes(1);
@NotNull
private String validationQuery = "/* Health Check */ SELECT 1";
@MinDuration(value = 0, unit = TimeUnit.MILLISECONDS, inclusive = false)
@Nullable
private Duration validationQueryTimeout;
private boolean checkConnectionWhileIdle = true;
private boolean checkConnectionOnBorrow = false;
private boolean checkConnectionOnConnect = true;
private boolean checkConnectionOnReturn = false;
private boolean autoCommentsEnabled = true;
@NotNull
@MinDuration(value = 0, unit = TimeUnit.MILLISECONDS, inclusive = false)
private Duration evictionInterval = Duration.seconds(5);
@NotNull
@MinDuration(value = 50, unit = TimeUnit.MILLISECONDS)
private Duration validationInterval = Duration.seconds(30);
private Optional<String> validatorClassName = Optional.empty();
private boolean removeAbandoned = false;
@NotNull
@MinDuration(value = 0, unit = TimeUnit.MILLISECONDS, inclusive = false)
private Duration removeAbandonedTimeout = Duration.seconds(60L);
private Optional<String> jdbcInterceptors = Optional.empty();
private boolean ignoreExceptionOnPreLoad = false;
@JsonProperty
@Override
public boolean isAutoCommentsEnabled() {
return autoCommentsEnabled;
}
@JsonProperty
public void setAutoCommentsEnabled(boolean autoCommentsEnabled) {
this.autoCommentsEnabled = autoCommentsEnabled;
}
@JsonProperty
@Override
public String getDriverClass() {
return driverClass;
}
@JsonProperty
public void setDriverClass(String driverClass) {
this.driverClass = driverClass;
}
@JsonProperty
@Nullable
public String getUser() {
return user;
}
@JsonProperty
public void setUser(String user) {
this.user = user;
}
@JsonProperty
@Nullable
public String getPassword() {
return password;
}
@JsonProperty
public void setPassword(String password) {
this.password = password;
}
@JsonProperty
@Override
public String getUrl() {
return url;
}
@JsonProperty
public void setUrl(String url) {
this.url = url;
}
@JsonProperty
@Override
public Map<String, String> getProperties() {
return properties;
}
@JsonProperty
public void setProperties(Map<String, String> properties) {
this.properties = properties;
}
@JsonProperty
public Duration getMaxWaitForConnection() {
return maxWaitForConnection;
}
@JsonProperty
public void setMaxWaitForConnection(Duration maxWaitForConnection) {
this.maxWaitForConnection = maxWaitForConnection;
}
@Override
@JsonProperty
public String getValidationQuery() {
return validationQuery;
}
@Override
@Deprecated
@JsonIgnore
public String getHealthCheckValidationQuery() {
return getValidationQuery();
}
@JsonProperty
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
@JsonProperty
public int getMinSize() {
return minSize;
}
@JsonProperty
public void setMinSize(int minSize) {
this.minSize = minSize;
}
@JsonProperty
public int getMaxSize() {
return maxSize;
}
@JsonProperty
public void setMaxSize(int maxSize) {
this.maxSize = maxSize;
}
@JsonProperty
public boolean getCheckConnectionWhileIdle() {
return checkConnectionWhileIdle;
}
@JsonProperty
public void setCheckConnectionWhileIdle(boolean checkConnectionWhileIdle) {
this.checkConnectionWhileIdle = checkConnectionWhileIdle;
}
@Deprecated
@JsonProperty
public boolean isDefaultReadOnly() {
return Boolean.TRUE.equals(readOnlyByDefault);
}
@Deprecated
@JsonProperty
public void setDefaultReadOnly(boolean defaultReadOnly) {
readOnlyByDefault = defaultReadOnly;
}
@JsonIgnore
@ValidationMethod(message = ".minSize must be less than or equal to maxSize")
public boolean isMinSizeLessThanMaxSize() {
return minSize <= maxSize;
}
@JsonIgnore
@ValidationMethod(message = ".initialSize must be less than or equal to maxSize")
public boolean isInitialSizeLessThanMaxSize() {
return initialSize <= maxSize;
}
@JsonIgnore
@ValidationMethod(message = ".initialSize must be greater than or equal to minSize")
public boolean isInitialSizeGreaterThanMinSize() {
return minSize <= initialSize;
}
@JsonProperty
public int getAbandonWhenPercentageFull() {
return abandonWhenPercentageFull;
}
@JsonProperty
public void setAbandonWhenPercentageFull(int percentage) {
this.abandonWhenPercentageFull = percentage;
}
@JsonProperty
public boolean isAlternateUsernamesAllowed() {
return alternateUsernamesAllowed;
}
@JsonProperty
public void setAlternateUsernamesAllowed(boolean allow) {
this.alternateUsernamesAllowed = allow;
}
@JsonProperty
public boolean getCommitOnReturn() {
return commitOnReturn;
}
@JsonProperty
public boolean getRollbackOnReturn() {
return rollbackOnReturn;
}
@JsonProperty
public void setCommitOnReturn(boolean commitOnReturn) {
this.commitOnReturn = commitOnReturn;
}
@JsonProperty
public void setRollbackOnReturn(boolean rollbackOnReturn) {
this.rollbackOnReturn = rollbackOnReturn;
}
@JsonProperty
@Nullable
public Boolean getAutoCommitByDefault() {
return autoCommitByDefault;
}
@JsonProperty
public void setAutoCommitByDefault(Boolean autoCommit) {
this.autoCommitByDefault = autoCommit;
}
@JsonProperty
@Nullable
public String getDefaultCatalog() {
return defaultCatalog;
}
@JsonProperty
public void setDefaultCatalog(String defaultCatalog) {
this.defaultCatalog = defaultCatalog;
}
@JsonProperty
@Nullable
public Boolean getReadOnlyByDefault() {
return readOnlyByDefault;
}
@JsonProperty
public void setReadOnlyByDefault(Boolean readOnlyByDefault) {
this.readOnlyByDefault = readOnlyByDefault;
}
@JsonProperty
public TransactionIsolation getDefaultTransactionIsolation() {
return defaultTransactionIsolation;
}
@JsonProperty
public void setDefaultTransactionIsolation(TransactionIsolation isolation) {
this.defaultTransactionIsolation = isolation;
}
@JsonProperty
public boolean getUseFairQueue() {
return useFairQueue;
}
@JsonProperty
public void setUseFairQueue(boolean fair) {
this.useFairQueue = fair;
}
@JsonProperty
public int getInitialSize() {
return initialSize;
}
@JsonProperty
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
@JsonProperty
@Nullable
public String getInitializationQuery() {
return initializationQuery;
}
@JsonProperty
public void setInitializationQuery(String query) {
this.initializationQuery = query;
}
@JsonProperty
public boolean getLogAbandonedConnections() {
return logAbandonedConnections;
}
@JsonProperty
public void setLogAbandonedConnections(boolean log) {
this.logAbandonedConnections = log;
}
@JsonProperty
public boolean getLogValidationErrors() {
return logValidationErrors;
}
@JsonProperty
public void setLogValidationErrors(boolean log) {
this.logValidationErrors = log;
}
@JsonProperty
public Optional<Duration> getMaxConnectionAge() {
return Optional.ofNullable(maxConnectionAge);
}
@JsonProperty
public void setMaxConnectionAge(Duration age) {
this.maxConnectionAge = age;
}
@JsonProperty
public Duration getMinIdleTime() {
return minIdleTime;
}
@JsonProperty
public void setMinIdleTime(Duration time) {
this.minIdleTime = time;
}
@JsonProperty
public boolean getCheckConnectionOnBorrow() {
return checkConnectionOnBorrow;
}
@JsonProperty
public void setCheckConnectionOnBorrow(boolean checkConnectionOnBorrow) {
this.checkConnectionOnBorrow = checkConnectionOnBorrow;
}
@JsonProperty
public boolean getCheckConnectionOnConnect() {
return checkConnectionOnConnect;
}
@JsonProperty
public void setCheckConnectionOnConnect(boolean checkConnectionOnConnect) {
this.checkConnectionOnConnect = checkConnectionOnConnect;
}
@JsonProperty
public boolean getCheckConnectionOnReturn() {
return checkConnectionOnReturn;
}
@JsonProperty
public void setCheckConnectionOnReturn(boolean checkConnectionOnReturn) {
this.checkConnectionOnReturn = checkConnectionOnReturn;
}
@JsonProperty
public Duration getEvictionInterval() {
return evictionInterval;
}
@JsonProperty
public void setEvictionInterval(Duration interval) {
this.evictionInterval = interval;
}
@JsonProperty
public Duration getValidationInterval() {
return validationInterval;
}
@JsonProperty
public void setValidationInterval(Duration validationInterval) {
this.validationInterval = validationInterval;
}
@Override
@JsonProperty
public Optional<Duration> getValidationQueryTimeout() {
return Optional.ofNullable(validationQueryTimeout);
}
@JsonProperty
public Optional<String> getValidatorClassName() {
return validatorClassName;
}
@JsonProperty
public void setValidatorClassName(Optional<String> validatorClassName) {
this.validatorClassName = validatorClassName;
}
@Override
@Deprecated
@JsonIgnore
public Optional<Duration> getHealthCheckValidationTimeout() {
return getValidationQueryTimeout();
}
@JsonProperty
public void setValidationQueryTimeout(Duration validationQueryTimeout) {
this.validationQueryTimeout = validationQueryTimeout;
}
@JsonProperty
public boolean isRemoveAbandoned() {
return removeAbandoned;
}
@JsonProperty
public void setRemoveAbandoned(boolean removeAbandoned) {
this.removeAbandoned = removeAbandoned;
}
@JsonProperty
public Duration getRemoveAbandonedTimeout() {
return removeAbandonedTimeout;
}
@JsonProperty
public void setRemoveAbandonedTimeout(Duration removeAbandonedTimeout) {
this.removeAbandonedTimeout = Objects.requireNonNull(removeAbandonedTimeout);
}
@JsonProperty
public Optional<String> getJdbcInterceptors() {
return jdbcInterceptors;
}
@JsonProperty
public void setJdbcInterceptors(Optional<String> jdbcInterceptors) {
this.jdbcInterceptors = jdbcInterceptors;
}
@JsonProperty
public boolean isIgnoreExceptionOnPreLoad() {
return ignoreExceptionOnPreLoad;
}
@JsonProperty
public void setIgnoreExceptionOnPreLoad(boolean ignoreExceptionOnPreLoad) {
this.ignoreExceptionOnPreLoad = ignoreExceptionOnPreLoad;
}
@Override
public void asSingleConnectionPool() {
minSize = 1;
maxSize = 1;
initialSize = 1;
}
@Override
public ManagedDataSource build(MetricRegistry metricRegistry, String name) {
final Properties properties = new Properties();
for (Map.Entry<String, String> property : this.properties.entrySet()) {
properties.setProperty(property.getKey(), property.getValue());
}
final PoolProperties poolConfig = new PoolProperties();
poolConfig.setAbandonWhenPercentageFull(abandonWhenPercentageFull);
poolConfig.setAlternateUsernameAllowed(alternateUsernamesAllowed);
poolConfig.setCommitOnReturn(commitOnReturn);
poolConfig.setRollbackOnReturn(rollbackOnReturn);
poolConfig.setDbProperties(properties);
poolConfig.setDefaultAutoCommit(autoCommitByDefault);
poolConfig.setDefaultCatalog(defaultCatalog);
poolConfig.setDefaultReadOnly(readOnlyByDefault);
poolConfig.setDefaultTransactionIsolation(defaultTransactionIsolation.get());
poolConfig.setDriverClassName(driverClass);
poolConfig.setFairQueue(useFairQueue);
poolConfig.setIgnoreExceptionOnPreLoad(ignoreExceptionOnPreLoad);
poolConfig.setInitialSize(initialSize);
poolConfig.setInitSQL(initializationQuery);
poolConfig.setLogAbandoned(logAbandonedConnections);
poolConfig.setLogValidationErrors(logValidationErrors);
poolConfig.setMaxActive(maxSize);
poolConfig.setMaxIdle(maxSize);
poolConfig.setMinIdle(minSize);
if (getMaxConnectionAge().isPresent()) {
poolConfig.setMaxAge(getMaxConnectionAge().get().toMilliseconds());
}
poolConfig.setMaxWait((int) maxWaitForConnection.toMilliseconds());
poolConfig.setMinEvictableIdleTimeMillis((int) minIdleTime.toMilliseconds());
poolConfig.setName(name);
poolConfig.setUrl(url);
poolConfig.setUsername(user);
poolConfig.setPassword(user != null && password == null ? "" : password);
poolConfig.setRemoveAbandoned(removeAbandoned);
poolConfig.setRemoveAbandonedTimeout(Ints.saturatedCast(removeAbandonedTimeout.toSeconds()));
poolConfig.setTestWhileIdle(checkConnectionWhileIdle);
poolConfig.setValidationQuery(validationQuery);
poolConfig.setTestOnBorrow(checkConnectionOnBorrow);
poolConfig.setTestOnConnect(checkConnectionOnConnect);
poolConfig.setTestOnReturn(checkConnectionOnReturn);
poolConfig.setTimeBetweenEvictionRunsMillis((int) evictionInterval.toMilliseconds());
poolConfig.setValidationInterval(validationInterval.toMilliseconds());
if (getValidationQueryTimeout().isPresent()) {
poolConfig.setValidationQueryTimeout((int) getValidationQueryTimeout().get().toSeconds());
}
validatorClassName.ifPresent(poolConfig::setValidatorClassName);
jdbcInterceptors.ifPresent(poolConfig::setJdbcInterceptors);
return new ManagedPooledDataSource(poolConfig, metricRegistry);
}
}