diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java index d918470ba615..e1c5165d4acb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations.java @@ -43,6 +43,7 @@ * * @author Mark Paluch * @author Stephane Nicoll + * @author Rodolpho S. Couto */ abstract class ConnectionFactoryConfigurations { @@ -69,7 +70,11 @@ ConnectionPool connectionFactory(R2dbcProperties properties, ResourceLoader reso customizers.orderedStream().collect(Collectors.toList())); R2dbcProperties.Pool pool = properties.getPool(); ConnectionPoolConfiguration.Builder builder = ConnectionPoolConfiguration.builder(connectionFactory) - .maxSize(pool.getMaxSize()).initialSize(pool.getInitialSize()).maxIdleTime(pool.getMaxIdleTime()); + .initialSize(pool.getInitialSize()).maxSize(pool.getMaxSize()).maxIdleTime(pool.getMaxIdleTime()) + .maxLifeTime(pool.getMaxLifeTime()).maxAcquireTime(pool.getMaxAcquireTime()) + .maxCreateConnectionTime(pool.getMaxCreateConnectionTime()) + .validationDepth(pool.getValidationDepth()); + if (StringUtils.hasText(pool.getValidationQuery())) { builder.validationQuery(pool.getValidationQuery()); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java index 7792e673921e..5f61fdd96951 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcProperties.java @@ -21,6 +21,8 @@ import java.util.Map; import java.util.UUID; +import io.r2dbc.spi.ValidationDepth; + import org.springframework.boot.context.properties.ConfigurationProperties; /** @@ -29,6 +31,7 @@ * @author Mark Paluch * @author Andreas Killaitis * @author Stephane Nicoll + * @author Rodolpho S. Couto * @since 2.3.0 */ @ConfigurationProperties(prefix = "spring.r2dbc") @@ -138,6 +141,21 @@ public static class Pool { */ private Duration maxIdleTime = Duration.ofMinutes(30); + /** + * Max lifetime. + */ + private Duration maxLifeTime = Duration.ofMinutes(0L); + + /** + * Max acquire time. + */ + private Duration maxAcquireTime = Duration.ofMinutes(0L); + + /** + * Max create connection time. + */ + private Duration maxCreateConnectionTime = Duration.ofMinutes(0L); + /** * Initial connection pool size. */ @@ -153,6 +171,11 @@ public static class Pool { */ private String validationQuery; + /** + * Validation depth. + */ + private ValidationDepth validationDepth = ValidationDepth.LOCAL; + public Duration getMaxIdleTime() { return this.maxIdleTime; } @@ -161,6 +184,30 @@ public void setMaxIdleTime(Duration maxIdleTime) { this.maxIdleTime = maxIdleTime; } + public Duration getMaxLifeTime() { + return this.maxLifeTime; + } + + public void setMaxLifeTime(Duration maxLifeTime) { + this.maxLifeTime = maxLifeTime; + } + + public Duration getMaxAcquireTime() { + return this.maxAcquireTime; + } + + public void setMaxAcquireTime(Duration maxAcquireTime) { + this.maxAcquireTime = maxAcquireTime; + } + + public Duration getMaxCreateConnectionTime() { + return this.maxCreateConnectionTime; + } + + public void setMaxCreateConnectionTime(Duration maxCreateConnectionTime) { + this.maxCreateConnectionTime = maxCreateConnectionTime; + } + public int getInitialSize() { return this.initialSize; } @@ -185,6 +232,14 @@ public void setValidationQuery(String validationQuery) { this.validationQuery = validationQuery; } + public ValidationDepth getValidationDepth() { + return this.validationDepth; + } + + public void setValidationDepth(ValidationDepth validationDepth) { + this.validationDepth = validationDepth; + } + } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 4979e811881b..eee18698f351 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -1471,6 +1471,10 @@ "type": "java.lang.Boolean", "description": "Whether pooling is enabled. Enabled automatically if \"r2dbc-pool\" is on the classpath." }, + { + "name": "spring.r2dbc.pool.validationDepth", + "defaultValue": "local" + }, { "name": "spring.rabbitmq.cache.connection.mode", "defaultValue": "channel" diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java index 5e8a3f5998ab..bb82c30a85ce 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/r2dbc/R2dbcAutoConfigurationTests.java @@ -18,6 +18,7 @@ import java.net.URL; import java.net.URLClassLoader; +import java.time.Duration; import java.util.UUID; import java.util.function.Function; @@ -28,6 +29,7 @@ import io.r2dbc.pool.PoolMetrics; import io.r2dbc.spi.ConnectionFactory; import io.r2dbc.spi.Option; +import io.r2dbc.spi.ValidationDepth; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanCreationException; @@ -61,11 +63,27 @@ void configureWithUrlCreateConnectionPoolByDefault() { @Test void configureWithUrlAndPoolPropertiesApplyProperties() { - this.contextRunner.withPropertyValues("spring.r2dbc.url:r2dbc:h2:mem:///" + randomDatabaseName(), - "spring.r2dbc.pool.max-size=15").run((context) -> { - assertThat(context).hasSingleBean(ConnectionFactory.class).hasSingleBean(ConnectionPool.class); + this.contextRunner + .withPropertyValues("spring.r2dbc.url:r2dbc:h2:mem:///" + randomDatabaseName(), + "spring.r2dbc.pool.initial-size=5", "spring.r2dbc.pool.max-size=15", + "spring.r2dbc.pool.max-idle-time=1ms", "spring.r2dbc.pool.max-life-time=2s", + "spring.r2dbc.pool.max-acquire-time=3m", "spring.r2dbc.pool.max-create-connection-time=4h", + "spring.r2dbc.pool.validation-query=SELECT 1", "spring.r2dbc.pool.validation-depth=remote") + .run((context) -> { + assertThat(context).hasSingleBean(ConnectionFactory.class).hasSingleBean(ConnectionPool.class) + .hasSingleBean(R2dbcProperties.class); PoolMetrics poolMetrics = context.getBean(ConnectionPool.class).getMetrics().get(); assertThat(poolMetrics.getMaxAllocatedSize()).isEqualTo(15); + + R2dbcProperties properties = context.getBean(R2dbcProperties.class); + assertThat(properties.getPool().getInitialSize()).isEqualTo(5); + assertThat(properties.getPool().getMaxSize()).isEqualTo(15); + assertThat(properties.getPool().getMaxIdleTime()).isEqualTo(Duration.ofMillis(1)); + assertThat(properties.getPool().getMaxLifeTime()).isEqualTo(Duration.ofSeconds(2)); + assertThat(properties.getPool().getMaxAcquireTime()).isEqualTo(Duration.ofMinutes(3)); + assertThat(properties.getPool().getMaxCreateConnectionTime()).isEqualTo(Duration.ofHours(4)); + assertThat(properties.getPool().getValidationQuery()).isEqualTo("SELECT 1"); + assertThat(properties.getPool().getValidationDepth()).isEqualTo(ValidationDepth.REMOTE); }); }