All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.dropwizard.db.DataSourceFactory Maven / Gradle / Ivy

There is a newer version: 5.0.0-rc.1
Show newest version
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 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 {@link ManagedDataSource}s.
 * 

* Configuration Parameters: *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
NameDefaultDescription
{@code driverClass}REQUIREDThe full name of the JDBC driver class.
{@code url}REQUIREDThe URL of the server.
{@code user}noneThe username used to connect to the server.
{@code password}noneThe password used to connect to the server.
{@code removeAbandoned}{@code false} * 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. *
{@code removeAbandonedTimeout}60 seconds * The time before a database connection can be considered abandoned. *
{@code 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 * {@code abandonWhenPercentageFull}. The value should be between 0-100. *
{@code alternateUsernamesAllowed}{@code false} * 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. *
{@code commitOnReturn}{@code false} * Set to true if you want the connection pool to commit any pending transaction when a * connection is returned. *
{@code rollbackOnReturn}{@code false} * Set to true if you want the connection pool to rollback any pending transaction when a * connection is returned. *
{@code autoCommitByDefault}JDBC driver's defaultThe default auto-commit state of the connections.
{@code readOnlyByDefault}JDBC driver's defaultThe default read-only state of the connections.
{@code properties}noneAny additional JDBC driver parameters.
{@code defaultCatalog}noneThe default catalog to use for the connections.
{@code defaultTransactionIsolation}JDBC driver default * 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}. *
{@code useFairQueue}{@code true} * If {@code true}, calls to {@code getConnection} are handled in a FIFO manner. *
{@code 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 {@link #minSize} * must also be set to zero. *
{@code minSize}10 * The minimum size of the connection pool. *
{@code maxSize}100 * The maximum size of the connection pool. *
{@code initializationQuery}none * A custom query to be run when a connection is first created. *
{@code logAbandonedConnections}{@code false} * If {@code true}, logs stack traces of abandoned connections. *
{@code logValidationErrors}{@code false} * If {@code true}, logs errors when connections fail validation. *
{@code maxConnectionAge}none * If set, connections which have been open for longer than {@code maxConnectionAge} are * closed when returned. *
{@code maxWaitForConnection}30 seconds * If a request for a connection is blocked for longer than this period, an exception * will be thrown. *
{@code minIdleTime}1 minute * The minimum amount of time an connection must sit idle in the pool before it is * eligible for eviction. *
{@code validationQuery}{@code 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. *
{@code validationQueryTimeout}none * The timeout before a connection validation queries fail. *
{@code checkConnectionWhileIdle}{@code true} * Set to true if query validation should take place while the connection is idle. *
{@code checkConnectionOnBorrow}{@code 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. *
{@code checkConnectionOnConnect}{@code false} * 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. *
{@code checkConnectionOnReturn}{@code 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. *
{@code autoCommentsEnabled}{@code true} * Whether or not ORMs should automatically add comments. *
{@code evictionInterval}5 seconds * The amount of time to sleep between runs of the idle connection validation, abandoned * cleaner and idle pool resizing. *
{@code validationInterval}30 seconds * To avoid excess validation, only run validation once every interval. *
{@code validatorClassName}(none) * Name of a class of a custom {@link org.apache.tomcat.jdbc.pool.Validator} * implementation, which will be used for validating connections. *
*/ 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; } } @NotNull private String driverClass = null; @Min(0) @Max(100) private int abandonWhenPercentageFull = 0; private boolean alternateUsernamesAllowed = false; private boolean commitOnReturn = false; private boolean rollbackOnReturn = false; private Boolean autoCommitByDefault; private Boolean readOnlyByDefault; private String user = null; private String password = null; @NotNull private String url = null; @NotNull private Map properties = new LinkedHashMap<>(); 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; private String initializationQuery; private boolean logAbandonedConnections = false; private boolean logValidationErrors = false; @MinDuration(value = 1, unit = TimeUnit.SECONDS) private Duration maxConnectionAge; @NotNull @MinDuration(value = 1, unit = TimeUnit.SECONDS) private Duration maxWaitForConnection = Duration.seconds(30); @NotNull @MinDuration(value = 1, unit = TimeUnit.SECONDS) private Duration minIdleTime = Duration.minutes(1); @NotNull private String validationQuery = "/* Health Check */ SELECT 1"; @MinDuration(value = 1, unit = TimeUnit.SECONDS) 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(1) private Duration evictionInterval = Duration.seconds(5); @NotNull @MinDuration(1) private Duration validationInterval = Duration.seconds(30); private Optional validatorClassName = Optional.empty(); private boolean removeAbandoned = false; @NotNull @MinDuration(1) private Duration removeAbandonedTimeout = Duration.seconds(60L); @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 public String getUser() { return user; } @JsonProperty public void setUser(String user) { this.user = user; } @JsonProperty 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 getProperties() { return properties; } @JsonProperty public void setProperties(Map 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 public Boolean getAutoCommitByDefault() { return autoCommitByDefault; } @JsonProperty public void setAutoCommitByDefault(Boolean autoCommit) { this.autoCommitByDefault = autoCommit; } @JsonProperty public String getDefaultCatalog() { return defaultCatalog; } @JsonProperty public void setDefaultCatalog(String defaultCatalog) { this.defaultCatalog = defaultCatalog; } @JsonProperty 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 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 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 getValidationQueryTimeout() { return Optional.ofNullable(validationQueryTimeout); } @JsonProperty public Optional getValidatorClassName() { return validatorClassName; } @JsonProperty public void setValidatorClassName(Optional validatorClassName) { this.validatorClassName = validatorClassName; } @Override @Deprecated @JsonIgnore public Optional 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); } @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 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.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(maxConnectionAge.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) validationQueryTimeout.toSeconds()); } if (validatorClassName.isPresent()) { poolConfig.setValidatorClassName(validatorClassName.get()); } return new ManagedPooledDataSource(poolConfig, metricRegistry); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy