package com.vladmihalcea.flexypool.config; import com.vladmihalcea.flexypool.adaptor.PoolAdapter; import com.vladmihalcea.flexypool.adaptor.PoolAdapterFactory; import com.vladmihalcea.flexypool.common.ConfigurationProperties; import com.vladmihalcea.flexypool.connection.ConnectionDecoratorFactoryResolver; import com.vladmihalcea.flexypool.connection.ConnectionProxyFactory; import com.vladmihalcea.flexypool.event.EventListenerResolver; import com.vladmihalcea.flexypool.event.EventPublisher; import com.vladmihalcea.flexypool.metric.Metrics; import com.vladmihalcea.flexypool.metric.MetricsFactory; import com.vladmihalcea.flexypool.metric.MetricsFactoryResolver; import javax.sql.DataSource; import java.util.concurrent.TimeUnit; /** * <code>Configuration</code> defines all required external associations for a given FlexyPool instance. * An instance is retrieved through the {@link com.vladmihalcea.flexypool.config.Configuration.Builder} which takes care of the actual order of setting required dependencies. * * @author Vlad Mihalcea * @since 1.0 */ public final class Configuration<T extends DataSource> extends ConfigurationProperties<T, Metrics, PoolAdapter<T>> { public static final long DEFAULT_METRIC_LOG_REPORTER_MILLIS = TimeUnit.MINUTES.toMillis(5); /** * A Factory for configuration data. * * @param <T> the data source type */ public static class Builder<T extends DataSource> { private final String uniqueName; private final T targetDataSource; private final PoolAdapterFactory<T> poolAdapterFactory; private MetricsFactory metricsFactory = MetricsFactoryResolver.INSTANCE.resolve(); private ConnectionProxyFactory connectionProxyFactory = ConnectionDecoratorFactoryResolver.INSTANCE.resolve(); private boolean jmxEnabled = true; private boolean jmxAutoStart = false; private long metricLogReporterMillis = DEFAULT_METRIC_LOG_REPORTER_MILLIS; private EventListenerResolver eventListenerResolver; private long connectionAcquireTimeThresholdMillis = Long.MAX_VALUE; private long connectionLeaseTimeThresholdMillis = Long.MAX_VALUE; /** * Construct the builder with the mandatory associations. * * @param uniqueName the configuration unique name (required if you have multiple flexypool pools running) * @param targetDataSource target data source * @param poolAdapterFactory pool adaptor factory */ public Builder(String uniqueName, T targetDataSource, PoolAdapterFactory<T> poolAdapterFactory) { this.uniqueName = uniqueName; this.targetDataSource = targetDataSource; this.poolAdapterFactory = poolAdapterFactory; } /** * Set metrics factory * * @param metricsFactory metrics factory * @return this {@link com.vladmihalcea.flexypool.config.Configuration.Builder} */ public Builder<T> setMetricsFactory(MetricsFactory metricsFactory) { this.metricsFactory = metricsFactory; return this; } /** * Set connection proxy factory. * * @param connectionProxyFactory connection proxy factory * @return this {@link com.vladmihalcea.flexypool.config.Configuration.Builder} */ public Builder<T> setConnectionProxyFactory(ConnectionProxyFactory connectionProxyFactory) { this.connectionProxyFactory = connectionProxyFactory; return this; } /** * Enable/Disable jmx * * @param enableJmx jmx enabling * @return this {@link com.vladmihalcea.flexypool.config.Configuration.Builder} */ public Builder<T> setJmxEnabled(boolean enableJmx) { this.jmxEnabled = enableJmx; return this; } /** * Enable/Disable jmx auto-start * * @param jmxAutoStart jmx auto-started * @return this {@link com.vladmihalcea.flexypool.config.Configuration.Builder} */ public Builder<T> setJmxAutoStart(boolean jmxAutoStart) { this.jmxAutoStart = jmxAutoStart; return this; } /** * Set metric log report millis * * @param metricLogReporterMillis millis between two consecutive log reports * @return this {@link com.vladmihalcea.flexypool.config.Configuration.Builder} */ public Builder<T> setMetricLogReporterMillis(long metricLogReporterMillis) { this.metricLogReporterMillis = metricLogReporterMillis; return this; } /** * Set the event listener resolver * * @param eventListenerResolver event listener resolver * @return this {@link com.vladmihalcea.flexypool.config.Configuration.Builder} */ public Builder<T> setEventListenerResolver(EventListenerResolver eventListenerResolver) { this.eventListenerResolver = eventListenerResolver; return this; } /** * Set the connection acquire time threshold millis * * @param connectionAcquireTimeThresholdMillis connection acquire time threshold millis * @return this {@link com.vladmihalcea.flexypool.config.Configuration.Builder} */ public Builder<T> setConnectionAcquireTimeThresholdMillis(Long connectionAcquireTimeThresholdMillis) { if (connectionAcquireTimeThresholdMillis != null) { this.connectionAcquireTimeThresholdMillis = connectionAcquireTimeThresholdMillis; } return this; } /** * Set the connection lease time threshold millis * * @param connectionLeaseTimeThresholdMillis connection lease time threshold millis * @return this {@link com.vladmihalcea.flexypool.config.Configuration.Builder} */ public Builder<T> setConnectionLeaseTimeThresholdMillis(Long connectionLeaseTimeThresholdMillis) { if (connectionLeaseTimeThresholdMillis != null) { this.connectionLeaseTimeThresholdMillis = connectionLeaseTimeThresholdMillis; } return this; } /** * Build the configuration object. * * @return configuration */ public Configuration<T> build() { EventPublisher eventPublisher = EventPublisher.newInstance(eventListenerResolver); Configuration<T> configuration = new Configuration<T>(uniqueName, targetDataSource, eventPublisher); configuration.setJmxEnabled(jmxEnabled); configuration.setJmxAutoStart(jmxAutoStart); configuration.setMetricLogReporterMillis(metricLogReporterMillis); configuration.setConnectionAcquireTimeThresholdMillis(connectionAcquireTimeThresholdMillis); configuration.setConnectionLeaseTimeThresholdMillis(connectionLeaseTimeThresholdMillis); configuration.metrics = metricsFactory.newInstance(configuration); configuration.poolAdapter = poolAdapterFactory.newInstance(configuration); configuration.connectionProxyFactory = connectionProxyFactory; return configuration; } } private final T targetDataSource; private Metrics metrics; private PoolAdapter<T> poolAdapter; private ConnectionProxyFactory connectionProxyFactory; private Configuration(String uniqueName, T targetDataSource, EventPublisher eventPublisher) { super(uniqueName, eventPublisher); this.targetDataSource = targetDataSource; } /** * Get the target data source * * @return target data source */ public T getTargetDataSource() { return targetDataSource; } /** * Get the associated {@link com.vladmihalcea.flexypool.metric.Metrics} * * @return {@link com.vladmihalcea.flexypool.metric.Metrics} */ public Metrics getMetrics() { return metrics; } /** * Get the associated {@link com.vladmihalcea.flexypool.adaptor.PoolAdapter} * * @return {@link com.vladmihalcea.flexypool.adaptor.PoolAdapter} */ public PoolAdapter<T> getPoolAdapter() { return poolAdapter; } /** * Get the associated {@link com.vladmihalcea.flexypool.connection.ConnectionProxyFactory} * * @return {@link com.vladmihalcea.flexypool.connection.ConnectionProxyFactory} */ public ConnectionProxyFactory getConnectionProxyFactory() { return connectionProxyFactory; } }