diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration.java index 6cc58a468d..dca260f473 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration.java @@ -131,7 +131,8 @@ class LettuceConnectionConfiguration extends RedisConnectionConfiguration { if (getProperties().getCluster() != null) { ClusterClientOptions.Builder builder = ClusterClientOptions.builder(); Refresh refreshProperties = getProperties().getLettuce().getCluster().getRefresh(); - Builder refreshBuilder = ClusterTopologyRefreshOptions.builder(); + Builder refreshBuilder = ClusterTopologyRefreshOptions.builder() + .dynamicRefreshSources(refreshProperties.isDynamicRefreshSources()); if (refreshProperties.getPeriod() != null) { refreshBuilder.enablePeriodicRefresh(refreshProperties.getPeriod()); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisProperties.java index 803f60065d..c762541a1d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisProperties.java @@ -399,6 +399,13 @@ public class RedisProperties { public static class Refresh { + /** + * Whether to discover and query all cluster nodes for obtaining the + * cluster topology. When set to false, only the initial seed nodes are + * used as sources for topology discovery. + */ + private boolean dynamicRefreshSources = true; + /** * Cluster topology refresh period. */ @@ -410,6 +417,14 @@ public class RedisProperties { */ private boolean adaptive; + public boolean isDynamicRefreshSources() { + return this.dynamicRefreshSources; + } + + public void setDynamicRefreshSources(boolean dynamicRefreshSources) { + this.dynamicRefreshSources = dynamicRefreshSources; + } + public Duration getPeriod() { return this.period; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java index f6f0c827b1..5a1424d21d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java @@ -25,6 +25,7 @@ import java.util.stream.Collectors; import io.lettuce.core.ClientOptions; import io.lettuce.core.cluster.ClusterClientOptions; +import io.lettuce.core.cluster.ClusterTopologyRefreshOptions; import io.lettuce.core.cluster.ClusterTopologyRefreshOptions.RefreshTrigger; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.junit.jupiter.api.Test; @@ -312,6 +313,36 @@ class RedisAutoConfigurationTests { ClientOptions.class, (options) -> assertThat(options.getClass()).isEqualTo(ClientOptions.class))); } + @Test + void testRedisConfigurationWithClusterDynamicRefreshSourcesEnabled() { + this.contextRunner + .withPropertyValues("spring.redis.cluster.nodes=127.0.0.1:27379,127.0.0.1:27380", + "spring.redis.lettuce.cluster.refresh.dynamic-refresh-sources=true") + .run(assertClientOptions(ClusterClientOptions.class, + (options) -> assertThat(options.getTopologyRefreshOptions().useDynamicRefreshSources()) + .isTrue())); + } + + @Test + void testRedisConfigurationWithClusterDynamicRefreshSourcesDisabled() { + this.contextRunner + .withPropertyValues("spring.redis.cluster.nodes=127.0.0.1:27379,127.0.0.1:27380", + "spring.redis.lettuce.cluster.refresh.dynamic-refresh-sources=false") + .run(assertClientOptions(ClusterClientOptions.class, + (options) -> assertThat(options.getTopologyRefreshOptions().useDynamicRefreshSources()) + .isFalse())); + } + + @Test + void testRedisConfigurationWithClusterDynamicSourcesUnspecifiedUsesDefault() { + this.contextRunner + .withPropertyValues("spring.redis.cluster.nodes=127.0.0.1:27379,127.0.0.1:27380", + "spring.redis.lettuce.cluster.refresh.dynamic-sources=") + .run(assertClientOptions(ClusterClientOptions.class, + (options) -> assertThat(options.getTopologyRefreshOptions().useDynamicRefreshSources()) + .isEqualTo(ClusterTopologyRefreshOptions.DEFAULT_DYNAMIC_REFRESH_SOURCES))); + } + private ContextConsumer assertClientOptions( Class expectedType, Consumer options) { return (context) -> { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisPropertiesTests.java new file mode 100644 index 0000000000..0a42e51a73 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisPropertiesTests.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-2020 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 + * + * https://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 io.lettuce.core.cluster.ClusterTopologyRefreshOptions; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Lettuce; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link RedisProperties}. + * + * @author Stephane Nicoll + */ +class RedisPropertiesTests { + + @Test + void lettuceDefaultsAreConsistent() { + Lettuce lettuce = new RedisProperties().getLettuce(); + ClusterTopologyRefreshOptions defaultClusterTopologyRefreshOptions = ClusterTopologyRefreshOptions.builder() + .build(); + assertThat(lettuce.getCluster().getRefresh().isDynamicRefreshSources()) + .isEqualTo(defaultClusterTopologyRefreshOptions.useDynamicRefreshSources()); + } + +}