Migrate to auto-configurations to PropertyMapper

Update auto-configuration classes that have extensive property mapping
code to make use of the new `PropertyMapper` utility.

Fixes gh-9018
pull/11364/head
Phillip Webb 7 years ago
parent 241a7086c0
commit 5e9cfea5a8

@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.amqp;
import org.springframework.amqp.rabbit.config.DirectRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.boot.context.properties.PropertyMapper;
/**
* Configure {@link DirectRabbitListenerContainerFactoryConfigurer} with sensible
@ -33,12 +34,12 @@ public final class DirectRabbitListenerContainerFactoryConfigurer extends
@Override
public void configure(DirectRabbitListenerContainerFactory factory,
ConnectionFactory connectionFactory) {
PropertyMapper map = PropertyMapper.get();
RabbitProperties.DirectContainer config = getRabbitProperties().getListener()
.getDirect();
configure(factory, connectionFactory, config);
if (config.getConsumersPerQueue() != null) {
factory.setConsumersPerQueue(config.getConsumersPerQueue());
}
map.from(config::getConsumersPerQueue).whenNonNull()
.to(factory::setConsumersPerQueue);
}
}

@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure.amqp;
import java.time.Duration;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.AmqpAdmin;
@ -33,6 +35,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@ -76,6 +79,7 @@ import org.springframework.retry.support.RetryTemplate;
* @author Josh Long
* @author Stephane Nicoll
* @author Gary Russell
* @author Phillip Webb
*/
@Configuration
@ConditionalOnClass({ RabbitTemplate.class, Channel.class })
@ -88,66 +92,55 @@ public class RabbitAutoConfiguration {
protected static class RabbitConnectionFactoryCreator {
@Bean
public CachingConnectionFactory rabbitConnectionFactory(RabbitProperties config)
throws Exception {
public CachingConnectionFactory rabbitConnectionFactory(
RabbitProperties properties) throws Exception {
PropertyMapper map = PropertyMapper.get();
CachingConnectionFactory factory = new CachingConnectionFactory(
getRabbitConnectionFactoryBean(properties).getObject());
map.from(properties::determineAddresses).to(factory::setAddresses);
map.from(properties::isPublisherConfirms).to(factory::setPublisherConfirms);
map.from(properties::isPublisherReturns).to(factory::setPublisherReturns);
RabbitProperties.Cache.Channel channel = properties.getCache().getChannel();
map.from(channel::getSize).whenNonNull().to(factory::setChannelCacheSize);
map.from(channel::getCheckoutTimeout).whenNonNull()
.to(factory::setChannelCheckoutTimeout);
RabbitProperties.Cache.Connection connection = properties.getCache()
.getConnection();
map.from(connection::getMode).whenNonNull().to(factory::setCacheMode);
map.from(connection::getSize).whenNonNull()
.to(factory::setConnectionCacheSize);
return factory;
}
private RabbitConnectionFactoryBean getRabbitConnectionFactoryBean(
RabbitProperties properties) throws Exception {
PropertyMapper map = PropertyMapper.get();
RabbitConnectionFactoryBean factory = new RabbitConnectionFactoryBean();
if (config.determineHost() != null) {
factory.setHost(config.determineHost());
}
factory.setPort(config.determinePort());
if (config.determineUsername() != null) {
factory.setUsername(config.determineUsername());
}
if (config.determinePassword() != null) {
factory.setPassword(config.determinePassword());
}
if (config.determineVirtualHost() != null) {
factory.setVirtualHost(config.determineVirtualHost());
}
if (config.getRequestedHeartbeat() != null) {
factory.setRequestedHeartbeat(
(int) config.getRequestedHeartbeat().getSeconds());
}
RabbitProperties.Ssl ssl = config.getSsl();
map.from(properties::determineHost).whenNonNull().to(factory::setHost);
map.from(properties::determinePort).to(factory::setPort);
map.from(properties::determineUsername).whenNonNull()
.to(factory::setUsername);
map.from(properties::determinePassword).whenNonNull()
.to(factory::setPassword);
map.from(properties::determineVirtualHost).whenNonNull()
.to(factory::setVirtualHost);
map.from(properties::getRequestedHeartbeat).whenNonNull()
.asInt(Duration::getSeconds).to(factory::setRequestedHeartbeat);
RabbitProperties.Ssl ssl = properties.getSsl();
if (ssl.isEnabled()) {
factory.setUseSSL(true);
if (ssl.getAlgorithm() != null) {
factory.setSslAlgorithm(ssl.getAlgorithm());
}
factory.setKeyStoreType(ssl.getKeyStoreType());
factory.setKeyStore(ssl.getKeyStore());
factory.setKeyStorePassphrase(ssl.getKeyStorePassword());
factory.setTrustStoreType(ssl.getTrustStoreType());
factory.setTrustStore(ssl.getTrustStore());
factory.setTrustStorePassphrase(ssl.getTrustStorePassword());
}
if (config.getConnectionTimeout() != null) {
factory.setConnectionTimeout(
(int) config.getConnectionTimeout().toMillis());
map.from(ssl::getAlgorithm).whenNonNull().to(factory::setSslAlgorithm);
map.from(ssl::getKeyStoreType).to(factory::setKeyStoreType);
map.from(ssl::getKeyStore).to(factory::setKeyStore);
map.from(ssl::getKeyStorePassword).to(factory::setKeyStorePassphrase);
map.from(ssl::getTrustStoreType).to(factory::setTrustStoreType);
map.from(ssl::getTrustStore).to(factory::setTrustStore);
map.from(ssl::getTrustStorePassword).to(factory::setTrustStorePassphrase);
}
map.from(properties::getConnectionTimeout).whenNonNull()
.asInt(Duration::toMillis).to(factory::setConnectionTimeout);
factory.afterPropertiesSet();
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(
factory.getObject());
connectionFactory.setAddresses(config.determineAddresses());
connectionFactory.setPublisherConfirms(config.isPublisherConfirms());
connectionFactory.setPublisherReturns(config.isPublisherReturns());
if (config.getCache().getChannel().getSize() != null) {
connectionFactory
.setChannelCacheSize(config.getCache().getChannel().getSize());
}
if (config.getCache().getConnection().getMode() != null) {
connectionFactory
.setCacheMode(config.getCache().getConnection().getMode());
}
if (config.getCache().getConnection().getSize() != null) {
connectionFactory.setConnectionCacheSize(
config.getCache().getConnection().getSize());
}
if (config.getCache().getChannel().getCheckoutTimeout() != null) {
connectionFactory.setChannelCheckoutTimeout(
config.getCache().getChannel().getCheckoutTimeout());
}
return connectionFactory;
return factory;
}
}
@ -171,26 +164,24 @@ public class RabbitAutoConfiguration {
@ConditionalOnSingleCandidate(ConnectionFactory.class)
@ConditionalOnMissingBean(RabbitTemplate.class)
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
PropertyMapper map = PropertyMapper.get();
RabbitTemplate template = new RabbitTemplate(connectionFactory);
MessageConverter messageConverter = this.messageConverter.getIfUnique();
if (messageConverter != null) {
rabbitTemplate.setMessageConverter(messageConverter);
}
rabbitTemplate.setMandatory(determineMandatoryFlag());
RabbitProperties.Template templateProperties = this.properties.getTemplate();
RabbitProperties.Retry retryProperties = templateProperties.getRetry();
if (retryProperties.isEnabled()) {
rabbitTemplate.setRetryTemplate(createRetryTemplate(retryProperties));
template.setMessageConverter(messageConverter);
}
if (templateProperties.getReceiveTimeout() != null) {
rabbitTemplate.setReceiveTimeout(templateProperties.getReceiveTimeout());
template.setMandatory(determineMandatoryFlag());
RabbitProperties.Template properties = this.properties.getTemplate();
if (properties.getRetry().isEnabled()) {
template.setRetryTemplate(createRetryTemplate(properties.getRetry()));
}
if (templateProperties.getReplyTimeout() != null) {
rabbitTemplate.setReplyTimeout(templateProperties.getReplyTimeout());
}
rabbitTemplate.setExchange(templateProperties.getExchange());
rabbitTemplate.setRoutingKey(templateProperties.getRoutingKey());
return rabbitTemplate;
map.from(properties::getReceiveTimeout).whenNonNull()
.to(template::setReceiveTimeout);
map.from(properties::getReplyTimeout).whenNonNull()
.to(template::setReplyTimeout);
map.from(properties::getExchange).to(template::setExchange);
map.from(properties::getRoutingKey).to(template::setRoutingKey);
return template;
}
private boolean determineMandatoryFlag() {
@ -199,14 +190,16 @@ public class RabbitAutoConfiguration {
}
private RetryTemplate createRetryTemplate(RabbitProperties.Retry properties) {
PropertyMapper map = PropertyMapper.get();
RetryTemplate template = new RetryTemplate();
SimpleRetryPolicy policy = new SimpleRetryPolicy();
policy.setMaxAttempts(properties.getMaxAttempts());
map.from(properties::getMaxAttempts).to(policy::setMaxAttempts);
template.setRetryPolicy(policy);
ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
backOffPolicy.setInitialInterval(properties.getInitialInterval());
backOffPolicy.setMultiplier(properties.getMultiplier());
backOffPolicy.setMaxInterval(properties.getMaxInterval());
map.from(properties::getInitialInterval)
.to(backOffPolicy::setInitialInterval);
map.from(properties::getMultiplier).to(backOffPolicy::setMultiplier);
map.from(properties::getMaxInterval).to(backOffPolicy::setMaxInterval);
template.setBackOffPolicy(backOffPolicy);
return template;
}

@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.amqp;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.boot.context.properties.PropertyMapper;
/**
* Configure {@link SimpleRabbitListenerContainerFactoryConfigurer} with sensible
@ -33,18 +34,15 @@ public final class SimpleRabbitListenerContainerFactoryConfigurer extends
@Override
public void configure(SimpleRabbitListenerContainerFactory factory,
ConnectionFactory connectionFactory) {
PropertyMapper map = PropertyMapper.get();
RabbitProperties.SimpleContainer config = getRabbitProperties().getListener()
.getSimple();
configure(factory, connectionFactory, config);
if (config.getConcurrency() != null) {
factory.setConcurrentConsumers(config.getConcurrency());
}
if (config.getMaxConcurrency() != null) {
factory.setMaxConcurrentConsumers(config.getMaxConcurrency());
}
if (config.getTransactionSize() != null) {
factory.setTxSize(config.getTransactionSize());
}
map.from(config::getConcurrency).whenNonNull()
.to(factory::setConcurrentConsumers);
map.from(config::getMaxConcurrency).whenNonNull()
.to(factory::setMaxConcurrentConsumers);
map.from(config::getTransactionSize).whenNonNull().to(factory::setTxSize);
}
}

@ -27,9 +27,9 @@ import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.util.StringUtils;
/**
* Basic {@link BatchConfigurer} implementation.
@ -103,14 +103,13 @@ public class BasicBatchConfigurer implements BatchConfigurer {
}
protected JobExplorer createJobExplorer() throws Exception {
JobExplorerFactoryBean jobExplorerFactoryBean = new JobExplorerFactoryBean();
jobExplorerFactoryBean.setDataSource(this.dataSource);
String tablePrefix = this.properties.getTablePrefix();
if (StringUtils.hasText(tablePrefix)) {
jobExplorerFactoryBean.setTablePrefix(tablePrefix);
}
jobExplorerFactoryBean.afterPropertiesSet();
return jobExplorerFactoryBean.getObject();
PropertyMapper map = PropertyMapper.get();
JobExplorerFactoryBean factory = new JobExplorerFactoryBean();
factory.setDataSource(this.dataSource);
map.from(this.properties::getTablePrefix).whenHasText()
.to(factory::setTablePrefix);
factory.afterPropertiesSet();
return factory.getObject();
}
protected JobLauncher createJobLauncher() throws Exception {
@ -122,16 +121,13 @@ public class BasicBatchConfigurer implements BatchConfigurer {
protected JobRepository createJobRepository() throws Exception {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(this.dataSource);
String isolationLevel = determineIsolationLevel();
if (isolationLevel != null) {
factory.setIsolationLevelForCreate(isolationLevel);
}
String tablePrefix = this.properties.getTablePrefix();
if (StringUtils.hasText(tablePrefix)) {
factory.setTablePrefix(tablePrefix);
}
factory.setTransactionManager(getTransactionManager());
PropertyMapper map = PropertyMapper.get();
map.from(() -> this.dataSource).to(factory::setDataSource);
map.from(this::determineIsolationLevel).whenNonNull()
.to(factory::setIsolationLevelForCreate);
map.from(this.properties::getTablePrefix).whenHasText()
.to(factory::setTablePrefix);
map.from(this::getTransactionManager).to(factory::setTransactionManager);
factory.afterPropertiesSet();
return factory.getObject();
}

@ -23,9 +23,11 @@ import com.couchbase.client.java.Bucket;
import com.couchbase.client.spring.cache.CacheBuilder;
import com.couchbase.client.spring.cache.CouchbaseCacheManager;
import org.springframework.boot.autoconfigure.cache.CacheProperties.Couchbase;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
@ -61,10 +63,9 @@ public class CouchbaseCacheConfiguration {
public CouchbaseCacheManager cacheManager() {
List<String> cacheNames = this.cacheProperties.getCacheNames();
CacheBuilder builder = CacheBuilder.newInstance(this.bucket);
Duration expiration = this.cacheProperties.getCouchbase().getExpiration();
if (expiration != null) {
builder = builder.withExpiration((int) expiration.getSeconds());
}
Couchbase couchbase = this.cacheProperties.getCouchbase();
PropertyMapper.get().from(couchbase::getExpiration).whenNonNull()
.asInt(Duration::getSeconds).to(builder::withExpiration);
String[] names = cacheNames.toArray(new String[cacheNames.size()]);
CouchbaseCacheManager cacheManager = new CouchbaseCacheManager(builder, names);
return this.customizers.customize(cacheManager);

@ -77,10 +77,8 @@ public class InfinispanCacheConfiguration {
EmbeddedCacheManager cacheManager = createEmbeddedCacheManager();
List<String> cacheNames = this.cacheProperties.getCacheNames();
if (!CollectionUtils.isEmpty(cacheNames)) {
for (String cacheName : cacheNames) {
cacheManager.defineConfiguration(cacheName,
getDefaultCacheConfiguration());
}
cacheNames.forEach((cacheName) -> cacheManager.defineConfiguration(cacheName,
getDefaultCacheConfiguration()));
}
return cacheManager;
}

@ -16,15 +16,13 @@
package org.springframework.boot.autoconfigure.cassandra;
import java.time.Duration;
import java.util.List;
import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.PoolingOptions;
import com.datastax.driver.core.QueryOptions;
import com.datastax.driver.core.SocketOptions;
import com.datastax.driver.core.policies.LoadBalancingPolicy;
import com.datastax.driver.core.policies.ReconnectionPolicy;
import com.datastax.driver.core.policies.RetryPolicy;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.ObjectProvider;
@ -32,6 +30,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -62,36 +61,27 @@ public class CassandraAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public Cluster cassandraCluster() {
PropertyMapper map = PropertyMapper.get();
CassandraProperties properties = this.properties;
Cluster.Builder builder = Cluster.builder()
.withClusterName(properties.getClusterName())
.withPort(properties.getPort());
if (properties.getUsername() != null) {
builder.withCredentials(properties.getUsername(), properties.getPassword());
}
if (properties.getCompression() != null) {
builder.withCompression(properties.getCompression());
}
if (properties.getLoadBalancingPolicy() != null) {
LoadBalancingPolicy policy = instantiate(properties.getLoadBalancingPolicy());
builder.withLoadBalancingPolicy(policy);
}
builder.withQueryOptions(getQueryOptions());
if (properties.getReconnectionPolicy() != null) {
ReconnectionPolicy policy = instantiate(properties.getReconnectionPolicy());
builder.withReconnectionPolicy(policy);
}
if (properties.getRetryPolicy() != null) {
RetryPolicy policy = instantiate(properties.getRetryPolicy());
builder.withRetryPolicy(policy);
}
builder.withSocketOptions(getSocketOptions());
if (properties.isSsl()) {
builder.withSSL();
}
builder.withPoolingOptions(getPoolingOptions());
builder.addContactPoints(properties.getContactPoints().toArray(new String[0]));
map.from(properties::getUsername).whenNonNull().to((username) -> builder
.withCredentials(username, properties.getPassword()));
map.from(properties::getCompression).whenNonNull().to(builder::withCompression);
map.from(properties::getLoadBalancingPolicy).whenNonNull()
.as(BeanUtils::instantiateClass).to(builder::withLoadBalancingPolicy);
map.from(this::getQueryOptions).to(builder::withQueryOptions);
map.from(properties::getReconnectionPolicy).whenNonNull()
.as(BeanUtils::instantiateClass).to(builder::withReconnectionPolicy);
map.from(properties::getRetryPolicy).whenNonNull().as(BeanUtils::instantiateClass)
.to(builder::withRetryPolicy);
map.from(this::getSocketOptions).to(builder::withSocketOptions);
map.from(properties::isSsl).whenTrue().toCall(builder::withSSL);
map.from(this::getPoolingOptions).to(builder::withPoolingOptions);
map.from(properties::getContactPoints)
.as((list) -> list.toArray(new String[list.size()]))
.to(builder::addContactPoints);
customize(builder);
return builder.build();
}
@ -104,50 +94,39 @@ public class CassandraAutoConfiguration {
}
}
public static <T> T instantiate(Class<T> type) {
return BeanUtils.instantiateClass(type);
}
private QueryOptions getQueryOptions() {
PropertyMapper map = PropertyMapper.get();
QueryOptions options = new QueryOptions();
CassandraProperties properties = this.properties;
if (properties.getConsistencyLevel() != null) {
options.setConsistencyLevel(properties.getConsistencyLevel());
}
if (properties.getSerialConsistencyLevel() != null) {
options.setSerialConsistencyLevel(properties.getSerialConsistencyLevel());
}
options.setFetchSize(properties.getFetchSize());
map.from(properties::getConsistencyLevel).whenNonNull()
.to(options::setConsistencyLevel);
map.from(properties::getSerialConsistencyLevel).whenNonNull()
.to(options::setSerialConsistencyLevel);
map.from(properties::getFetchSize).to(options::setFetchSize);
return options;
}
private SocketOptions getSocketOptions() {
PropertyMapper map = PropertyMapper.get();
SocketOptions options = new SocketOptions();
if (this.properties.getConnectTimeout() != null) {
options.setConnectTimeoutMillis(
(int) this.properties.getConnectTimeout().toMillis());
}
if (this.properties.getReadTimeout() != null) {
options.setReadTimeoutMillis(
(int) this.properties.getReadTimeout().toMillis());
}
map.from(this.properties::getConnectTimeout).whenNonNull()
.asInt(Duration::toMillis).to(options::setConnectTimeoutMillis);
map.from(this.properties::getReadTimeout).whenNonNull().asInt(Duration::toMillis)
.to(options::setReadTimeoutMillis);
return options;
}
private PoolingOptions getPoolingOptions() {
CassandraProperties.Pool pool = this.properties.getPool();
PropertyMapper map = PropertyMapper.get();
CassandraProperties.Pool properties = this.properties.getPool();
PoolingOptions options = new PoolingOptions();
if (pool.getIdleTimeout() != null) {
options.setIdleTimeoutSeconds((int) pool.getIdleTimeout().getSeconds());
}
if (pool.getPoolTimeout() != null) {
options.setPoolTimeoutMillis((int) pool.getPoolTimeout().toMillis());
}
if (pool.getHeartbeatInterval() != null) {
options.setHeartbeatIntervalSeconds(
(int) pool.getHeartbeatInterval().getSeconds());
}
options.setMaxQueueSize(pool.getMaxQueueSize());
map.from(properties::getIdleTimeout).whenNonNull().asInt(Duration::getSeconds)
.to(options::setIdleTimeoutSeconds);
map.from(properties::getPoolTimeout).whenNonNull().asInt(Duration::toMillis)
.to(options::setPoolTimeoutMillis);
map.from(properties::getHeartbeatInterval).whenNonNull()
.asInt(Duration::getSeconds).to(options::setHeartbeatIntervalSeconds);
map.from(properties::getMaxQueueSize).to(options::setMaxQueueSize);
return options;
}

@ -32,6 +32,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.domain.EntityScanPackages;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -46,7 +47,6 @@ import org.springframework.data.cassandra.core.convert.CassandraCustomConversion
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
import org.springframework.data.cassandra.core.mapping.SimpleUserTypeResolver;
import org.springframework.util.StringUtils;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Cassandra support.
@ -92,14 +92,16 @@ public class CassandraDataAutoConfiguration {
if (!packages.isEmpty()) {
context.setInitialEntitySet(CassandraEntityClassScanner.scan(packages));
}
if (StringUtils.hasText(this.properties.getKeyspaceName())) {
context.setUserTypeResolver(new SimpleUserTypeResolver(this.cluster,
this.properties.getKeyspaceName()));
}
PropertyMapper.get().from(this.properties::getKeyspaceName).whenHasText()
.as(this::createSimpleUserTypeResolver).to(context::setUserTypeResolver);
context.setCustomConversions(conversions);
return context;
}
private SimpleUserTypeResolver createSimpleUserTypeResolver(String keyspaceName) {
return new SimpleUserTypeResolver(this.cluster, keyspaceName);
}
@Bean
@ConditionalOnMissingBean
public CassandraConverter cassandraConverter(CassandraMappingContext mapping,

@ -17,6 +17,7 @@
package org.springframework.boot.autoconfigure.data.rest;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.core.mapping.RepositoryDetectionStrategy.RepositoryDetectionStrategies;
import org.springframework.http.MediaType;
@ -176,40 +177,19 @@ public class RepositoryRestProperties {
this.enableEnumTranslation = enableEnumTranslation;
}
public void applyTo(RepositoryRestConfiguration configuration) {
if (this.basePath != null) {
configuration.setBasePath(this.basePath);
}
if (this.defaultPageSize != null) {
configuration.setDefaultPageSize(this.defaultPageSize);
}
if (this.maxPageSize != null) {
configuration.setMaxPageSize(this.maxPageSize);
}
if (this.pageParamName != null) {
configuration.setPageParamName(this.pageParamName);
}
if (this.limitParamName != null) {
configuration.setLimitParamName(this.limitParamName);
}
if (this.sortParamName != null) {
configuration.setSortParamName(this.sortParamName);
}
if (this.detectionStrategy != null) {
configuration.setRepositoryDetectionStrategy(this.detectionStrategy);
}
if (this.defaultMediaType != null) {
configuration.setDefaultMediaType(this.defaultMediaType);
}
if (this.returnBodyOnCreate != null) {
configuration.setReturnBodyOnCreate(this.returnBodyOnCreate);
}
if (this.returnBodyOnUpdate != null) {
configuration.setReturnBodyOnUpdate(this.returnBodyOnUpdate);
}
if (this.enableEnumTranslation != null) {
configuration.setEnableEnumTranslation(this.enableEnumTranslation);
}
public void applyTo(RepositoryRestConfiguration rest) {
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
map.from(this::getBasePath).to(rest::setBasePath);
map.from(this::getDefaultPageSize).to(rest::setDefaultPageSize);
map.from(this::getMaxPageSize).to(rest::setMaxPageSize);
map.from(this::getPageParamName).to(rest::setPageParamName);
map.from(this::getLimitParamName).to(rest::setLimitParamName);
map.from(this::getSortParamName).to(rest::setSortParamName);
map.from(this::getDetectionStrategy).to(rest::setRepositoryDetectionStrategy);
map.from(this::getDefaultMediaType).to(rest::setDefaultMediaType);
map.from(this::getReturnBodyOnCreate).to(rest::setReturnBodyOnCreate);
map.from(this::getReturnBodyOnUpdate).to(rest::setReturnBodyOnUpdate);
map.from(this::getEnableEnumTranslation).to(rest::setEnableEnumTranslation);
}
}

@ -16,6 +16,7 @@
package org.springframework.boot.autoconfigure.elasticsearch.jest;
import java.time.Duration;
import java.util.List;
import com.google.gson.Gson;
@ -29,12 +30,13 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.elasticsearch.jest.JestProperties.Proxy;
import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* {@link EnableAutoConfiguration Auto-Configuration} for Jest.
@ -72,27 +74,20 @@ public class JestAutoConfiguration {
protected HttpClientConfig createHttpClientConfig() {
HttpClientConfig.Builder builder = new HttpClientConfig.Builder(
this.properties.getUris());
if (StringUtils.hasText(this.properties.getUsername())) {
builder.defaultCredentials(this.properties.getUsername(),
this.properties.getPassword());
}
String proxyHost = this.properties.getProxy().getHost();
if (StringUtils.hasText(proxyHost)) {
Integer proxyPort = this.properties.getProxy().getPort();
Assert.notNull(proxyPort, "Proxy port must not be null");
builder.proxy(new HttpHost(proxyHost, proxyPort));
}
Gson gson = this.gsonProvider.getIfUnique();
if (gson != null) {
builder.gson(gson);
}
builder.multiThreaded(this.properties.isMultiThreaded());
if (this.properties.getConnectionTimeout() != null) {
builder.connTimeout((int) this.properties.getConnectionTimeout().toMillis());
}
if (this.properties.getReadTimeout() != null) {
builder.readTimeout((int) this.properties.getReadTimeout().toMillis());
}
PropertyMapper map = PropertyMapper.get();
map.from(this.properties::getUsername).whenHasText().to((username) -> builder
.defaultCredentials(username, this.properties.getPassword()));
Proxy proxy = this.properties.getProxy();
map.from(proxy::getHost).whenHasText().to((host) -> {
Assert.notNull(proxy.getPort(), "Proxy port must not be null");
builder.proxy(new HttpHost(host, proxy.getPort()));
});
map.from(this.gsonProvider::getIfUnique).whenNonNull().to(builder::gson);
map.from(this.properties::isMultiThreaded).to(builder::multiThreaded);
map.from(this.properties::getConnectionTimeout).whenNonNull()
.asInt(Duration::toMillis).to(builder::connTimeout);
map.from(this.properties::getReadTimeout).whenNonNull().asInt(Duration::toMillis)
.to(builder::readTimeout);
customize(builder);
return builder.build();
}

@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure.jms;
import java.time.Duration;
import javax.jms.ConnectionFactory;
import javax.jms.Message;
@ -25,7 +27,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.autoconfigure.jms.JmsProperties.DeliveryMode;
import org.springframework.boot.autoconfigure.jms.JmsProperties.Template;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@ -68,38 +73,31 @@ public class JmsAutoConfiguration {
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(ConnectionFactory.class)
public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
jmsTemplate.setPubSubDomain(this.properties.isPubSubDomain());
DestinationResolver destinationResolver = this.destinationResolver
.getIfUnique();
if (destinationResolver != null) {
jmsTemplate.setDestinationResolver(destinationResolver);
}
MessageConverter messageConverter = this.messageConverter.getIfUnique();
if (messageConverter != null) {
jmsTemplate.setMessageConverter(messageConverter);
}
JmsProperties.Template template = this.properties.getTemplate();
if (template.getDefaultDestination() != null) {
jmsTemplate.setDefaultDestinationName(template.getDefaultDestination());
}
if (template.getDeliveryDelay() != null) {
jmsTemplate.setDeliveryDelay(template.getDeliveryDelay().toMillis());
}
jmsTemplate.setExplicitQosEnabled(template.determineQosEnabled());
if (template.getDeliveryMode() != null) {
jmsTemplate.setDeliveryMode(template.getDeliveryMode().getValue());
}
if (template.getPriority() != null) {
jmsTemplate.setPriority(template.getPriority());
}
if (template.getTimeToLive() != null) {
jmsTemplate.setTimeToLive(template.getTimeToLive().toMillis());
}
if (template.getReceiveTimeout() != null) {
jmsTemplate.setReceiveTimeout(template.getReceiveTimeout().toMillis());
}
return jmsTemplate;
PropertyMapper map = PropertyMapper.get();
JmsTemplate template = new JmsTemplate(connectionFactory);
template.setPubSubDomain(this.properties.isPubSubDomain());
map.from(this.destinationResolver::getIfUnique).whenNonNull()
.to(template::setDestinationResolver);
map.from(this.messageConverter::getIfUnique).whenNonNull()
.to(template::setMessageConverter);
mapTemplateProperties(this.properties.getTemplate(), template);
return template;
}
private void mapTemplateProperties(Template properties, JmsTemplate template) {
PropertyMapper map = PropertyMapper.get();
map.from(properties::getDefaultDestination).whenNonNull()
.to(template::setDefaultDestinationName);
map.from(properties::getDeliveryDelay).whenNonNull().as(Duration::toMillis)
.to(template::setDeliveryDelay);
map.from(properties::determineQosEnabled).to(template::setExplicitQosEnabled);
map.from(properties::getDeliveryMode).whenNonNull().as(DeliveryMode::getValue)
.to(template::setDeliveryMode);
map.from(properties::getPriority).whenNonNull().to(template::setPriority);
map.from(properties::getTimeToLive).whenNonNull().as(Duration::toMillis)
.to(template::setTimeToLive);
map.from(properties::getReceiveTimeout).whenNonNull().as(Duration::toMillis)
.to(template::setReceiveTimeout);
}
}

@ -16,7 +16,10 @@
package org.springframework.boot.autoconfigure.kafka;
import java.time.Duration;
import org.springframework.boot.autoconfigure.kafka.KafkaProperties.Listener;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.core.ConsumerFactory;
import org.springframework.kafka.core.KafkaTemplate;
@ -65,41 +68,39 @@ public class ConcurrentKafkaListenerContainerFactoryConfigurer {
/**
* Configure the specified Kafka listener container factory. The factory can be
* further tuned and default settings can be overridden.
* @param listenerContainerFactory the {@link ConcurrentKafkaListenerContainerFactory}
* instance to configure
* @param listenerFactory the {@link ConcurrentKafkaListenerContainerFactory} instance
* to configure
* @param consumerFactory the {@link ConsumerFactory} to use
*/
public void configure(
ConcurrentKafkaListenerContainerFactory<Object, Object> listenerContainerFactory,
ConcurrentKafkaListenerContainerFactory<Object, Object> listenerFactory,
ConsumerFactory<Object, Object> consumerFactory) {
listenerContainerFactory.setConsumerFactory(consumerFactory);
if (this.messageConverter != null) {
listenerContainerFactory.setMessageConverter(this.messageConverter);
}
if (this.replyTemplate != null) {
listenerContainerFactory.setReplyTemplate(this.replyTemplate);
}
Listener container = this.properties.getListener();
ContainerProperties containerProperties = listenerContainerFactory
.getContainerProperties();
if (container.getAckMode() != null) {
containerProperties.setAckMode(container.getAckMode());
}
if (container.getAckCount() != null) {
containerProperties.setAckCount(container.getAckCount());
}
if (container.getAckTime() != null) {
containerProperties.setAckTime(container.getAckTime().toMillis());
}
if (container.getPollTimeout() != null) {
containerProperties.setPollTimeout(container.getPollTimeout().toMillis());
}
if (container.getConcurrency() != null) {
listenerContainerFactory.setConcurrency(container.getConcurrency());
}
if (container.getType() == Listener.Type.BATCH) {
listenerContainerFactory.setBatchListener(true);
}
listenerFactory.setConsumerFactory(consumerFactory);
configureListenerFactory(listenerFactory);
configureContainer(listenerFactory.getContainerProperties());
}
private void configureListenerFactory(
ConcurrentKafkaListenerContainerFactory<Object, Object> factory) {
PropertyMapper map = PropertyMapper.get();
Listener properties = this.properties.getListener();
map.from(properties::getConcurrency).whenNonNull().to(factory::setConcurrency);
map.from(() -> this.messageConverter).whenNonNull()
.to(factory::setMessageConverter);
map.from(() -> this.replyTemplate).whenNonNull().to(factory::setReplyTemplate);
map.from(properties::getType).whenEqualTo(Listener.Type.BATCH)
.toCall(() -> factory.setBatchListener(true));
}
private void configureContainer(ContainerProperties container) {
PropertyMapper map = PropertyMapper.get();
Listener properties = this.properties.getListener();
map.from(properties::getAckMode).whenNonNull().to(container::setAckMode);
map.from(properties::getAckCount).whenNonNull().to(container::setAckCount);
map.from(properties::getAckTime).whenNonNull().as(Duration::toMillis)
.to(container::setAckTime);
map.from(properties::getPollTimeout).whenNonNull().as(Duration::toMillis)
.to(container::setPollTimeout);
}
}

@ -16,6 +16,7 @@
package org.springframework.boot.autoconfigure.mail;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Properties;
@ -31,6 +32,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration.MailSenderCondition;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@ -77,19 +79,16 @@ public class MailSenderAutoConfiguration {
}
private void applyProperties(JavaMailSenderImpl sender) {
sender.setHost(this.properties.getHost());
if (this.properties.getPort() != null) {
sender.setPort(this.properties.getPort());
}
sender.setUsername(this.properties.getUsername());
sender.setPassword(this.properties.getPassword());
sender.setProtocol(this.properties.getProtocol());
if (this.properties.getDefaultEncoding() != null) {
sender.setDefaultEncoding(this.properties.getDefaultEncoding().name());
}
if (!this.properties.getProperties().isEmpty()) {
sender.setJavaMailProperties(asProperties(this.properties.getProperties()));
}
PropertyMapper map = PropertyMapper.get();
map.from(this.properties::getHost).to(sender::setHost);
map.from(this.properties::getPort).whenNonNull().to(sender::setPort);
map.from(this.properties::getUsername).to(sender::setUsername);
map.from(this.properties::getPassword).to(sender::setPassword);
map.from(this.properties::getProtocol).to(sender::setProtocol);
map.from(this.properties::getDefaultEncoding).whenNonNull().as(Charset::name)
.to(sender::setDefaultEncoding);
map.from(this.properties::getProperties).whenNot(Map::isEmpty)
.as(this::asProperties).to(sender::setJavaMailProperties);
}
private Properties asProperties(Map<String, String> source) {

@ -48,13 +48,10 @@ class RedisReactiveSessionConfiguration {
static class SpringBootRedisWebSessionConfiguration
extends RedisWebSessionConfiguration {
private SessionProperties sessionProperties;
@Autowired
public void customize(SessionProperties sessionProperties,
RedisSessionProperties redisSessionProperties) {
this.sessionProperties = sessionProperties;
Duration timeout = this.sessionProperties.getTimeout();
Duration timeout = sessionProperties.getTimeout();
if (timeout != null) {
setMaxInactiveIntervalInSeconds((int) timeout.getSeconds());
}

@ -19,7 +19,6 @@ package org.springframework.boot.autoconfigure.thymeleaf;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import javax.annotation.PostConstruct;
@ -48,15 +47,16 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.autoconfigure.template.TemplateLocation;
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties.Reactive;
import org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain;
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.MediaType;
import org.springframework.util.MimeType;
import org.springframework.web.servlet.resource.ResourceUrlEncodingFilter;
@ -263,27 +263,34 @@ public class ThymeleafAutoConfiguration {
ISpringWebFluxTemplateEngine templateEngine) {
ThymeleafReactiveViewResolver resolver = new ThymeleafReactiveViewResolver();
resolver.setTemplateEngine(templateEngine);
resolver.setDefaultCharset(this.properties.getEncoding());
List<MediaType> mediaTypes = this.properties.getReactive().getMediaTypes();
if (mediaTypes != null) {
resolver.setSupportedMediaTypes(mediaTypes);
}
resolver.setExcludedViewNames(this.properties.getExcludedViewNames());
resolver.setViewNames(this.properties.getViewNames());
if (this.properties.getReactive().getMaxChunkSize() > 0) {
resolver.setResponseMaxChunkSizeBytes(
this.properties.getReactive().getMaxChunkSize());
}
resolver.setFullModeViewNames(
this.properties.getReactive().getFullModeViewNames());
resolver.setChunkedModeViewNames(
this.properties.getReactive().getChunkedModeViewNames());
mapProperties(this.properties, resolver);
mapReactiveProperties(this.properties.getReactive(), resolver);
// This resolver acts as a fallback resolver (e.g. like a
// InternalResourceViewResolver) so it needs to have low precedence
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5);
return resolver;
}
private void mapProperties(ThymeleafProperties properties,
ThymeleafReactiveViewResolver resolver) {
PropertyMapper map = PropertyMapper.get();
map.from(properties::getEncoding).to(resolver::setDefaultCharset);
resolver.setExcludedViewNames(properties.getExcludedViewNames());
resolver.setViewNames(properties.getViewNames());
}
private void mapReactiveProperties(Reactive properties,
ThymeleafReactiveViewResolver resolver) {
PropertyMapper map = PropertyMapper.get();
map.from(properties::getMediaTypes).whenNonNull()
.to(resolver::setSupportedMediaTypes);
map.from(properties::getMaxChunkSize).when((size) -> size > 0)
.to(resolver::setResponseMaxChunkSizeBytes);
map.from(properties::getFullModeViewNames).to(resolver::setFullModeViewNames);
map.from(properties::getChunkedModeViewNames)
.to(resolver::setChunkedModeViewNames);
}
}
@Configuration

@ -19,9 +19,9 @@ package org.springframework.boot.autoconfigure.web;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.boot.context.properties.bind.convert.DefaultDurationUnit;
/**
@ -459,29 +459,23 @@ public class ResourceProperties {
}
public org.springframework.http.CacheControl toHttpCacheControl() {
org.springframework.http.CacheControl cacheControl = createCacheControl();
callIfTrue(this.mustRevalidate, cacheControl,
org.springframework.http.CacheControl::mustRevalidate);
callIfTrue(this.noTransform, cacheControl,
org.springframework.http.CacheControl::noTransform);
callIfTrue(this.cachePublic, cacheControl,
org.springframework.http.CacheControl::cachePublic);
callIfTrue(this.cachePrivate, cacheControl,
org.springframework.http.CacheControl::cachePrivate);
callIfTrue(this.proxyRevalidate, cacheControl,
org.springframework.http.CacheControl::proxyRevalidate);
if (this.staleWhileRevalidate != null) {
cacheControl.staleWhileRevalidate(
this.staleWhileRevalidate.getSeconds(), TimeUnit.SECONDS);
}
if (this.staleIfError != null) {
cacheControl.staleIfError(this.staleIfError.getSeconds(),
TimeUnit.SECONDS);
}
if (this.sMaxAge != null) {
cacheControl.sMaxAge(this.sMaxAge.getSeconds(), TimeUnit.SECONDS);
}
return cacheControl;
PropertyMapper map = PropertyMapper.get();
org.springframework.http.CacheControl control = createCacheControl();
map.from(this::getMustRevalidate).whenTrue()
.toCall(control::mustRevalidate);
map.from(this::getNoTransform).whenTrue().toCall(control::noTransform);
map.from(this::getCachePublic).whenTrue().toCall(control::cachePublic);
map.from(this::getCachePrivate).whenTrue().toCall(control::cachePrivate);
map.from(this::getProxyRevalidate).whenTrue()
.toCall(control::proxyRevalidate);
map.from(this::getStaleWhileRevalidate).whenNonNull().to(
(duration) -> control.staleWhileRevalidate(duration.getSeconds(),
TimeUnit.SECONDS));
map.from(this::getStaleIfError).whenNonNull().to((duration) -> control
.staleIfError(duration.getSeconds(), TimeUnit.SECONDS));
map.from(this::getSMaxAge).whenNonNull().to((duration) -> control
.sMaxAge(duration.getSeconds(), TimeUnit.SECONDS));
return control;
}
private org.springframework.http.CacheControl createCacheControl() {
@ -498,12 +492,6 @@ public class ResourceProperties {
return org.springframework.http.CacheControl.empty();
}
private <T> void callIfTrue(Boolean property, T instance, Consumer<T> call) {
if (Boolean.TRUE.equals(property)) {
call.accept(instance);
}
}
}
}

Loading…
Cancel
Save