diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisClientConfigurationBuilderCustomizer.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisClientConfigurationBuilderCustomizer.java new file mode 100644 index 00000000000..98d39623261 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisClientConfigurationBuilderCustomizer.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.data.redis; + +import org.springframework.data.redis.connection.jedis.JedisClientConfiguration; +import org.springframework.data.redis.connection.jedis.JedisClientConfiguration.JedisClientConfigurationBuilder; + +/** + * Callback interface that can be implemented by beans wishing to customize the + * {@link JedisClientConfiguration} via a {@link JedisClientConfigurationBuilder + * JedisClientConfiguration.JedisClientConfigurationBuilder} whilst retaining default + * auto-configuration. + * + * @author Mark Paluch + * @since 2.0.0 + */ +@FunctionalInterface +public interface JedisClientConfigurationBuilderCustomizer { + + /** + * Customize the {@link JedisClientConfigurationBuilder}. + * @param clientConfigurationBuilder the builder to customize + */ + void customize(JedisClientConfigurationBuilder clientConfigurationBuilder); + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisConnectionConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisConnectionConfiguration.java index cb2799c859a..58b3b5f17be 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisConnectionConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisConnectionConfiguration.java @@ -17,6 +17,9 @@ package org.springframework.boot.autoconfigure.data.redis; import java.net.UnknownHostException; +import java.time.Duration; +import java.util.Collections; +import java.util.List; import org.apache.commons.pool2.impl.GenericObjectPool; import redis.clients.jedis.Jedis; @@ -30,6 +33,8 @@ import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisSentinelConfiguration; +import org.springframework.data.redis.connection.jedis.JedisClientConfiguration; +import org.springframework.data.redis.connection.jedis.JedisClientConfiguration.JedisClientConfigurationBuilder; import org.springframework.data.redis.connection.jedis.JedisConnection; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.util.StringUtils; @@ -46,66 +51,68 @@ class JedisConnectionConfiguration extends RedisConnectionConfiguration { private final RedisProperties properties; + private final List builderCustomizers; + JedisConnectionConfiguration(RedisProperties properties, ObjectProvider sentinelConfiguration, - ObjectProvider clusterConfiguration) { + ObjectProvider clusterConfiguration, + ObjectProvider> builderCustomizers) { super(properties, sentinelConfiguration, clusterConfiguration); this.properties = properties; + this.builderCustomizers = builderCustomizers + .getIfAvailable(Collections::emptyList); } @Bean @ConditionalOnMissingBean(RedisConnectionFactory.class) public JedisConnectionFactory redisConnectionFactory() throws UnknownHostException { - return applyProperties(createJedisConnectionFactory()); - } - - private JedisConnectionFactory applyProperties(JedisConnectionFactory factory) { - configureConnection(factory); - if (this.properties.isSsl()) { - factory.setUseSsl(true); - } - factory.setDatabase(this.properties.getDatabase()); - if (this.properties.getTimeout() > 0) { - factory.setTimeout(this.properties.getTimeout()); - } - return factory; - } - - private void configureConnection(JedisConnectionFactory factory) { - if (StringUtils.hasText(this.properties.getUrl())) { - configureConnectionFromUrl(factory); - } - else { - factory.setHostName(this.properties.getHost()); - factory.setPort(this.properties.getPort()); - if (this.properties.getPassword() != null) { - factory.setPassword(this.properties.getPassword()); - } - } - } - - private void configureConnectionFromUrl(JedisConnectionFactory factory) { - ConnectionInfo connectionInfo = parseUrl(this.properties.getUrl()); - factory.setUseSsl(connectionInfo.isUseSsl()); - factory.setHostName(connectionInfo.getHostName()); - factory.setPort(connectionInfo.getPort()); - if (connectionInfo.getPassword() != null) { - factory.setPassword(connectionInfo.getPassword()); - } + return createJedisConnectionFactory(); } private JedisConnectionFactory createJedisConnectionFactory() { - RedisProperties.Pool pool = this.properties.getJedis().getPool(); - JedisPoolConfig poolConfig = pool != null ? jedisPoolConfig(pool) - : new JedisPoolConfig(); + JedisClientConfiguration clientConfiguration = getJedisClientConfiguration(); if (getSentinelConfig() != null) { - return new JedisConnectionFactory(getSentinelConfig(), poolConfig); + return new JedisConnectionFactory(getSentinelConfig(), clientConfiguration); } + if (getClusterConfiguration() != null) { - return new JedisConnectionFactory(getClusterConfiguration(), poolConfig); + return new JedisConnectionFactory(getClusterConfiguration(), + clientConfiguration); } - return new JedisConnectionFactory(poolConfig); + + return new JedisConnectionFactory(getStandaloneConfig(), clientConfiguration); + } + + private JedisClientConfiguration getJedisClientConfiguration() { + JedisClientConfigurationBuilder builder = applyProperties( + JedisClientConfiguration.builder()); + RedisProperties.Pool pool = this.properties.getJedis().getPool(); + if (pool != null) { + applyPooling(pool, builder); + } + if (StringUtils.hasText(this.properties.getUrl())) { + customizeConfigurationFromUrl(builder); + } + customize(builder); + return builder.build(); + } + + private JedisClientConfigurationBuilder applyProperties( + JedisClientConfigurationBuilder builder) { + if (this.properties.isSsl()) { + builder.useSsl(); + } + if (this.properties.getTimeout() != 0) { + Duration timeout = Duration.ofMillis(this.properties.getTimeout()); + builder.readTimeout(timeout).connectTimeout(timeout); + } + return builder; + } + + private void applyPooling(RedisProperties.Pool pool, + JedisClientConfiguration.JedisClientConfigurationBuilder builder) { + builder.usePooling().poolConfig(jedisPoolConfig(pool)); } private JedisPoolConfig jedisPoolConfig(RedisProperties.Pool pool) { @@ -117,4 +124,19 @@ class JedisConnectionConfiguration extends RedisConnectionConfiguration { return config; } + private void customizeConfigurationFromUrl( + JedisClientConfiguration.JedisClientConfigurationBuilder builder) { + ConnectionInfo connectionInfo = parseUrl(this.properties.getUrl()); + if (connectionInfo.isUseSsl()) { + builder.useSsl(); + } + } + + private void customize( + JedisClientConfiguration.JedisClientConfigurationBuilder builder) { + for (JedisClientConfigurationBuilderCustomizer customizer : this.builderCustomizers) { + customizer.customize(builder); + } + } + } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceClientConfigurationBuilderCustomizer.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceClientConfigurationBuilderCustomizer.java new file mode 100644 index 00000000000..3a20947bbb7 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceClientConfigurationBuilderCustomizer.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.data.redis; + +import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration.LettuceClientConfigurationBuilder; + +/** + * Callback interface that can be implemented by beans wishing to customize the + * {@link LettuceClientConfiguration} via a {@link LettuceClientConfigurationBuilder + * LettuceClientConfiguration.LettuceClientConfigurationBuilder} whilst retaining default + * auto-configuration. + * + * @author Mark Paluch + * @since 2.0.0 + */ +@FunctionalInterface +public interface LettuceClientConfigurationBuilderCustomizer { + + /** + * Customize the {@link LettuceClientConfigurationBuilder}. + * @param clientConfigurationBuilder the builder to customize + */ + void customize(LettuceClientConfigurationBuilder clientConfigurationBuilder); + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration.java index f269b4a2016..be88d7a4940 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration.java @@ -17,6 +17,9 @@ package org.springframework.boot.autoconfigure.data.redis; import java.net.UnknownHostException; +import java.time.Duration; +import java.util.Collections; +import java.util.List; import io.lettuce.core.RedisClient; import io.lettuce.core.cluster.RedisClusterClient; @@ -34,6 +37,8 @@ import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisSentinelConfiguration; import org.springframework.data.redis.connection.lettuce.DefaultLettucePool; +import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration.LettuceClientConfigurationBuilder; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.util.StringUtils; @@ -49,11 +54,16 @@ class LettuceConnectionConfiguration extends RedisConnectionConfiguration { private final RedisProperties properties; + private final List builderCustomizers; + LettuceConnectionConfiguration(RedisProperties properties, ObjectProvider sentinelConfigurationProvider, - ObjectProvider clusterConfigurationProvider) { + ObjectProvider clusterConfigurationProvider, + ObjectProvider> builderCustomizers) { super(properties, sentinelConfigurationProvider, clusterConfigurationProvider); this.properties = properties; + this.builderCustomizers = builderCustomizers + .getIfAvailable(Collections::emptyList); } @Bean(destroyMethod = "shutdown") @@ -66,52 +76,26 @@ class LettuceConnectionConfiguration extends RedisConnectionConfiguration { @ConditionalOnMissingBean(RedisConnectionFactory.class) public LettuceConnectionFactory redisConnectionFactory( ClientResources clientResources) throws UnknownHostException { - return applyProperties(createLettuceConnectionFactory(clientResources)); + if (this.properties.getLettuce().getPool() != null) { + return createLettuceConnectionFactory(clientResources); + } + return createLettuceConnectionFactory( + getLettuceClientConfiguration(clientResources)); } - private LettuceConnectionFactory applyProperties(LettuceConnectionFactory factory) { - configureConnection(factory); - if (this.properties.isSsl()) { - factory.setUseSsl(true); - } - if (this.properties.getLettuce() != null) { - RedisProperties.Lettuce lettuce = this.properties.getLettuce(); - if (lettuce.getShutdownTimeout() >= 0) { - factory.setShutdownTimeout( - this.properties.getLettuce().getShutdownTimeout()); - } - } - return factory; + private LettuceConnectionFactory createLettuceConnectionFactory( + ClientResources clientResources) { + return new LettuceConnectionFactory(applyProperties(createLettucePool(), + this.properties.getLettuce().getPool(), clientResources)); } - private void configureConnection(LettuceConnectionFactory factory) { - if (StringUtils.hasText(this.properties.getUrl())) { - configureConnectionFromUrl(factory); - } - else { - factory.setHostName(this.properties.getHost()); - factory.setPort(this.properties.getPort()); - if (this.properties.getPassword() != null) { - factory.setPassword(this.properties.getPassword()); - } - factory.setDatabase(this.properties.getDatabase()); - if (this.properties.getTimeout() > 0) { - factory.setTimeout(this.properties.getTimeout()); - } - } + private DefaultLettucePool createLettucePool() { + return getSentinelConfig() != null ? new DefaultLettucePool(getSentinelConfig()) + : new DefaultLettucePool(); } - private void configureConnectionFromUrl(LettuceConnectionFactory factory) { - ConnectionInfo connectionInfo = parseUrl(this.properties.getUrl()); - factory.setUseSsl(connectionInfo.isUseSsl()); - factory.setHostName(connectionInfo.getHostName()); - factory.setPort(connectionInfo.getPort()); - if (connectionInfo.getPassword() != null) { - factory.setPassword(connectionInfo.getPassword()); - } - } - - private DefaultLettucePool applyProperties(DefaultLettucePool pool) { + private DefaultLettucePool applyProperties(DefaultLettucePool pool, + RedisProperties.Pool properties, ClientResources clientResources) { if (StringUtils.hasText(this.properties.getUrl())) { configureConnectionFromUrl(pool); } @@ -126,6 +110,8 @@ class LettuceConnectionConfiguration extends RedisConnectionConfiguration { if (this.properties.getTimeout() > 0) { pool.setTimeout(this.properties.getTimeout()); } + pool.setPoolConfig(lettucePoolConfig(properties)); + pool.setClientResources(clientResources); pool.afterPropertiesSet(); return pool; } @@ -139,53 +125,7 @@ class LettuceConnectionConfiguration extends RedisConnectionConfiguration { } } - private LettuceConnectionFactory createLettuceConnectionFactory( - ClientResources clientResources) { - - if (getSentinelConfig() != null) { - if (this.properties.getLettuce() != null - && this.properties.getLettuce().getPool() != null) { - DefaultLettucePool lettucePool = new DefaultLettucePool( - getSentinelConfig()); - return new LettuceConnectionFactory(applyProperties( - applyClientResources(lettucePool, clientResources))); - } - return applyClientResources(new LettuceConnectionFactory(getSentinelConfig()), - clientResources); - } - - if (getClusterConfiguration() != null) { - return applyClientResources( - new LettuceConnectionFactory(getClusterConfiguration()), - clientResources); - } - - if (this.properties.getLettuce() != null - && this.properties.getLettuce().getPool() != null) { - GenericObjectPoolConfig config = lettucePoolConfig( - this.properties.getLettuce().getPool()); - DefaultLettucePool lettucePool = new DefaultLettucePool( - this.properties.getHost(), this.properties.getPort(), config); - return new LettuceConnectionFactory( - applyProperties(applyClientResources(lettucePool, clientResources))); - } - - return applyClientResources(new LettuceConnectionFactory(), clientResources); - } - - private DefaultLettucePool applyClientResources(DefaultLettucePool lettucePool, - ClientResources clientResources) { - lettucePool.setClientResources(clientResources); - return lettucePool; - } - - private LettuceConnectionFactory applyClientResources( - LettuceConnectionFactory factory, ClientResources clientResources) { - factory.setClientResources(clientResources); - return factory; - } - - private GenericObjectPoolConfig lettucePoolConfig(RedisProperties.Pool props) { + private static GenericObjectPoolConfig lettucePoolConfig(RedisProperties.Pool props) { GenericObjectPoolConfig config = new GenericObjectPoolConfig(); config.setMaxTotal(props.getMaxActive()); config.setMaxIdle(props.getMaxIdle()); @@ -194,4 +134,64 @@ class LettuceConnectionConfiguration extends RedisConnectionConfiguration { return config; } + private LettuceConnectionFactory createLettuceConnectionFactory( + LettuceClientConfiguration clientConfiguration) { + + if (getSentinelConfig() != null) { + return new LettuceConnectionFactory(getSentinelConfig(), clientConfiguration); + } + + if (getClusterConfiguration() != null) { + return new LettuceConnectionFactory(getClusterConfiguration(), + clientConfiguration); + } + + return new LettuceConnectionFactory(getStandaloneConfig(), clientConfiguration); + } + + private LettuceClientConfiguration getLettuceClientConfiguration( + ClientResources clientResources) { + LettuceClientConfigurationBuilder builder = applyProperties( + LettuceClientConfiguration.builder()); + if (StringUtils.hasText(this.properties.getUrl())) { + customizeConfigurationFromUrl(builder); + } + builder.clientResources(clientResources); + customize(builder); + return builder.build(); + } + + private LettuceClientConfigurationBuilder applyProperties( + LettuceClientConfiguration.LettuceClientConfigurationBuilder builder) { + if (this.properties.isSsl()) { + builder.useSsl(); + } + if (this.properties.getTimeout() != 0) { + builder.commandTimeout(Duration.ofMillis(this.properties.getTimeout())); + } + if (this.properties.getLettuce() != null) { + RedisProperties.Lettuce lettuce = this.properties.getLettuce(); + if (lettuce.getShutdownTimeout() >= 0) { + builder.shutdownTimeout(Duration + .ofSeconds(this.properties.getLettuce().getShutdownTimeout())); + } + } + return builder; + } + + private void customizeConfigurationFromUrl( + LettuceClientConfiguration.LettuceClientConfigurationBuilder builder) { + ConnectionInfo connectionInfo = parseUrl(this.properties.getUrl()); + if (connectionInfo.isUseSsl()) { + builder.useSsl(); + } + } + + private void customize( + LettuceClientConfiguration.LettuceClientConfigurationBuilder builder) { + for (LettuceClientConfigurationBuilderCustomizer customizer : this.builderCustomizers) { + customizer.customize(builder); + } + } + } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionConfiguration.java index b8ae36329f2..a2f6e886663 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionConfiguration.java @@ -24,7 +24,9 @@ import java.util.List; import org.springframework.beans.factory.ObjectProvider; import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.RedisNode; +import org.springframework.data.redis.connection.RedisPassword; import org.springframework.data.redis.connection.RedisSentinelConfiguration; +import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -50,6 +52,24 @@ abstract class RedisConnectionConfiguration { this.clusterConfiguration = clusterConfigurationProvider.getIfAvailable(); } + protected final RedisStandaloneConfiguration getStandaloneConfig() { + RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(); + + if (StringUtils.hasText(this.properties.getUrl())) { + ConnectionInfo connectionInfo = parseUrl(this.properties.getUrl()); + config.setHostName(connectionInfo.getHostName()); + config.setPort(connectionInfo.getPort()); + config.setPassword(RedisPassword.of(connectionInfo.getPassword())); + } + else { + config.setHostName(this.properties.getHost()); + config.setPort(this.properties.getPort()); + config.setPassword(RedisPassword.of(this.properties.getPassword())); + } + config.setDatabase(this.properties.getDatabase()); + return config; + } + protected final RedisSentinelConfiguration getSentinelConfig() { if (this.sentinelConfiguration != null) { return this.sentinelConfiguration; diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationJedisTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationJedisTests.java index 0121ac197d6..58007349c20 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationJedisTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationJedisTests.java @@ -28,6 +28,9 @@ import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions; import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner; import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.jedis.JedisClientConfiguration.JedisClientConfigurationBuilder; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.util.StringUtils; @@ -62,6 +65,13 @@ public class RedisAutoConfigurationJedisTests { assertThat(cf.isUseSsl()).isFalse(); } + @Test + public void testCustomizeRedisConfiguration() throws Exception { + load(CustomConfiguration.class); + JedisConnectionFactory cf = this.context.getBean(JedisConnectionFactory.class); + assertThat(cf.isUseSsl()).isTrue(); + } + @Test public void testRedisUrlConfiguration() throws Exception { load("spring.redis.host:foo", @@ -130,8 +140,15 @@ public class RedisAutoConfigurationJedisTests { } private void load(String... environment) { + load(null, environment); + } + + private void load(Class config, String... environment) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); TestPropertyValues.of(environment).applyTo(ctx); + if (config != null) { + ctx.register(config); + } ctx.register(RedisAutoConfiguration.class); ctx.refresh(); this.context = ctx; @@ -172,4 +189,14 @@ public class RedisAutoConfigurationJedisTests { } } + @Configuration + static class CustomConfiguration { + + @Bean + JedisClientConfigurationBuilderCustomizer customizer() { + return JedisClientConfigurationBuilder::useSsl; + } + + } + } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java index aafecf1762f..2df886f981d 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java @@ -28,7 +28,10 @@ import org.junit.Test; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.lettuce.DefaultLettucePool; +import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration.LettuceClientConfigurationBuilder; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisOperations; import org.springframework.data.redis.core.StringRedisTemplate; @@ -78,6 +81,13 @@ public class RedisAutoConfigurationTests { assertThat(cf.isUseSsl()).isFalse(); } + @Test + public void testCustomizeRedisConfiguration() { + load(CustomConfiguration.class); + LettuceConnectionFactory cf = this.context.getBean(LettuceConnectionFactory.class); + assertThat(cf.isUseSsl()).isTrue(); + } + @Test public void testRedisUrlConfiguration() throws Exception { load("spring.redis.host:foo", @@ -111,7 +121,6 @@ public class RedisAutoConfigurationTests { "spring.redis.lettuce.pool.max-wait:2000"); LettuceConnectionFactory cf = this.context .getBean(LettuceConnectionFactory.class); - assertThat(cf.getHostName()).isEqualTo("foo"); assertThat(getDefaultLettucePool(cf).getHostName()).isEqualTo("foo"); assertThat(getDefaultLettucePool(cf).getPoolConfig().getMinIdle()).isEqualTo(1); assertThat(getDefaultLettucePool(cf).getPoolConfig().getMaxIdle()).isEqualTo(4); @@ -190,11 +199,28 @@ public class RedisAutoConfigurationTests { } private void load(String... environment) { + load(null, environment); + } + + private void load(Class config, String... environment) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); TestPropertyValues.of(environment).applyTo(ctx); + if (config != null) { + ctx.register(config); + } ctx.register(RedisAutoConfiguration.class); ctx.refresh(); this.context = ctx; } + @Configuration + static class CustomConfiguration { + + @Bean + LettuceClientConfigurationBuilderCustomizer customizer() { + return LettuceClientConfigurationBuilder::useSsl; + } + + } + }