Merge pull request #21219 from rodolphocouto

* pr/21219:
  Polish "Add additional properties to configure R2DBC pool"
  Add additional properties to configure R2DBC pool

Closes gh-21219
pull/22329/head
Stephane Nicoll 4 years ago
commit 7fd2284b22

@ -29,6 +29,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition; import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.ConditionContext;
@ -43,6 +44,7 @@ import org.springframework.util.StringUtils;
* *
* @author Mark Paluch * @author Mark Paluch
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Rodolpho S. Couto
*/ */
abstract class ConnectionFactoryConfigurations { abstract class ConnectionFactoryConfigurations {
@ -68,11 +70,16 @@ abstract class ConnectionFactoryConfigurations {
ConnectionFactory connectionFactory = createConnectionFactory(properties, resourceLoader.getClassLoader(), ConnectionFactory connectionFactory = createConnectionFactory(properties, resourceLoader.getClassLoader(),
customizers.orderedStream().collect(Collectors.toList())); customizers.orderedStream().collect(Collectors.toList()));
R2dbcProperties.Pool pool = properties.getPool(); R2dbcProperties.Pool pool = properties.getPool();
ConnectionPoolConfiguration.Builder builder = ConnectionPoolConfiguration.builder(connectionFactory) PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
.maxSize(pool.getMaxSize()).initialSize(pool.getInitialSize()).maxIdleTime(pool.getMaxIdleTime()); ConnectionPoolConfiguration.Builder builder = ConnectionPoolConfiguration.builder(connectionFactory);
if (StringUtils.hasText(pool.getValidationQuery())) { map.from(pool.getMaxIdleTime()).to(builder::maxIdleTime);
builder.validationQuery(pool.getValidationQuery()); map.from(pool.getMaxLifeTime()).to(builder::maxLifeTime);
} map.from(pool.getMaxAcquireTime()).to(builder::maxAcquireTime);
map.from(pool.getMaxCreateConnectionTime()).to(builder::maxCreateConnectionTime);
map.from(pool.getInitialSize()).to(builder::initialSize);
map.from(pool.getMaxSize()).to(builder::maxSize);
map.from(pool.getValidationQuery()).whenHasText().to(builder::validationQuery);
map.from(pool.getValidationDepth()).to(builder::validationDepth);
return new ConnectionPool(builder.build()); return new ConnectionPool(builder.build());
} }

@ -21,6 +21,8 @@ import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import io.r2dbc.spi.ValidationDepth;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
/** /**
@ -29,6 +31,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* @author Mark Paluch * @author Mark Paluch
* @author Andreas Killaitis * @author Andreas Killaitis
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Rodolpho S. Couto
* @since 2.3.0 * @since 2.3.0
*/ */
@ConfigurationProperties(prefix = "spring.r2dbc") @ConfigurationProperties(prefix = "spring.r2dbc")
@ -138,6 +141,23 @@ public class R2dbcProperties {
*/ */
private Duration maxIdleTime = Duration.ofMinutes(30); private Duration maxIdleTime = Duration.ofMinutes(30);
/**
* Maximum lifetime of a connection in the pool. By default, connections have an
* infinite lifetime.
*/
private Duration maxLifeTime;
/**
* Maximum time to acquire a connection from the pool. By default, wait
* indefinitely.
*/
private Duration maxAcquireTime;
/**
* Maximum time to wait to create a new connection. By default, wait indefinitely.
*/
private Duration maxCreateConnectionTime;
/** /**
* Initial connection pool size. * Initial connection pool size.
*/ */
@ -153,6 +173,11 @@ public class R2dbcProperties {
*/ */
private String validationQuery; private String validationQuery;
/**
* Validation depth.
*/
private ValidationDepth validationDepth = ValidationDepth.LOCAL;
public Duration getMaxIdleTime() { public Duration getMaxIdleTime() {
return this.maxIdleTime; return this.maxIdleTime;
} }
@ -161,6 +186,30 @@ public class R2dbcProperties {
this.maxIdleTime = 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() { public int getInitialSize() {
return this.initialSize; return this.initialSize;
} }
@ -185,6 +234,14 @@ public class R2dbcProperties {
this.validationQuery = validationQuery; this.validationQuery = validationQuery;
} }
public ValidationDepth getValidationDepth() {
return this.validationDepth;
}
public void setValidationDepth(ValidationDepth validationDepth) {
this.validationDepth = validationDepth;
}
} }
} }

@ -1468,6 +1468,10 @@
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
"description": "Whether pooling is enabled. Enabled automatically if \"r2dbc-pool\" is on the classpath." "description": "Whether pooling is enabled. Enabled automatically if \"r2dbc-pool\" is on the classpath."
}, },
{
"name": "spring.r2dbc.pool.validation-depth",
"defaultValue": "local"
},
{ {
"name": "spring.rabbitmq.cache.connection.mode", "name": "spring.rabbitmq.cache.connection.mode",
"defaultValue": "channel" "defaultValue": "channel"

@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.r2dbc;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.time.Duration;
import java.util.UUID; import java.util.UUID;
import java.util.function.Function; import java.util.function.Function;
@ -62,10 +63,24 @@ class R2dbcAutoConfigurationTests {
@Test @Test
void configureWithUrlAndPoolPropertiesApplyProperties() { void configureWithUrlAndPoolPropertiesApplyProperties() {
this.contextRunner.withPropertyValues("spring.r2dbc.url:r2dbc:h2:mem:///" + randomDatabaseName(), this.contextRunner.withPropertyValues("spring.r2dbc.url:r2dbc:h2:mem:///" + randomDatabaseName(),
"spring.r2dbc.pool.max-size=15").run((context) -> { "spring.r2dbc.pool.max-size=15", "spring.r2dbc.pool.max-acquire-time=3m").run((context) -> {
assertThat(context).hasSingleBean(ConnectionFactory.class).hasSingleBean(ConnectionPool.class); assertThat(context).hasSingleBean(ConnectionFactory.class).hasSingleBean(ConnectionPool.class)
PoolMetrics poolMetrics = context.getBean(ConnectionPool.class).getMetrics().get(); .hasSingleBean(R2dbcProperties.class);
ConnectionPool connectionPool = context.getBean(ConnectionPool.class);
PoolMetrics poolMetrics = connectionPool.getMetrics().get();
assertThat(poolMetrics.getMaxAllocatedSize()).isEqualTo(15); assertThat(poolMetrics.getMaxAllocatedSize()).isEqualTo(15);
assertThat(connectionPool).hasFieldOrPropertyWithValue("maxAcquireTime", Duration.ofMinutes(3));
});
}
@Test
void configureWithUrlAndDefaultDoNotOverrideDefaultTimeouts() {
this.contextRunner.withPropertyValues("spring.r2dbc.url:r2dbc:h2:mem:///" + randomDatabaseName())
.run((context) -> {
assertThat(context).hasSingleBean(ConnectionFactory.class).hasSingleBean(ConnectionPool.class)
.hasSingleBean(R2dbcProperties.class);
ConnectionPool connectionPool = context.getBean(ConnectionPool.class);
assertThat(connectionPool).hasFieldOrPropertyWithValue("maxAcquireTime", Duration.ZERO);
}); });
} }

Loading…
Cancel
Save