Polishing.
Deprecate RedisSentinelConfiguration and RedisClusterConfiguration constructors taking PropertySource in favor of a factory method. Reformat code. Update documentation. See #2860 Original pull request: #2861
This commit is contained in:
@@ -96,7 +96,7 @@ public RedisConnectionFactory jedisConnectionFactory() {
|
||||
|
||||
[TIP]
|
||||
====
|
||||
`RedisSentinelConfiguration` can also be defined with a `PropertySource`, which lets you set the following properties:
|
||||
`RedisSentinelConfiguration` can also be defined through `RedisSentinelConfiguration.of(PropertySource)`, which lets you pick up the following properties:
|
||||
|
||||
.Configuration Properties
|
||||
* `spring.redis.sentinel.master`: name of the master node.
|
||||
@@ -164,7 +164,7 @@ public class AppConfig {
|
||||
|
||||
[TIP]
|
||||
====
|
||||
`RedisClusterConfiguration` can also be defined through `PropertySource` and has the following properties:
|
||||
`RedisClusterConfiguration` can also be defined through `RedisClusterConfiguration.of(PropertySource)`, which lets you pick up the following properties:
|
||||
|
||||
.Configuration Properties
|
||||
- `spring.redis.cluster.nodes`: Comma-delimited list of host:port pairs.
|
||||
|
||||
@@ -51,16 +51,14 @@ public class RedisClusterConfiguration implements RedisConfiguration, ClusterCon
|
||||
|
||||
private RedisPassword password = RedisPassword.none();
|
||||
|
||||
private final Set<RedisNode> clusterNodes;
|
||||
private final Set<RedisNode> clusterNodes = new LinkedHashSet<>();
|
||||
|
||||
private @Nullable String username = null;
|
||||
|
||||
/**
|
||||
* Creates a new, default {@link RedisClusterConfiguration}.
|
||||
*/
|
||||
public RedisClusterConfiguration() {
|
||||
this(new MapPropertySource("RedisClusterConfiguration", Collections.emptyMap()));
|
||||
}
|
||||
public RedisClusterConfiguration() {}
|
||||
|
||||
/**
|
||||
* Creates a new {@link RedisClusterConfiguration} for given {@link String hostPort} combinations.
|
||||
@@ -75,28 +73,31 @@ public class RedisClusterConfiguration implements RedisConfiguration, ClusterCon
|
||||
* @param clusterNodes must not be {@literal null}.
|
||||
*/
|
||||
public RedisClusterConfiguration(Collection<String> clusterNodes) {
|
||||
this(new MapPropertySource("RedisClusterConfiguration", asMap(clusterNodes, -1)));
|
||||
initialize(new MapPropertySource("RedisClusterConfiguration", asMap(clusterNodes, -1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link RedisClusterConfiguration} looking up configuration values from the given
|
||||
* {@link PropertySource}.
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* <pre class="code">
|
||||
* spring.redis.cluster.nodes=127.0.0.1:23679,127.0.0.1:23680,127.0.0.1:23681
|
||||
* spring.redis.cluster.max-redirects=3
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* @param propertySource must not be {@literal null}.
|
||||
* @deprecated since 3.3, use {@link RedisSentinelConfiguration#of(PropertySource)} instead. This constructor will be
|
||||
* made private in the next major release.
|
||||
*/
|
||||
@Deprecated(since = "3.3")
|
||||
public RedisClusterConfiguration(PropertySource<?> propertySource) {
|
||||
initialize(propertySource);
|
||||
}
|
||||
|
||||
private void initialize(PropertySource<?> propertySource) {
|
||||
|
||||
Assert.notNull(propertySource, "PropertySource must not be null");
|
||||
|
||||
this.clusterNodes = new LinkedHashSet<>();
|
||||
|
||||
if (propertySource.containsProperty(REDIS_CLUSTER_NODES_CONFIG_PROPERTY)) {
|
||||
|
||||
Object redisClusterNodes = propertySource.getProperty(REDIS_CLUSTER_NODES_CONFIG_PROPERTY);
|
||||
@@ -109,6 +110,23 @@ public class RedisClusterConfiguration implements RedisConfiguration, ClusterCon
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link RedisClusterConfiguration} looking up configuration values from the given
|
||||
* {@link PropertySource}.
|
||||
*
|
||||
* <pre class="code">
|
||||
* spring.redis.cluster.nodes=127.0.0.1:23679,127.0.0.1:23680,127.0.0.1:23681
|
||||
* spring.redis.cluster.max-redirects=3
|
||||
* </pre>
|
||||
*
|
||||
* @param propertySource must not be {@literal null}.
|
||||
* @return a new {@link RedisClusterConfiguration} configured from the given {@link PropertySource}.
|
||||
* @since 3.3
|
||||
*/
|
||||
public static RedisClusterConfiguration of(PropertySource<?> propertySource) {
|
||||
return new RedisClusterConfiguration(propertySource);
|
||||
}
|
||||
|
||||
private void appendClusterNodes(Set<String> hostAndPorts) {
|
||||
|
||||
for (String hostAndPort : hostAndPorts) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection;
|
||||
|
||||
import static org.springframework.util.StringUtils.commaDelimitedListToSet;
|
||||
import static org.springframework.util.StringUtils.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -32,8 +32,8 @@ import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link RedisConfiguration Configuration} class used to set up a {@link RedisConnection}
|
||||
* with {@link RedisConnectionFactory} for connecting to <a href="https://redis.io/topics/sentinel">Redis Sentinel(s)</a>.
|
||||
* {@link RedisConfiguration Configuration} class used to set up a {@link RedisConnection} with
|
||||
* {@link RedisConnectionFactory} for connecting to <a href="https://redis.io/topics/sentinel">Redis Sentinel(s)</a>.
|
||||
* Useful when setting up a highly available Redis environment.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
@@ -101,7 +101,10 @@ public class RedisSentinelConfiguration implements RedisConfiguration, SentinelC
|
||||
*
|
||||
* @param propertySource must not be {@literal null}.
|
||||
* @since 1.5
|
||||
* @deprecated since 3.3, use {@link RedisSentinelConfiguration#of(PropertySource)} instead. This constructor will be
|
||||
* made private in the next major release.
|
||||
*/
|
||||
@Deprecated(since = "3.3")
|
||||
public RedisSentinelConfiguration(PropertySource<?> propertySource) {
|
||||
|
||||
Assert.notNull(propertySource, "PropertySource must not be null");
|
||||
@@ -153,6 +156,17 @@ public class RedisSentinelConfiguration implements RedisConfiguration, SentinelC
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@link RedisSentinelConfiguration} from the given {@link PropertySource}.
|
||||
*
|
||||
* @param propertySource must not be {@literal null}.
|
||||
* @return a new {@link RedisSentinelConfiguration} configured from the given {@link PropertySource}.
|
||||
* @since 3.3
|
||||
*/
|
||||
public static RedisSentinelConfiguration of(PropertySource<?> propertySource) {
|
||||
return new RedisSentinelConfiguration(propertySource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set {@literal Sentinels} to connect to.
|
||||
*
|
||||
@@ -315,8 +329,7 @@ public class RedisSentinelConfiguration implements RedisConfiguration, SentinelC
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.database == that.database
|
||||
&& ObjectUtils.nullSafeEquals(this.master, that.master)
|
||||
return this.database == that.database && ObjectUtils.nullSafeEquals(this.master, that.master)
|
||||
&& ObjectUtils.nullSafeEquals(this.sentinels, that.sentinels)
|
||||
&& ObjectUtils.nullSafeEquals(this.dataNodeUsername, that.dataNodeUsername)
|
||||
&& ObjectUtils.nullSafeEquals(this.dataNodePassword, that.dataNodePassword)
|
||||
|
||||
@@ -83,8 +83,7 @@ class RedisClusterConfigurationUnitTests {
|
||||
|
||||
@Test // DATAREDIS-315
|
||||
void shouldThrowExceptionWhenListOfHostAndPortIsNull() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new RedisClusterConfiguration(Collections.singleton(null)));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RedisClusterConfiguration(Collections.singleton(null)));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-315
|
||||
@@ -97,13 +96,13 @@ class RedisClusterConfigurationUnitTests {
|
||||
|
||||
@Test // DATAREDIS-315
|
||||
void shouldThrowExceptionGivenNullPropertySource() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RedisClusterConfiguration((PropertySource<?>) null));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> RedisClusterConfiguration.of((PropertySource<?>) null));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-315
|
||||
void shouldNotFailWhenGivenPropertySourceNotContainingRelevantProperties() {
|
||||
|
||||
RedisClusterConfiguration config = new RedisClusterConfiguration(new MockPropertySource());
|
||||
RedisClusterConfiguration config = RedisClusterConfiguration.of(new MockPropertySource());
|
||||
|
||||
assertThat(config.getMaxRedirects()).isNull();
|
||||
assertThat(config.getClusterNodes().size()).isEqualTo(0);
|
||||
@@ -116,7 +115,7 @@ class RedisClusterConfigurationUnitTests {
|
||||
propertySource.setProperty("spring.redis.cluster.nodes", HOST_AND_PORT_1);
|
||||
propertySource.setProperty("spring.redis.cluster.max-redirects", "5");
|
||||
|
||||
RedisClusterConfiguration config = new RedisClusterConfiguration(propertySource);
|
||||
RedisClusterConfiguration config = RedisClusterConfiguration.of(propertySource);
|
||||
|
||||
assertThat(config.getMaxRedirects()).isEqualTo(5);
|
||||
assertThat(config.getClusterNodes()).contains(new RedisNode("127.0.0.1", 123));
|
||||
@@ -130,7 +129,7 @@ class RedisClusterConfigurationUnitTests {
|
||||
StringUtils.collectionToCommaDelimitedString(Arrays.asList(HOST_AND_PORT_1, HOST_AND_PORT_2, HOST_AND_PORT_3)));
|
||||
propertySource.setProperty("spring.redis.cluster.max-redirects", "5");
|
||||
|
||||
RedisClusterConfiguration config = new RedisClusterConfiguration(propertySource);
|
||||
RedisClusterConfiguration config = RedisClusterConfiguration.of(propertySource);
|
||||
|
||||
assertThat(config.getMaxRedirects()).isEqualTo(5);
|
||||
assertThat(config.getClusterNodes()).contains(new RedisNode("127.0.0.1", 123), new RedisNode("localhost", 456),
|
||||
@@ -138,7 +137,7 @@ class RedisClusterConfigurationUnitTests {
|
||||
}
|
||||
|
||||
@Test // GH-2360
|
||||
public void shouldBeCreatedCorrectlyGivenValidPropertySourceWithMultipleIPv6AddressesAndPorts() {
|
||||
void shouldBeCreatedCorrectlyGivenValidPropertySourceWithMultipleIPv6AddressesAndPorts() {
|
||||
|
||||
MockPropertySource propertySource = new MockPropertySource();
|
||||
|
||||
@@ -146,7 +145,7 @@ class RedisClusterConfigurationUnitTests {
|
||||
StringUtils.collectionToCommaDelimitedString(Arrays.asList(HOST_AND_PORT_4, HOST_AND_PORT_5)));
|
||||
propertySource.setProperty("spring.redis.cluster.max-redirects", 2);
|
||||
|
||||
RedisClusterConfiguration configuration = new RedisClusterConfiguration(propertySource);
|
||||
RedisClusterConfiguration configuration = RedisClusterConfiguration.of(propertySource);
|
||||
|
||||
assertThat(configuration.getMaxRedirects()).isEqualTo(2);
|
||||
assertThat(configuration.getClusterNodes()).contains(new RedisNode("fe80::a00:27ff:fe4b:ee48", 6379),
|
||||
|
||||
@@ -96,13 +96,13 @@ class RedisSentinelConfigurationUnitTests {
|
||||
|
||||
@Test // DATAREDIS-372
|
||||
void shouldThrowExceptionGivenNullPropertySource() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RedisSentinelConfiguration(null));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> RedisSentinelConfiguration.of(null));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-372
|
||||
void shouldNotFailWhenGivenPropertySourceNotContainingRelevantProperties() {
|
||||
|
||||
RedisSentinelConfiguration config = new RedisSentinelConfiguration(new MockPropertySource());
|
||||
RedisSentinelConfiguration config = RedisSentinelConfiguration.of(new MockPropertySource());
|
||||
|
||||
assertThat(config.getMaster()).isNull();
|
||||
assertThat(config.getSentinels()).isEmpty();
|
||||
@@ -115,7 +115,7 @@ class RedisSentinelConfigurationUnitTests {
|
||||
propertySource.setProperty("spring.redis.sentinel.master", "myMaster");
|
||||
propertySource.setProperty("spring.redis.sentinel.nodes", HOST_AND_PORT_1);
|
||||
|
||||
RedisSentinelConfiguration config = new RedisSentinelConfiguration(propertySource);
|
||||
RedisSentinelConfiguration config = RedisSentinelConfiguration.of(propertySource);
|
||||
|
||||
assertThat(config.getMaster()).isNotNull();
|
||||
assertThat(config.getMaster().getName()).isEqualTo("myMaster");
|
||||
@@ -131,7 +131,7 @@ class RedisSentinelConfigurationUnitTests {
|
||||
propertySource.setProperty("spring.redis.sentinel.nodes",
|
||||
StringUtils.collectionToCommaDelimitedString(Arrays.asList(HOST_AND_PORT_1, HOST_AND_PORT_2, HOST_AND_PORT_3)));
|
||||
|
||||
RedisSentinelConfiguration config = new RedisSentinelConfiguration(propertySource);
|
||||
RedisSentinelConfiguration config = RedisSentinelConfiguration.of(propertySource);
|
||||
|
||||
assertThat(config.getSentinels()).hasSize(3);
|
||||
assertThat(config.getSentinels()).contains(new RedisNode("127.0.0.1", 123), new RedisNode("localhost", 456),
|
||||
@@ -151,6 +151,7 @@ class RedisSentinelConfigurationUnitTests {
|
||||
|
||||
@Test // GH-2218
|
||||
void dataNodeUsernameDoesNotAffectSentinelUsername() {
|
||||
|
||||
RedisSentinelConfiguration configuration = new RedisSentinelConfiguration("myMaster",
|
||||
Collections.singleton(HOST_AND_PORT_1));
|
||||
configuration.setUsername("data-admin");
|
||||
@@ -168,7 +169,7 @@ class RedisSentinelConfigurationUnitTests {
|
||||
propertySource.setProperty("spring.redis.sentinel.nodes", HOST_AND_PORT_1);
|
||||
propertySource.setProperty("spring.redis.sentinel.password", "computer-says-no");
|
||||
|
||||
RedisSentinelConfiguration config = new RedisSentinelConfiguration(propertySource);
|
||||
RedisSentinelConfiguration config = RedisSentinelConfiguration.of(propertySource);
|
||||
|
||||
assertThat(config.getSentinelPassword()).isEqualTo(RedisPassword.of("computer-says-no"));
|
||||
assertThat(config.getSentinels()).hasSize(1).contains(new RedisNode("127.0.0.1", 123));
|
||||
@@ -183,7 +184,7 @@ class RedisSentinelConfigurationUnitTests {
|
||||
propertySource.setProperty("spring.redis.sentinel.username", "sentinel-admin");
|
||||
propertySource.setProperty("spring.redis.sentinel.password", "foo");
|
||||
|
||||
RedisSentinelConfiguration config = new RedisSentinelConfiguration(propertySource);
|
||||
RedisSentinelConfiguration config = RedisSentinelConfiguration.of(propertySource);
|
||||
|
||||
assertThat(config.getSentinelUsername()).isEqualTo("sentinel-admin");
|
||||
assertThat(config.getSentinelPassword()).isEqualTo(RedisPassword.of("foo"));
|
||||
@@ -192,40 +193,44 @@ class RedisSentinelConfigurationUnitTests {
|
||||
|
||||
@Test // GH-2860
|
||||
void readSentinelDataNodeUsernameFromConfigProperty() {
|
||||
|
||||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.redis.sentinel.dataNode.username", "datanode-user");
|
||||
|
||||
RedisSentinelConfiguration config = new RedisSentinelConfiguration(propertySource);
|
||||
RedisSentinelConfiguration config = RedisSentinelConfiguration.of(propertySource);
|
||||
|
||||
assertThat(config.getDataNodeUsername()).isEqualTo("datanode-user");
|
||||
}
|
||||
|
||||
@Test // GH-2860
|
||||
void readSentinelDataNodePasswordFromConfigProperty() {
|
||||
|
||||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.redis.sentinel.dataNode.password", "datanode-password");
|
||||
|
||||
RedisSentinelConfiguration config = new RedisSentinelConfiguration(propertySource);
|
||||
RedisSentinelConfiguration config = RedisSentinelConfiguration.of(propertySource);
|
||||
|
||||
assertThat(config.getDataNodePassword()).isEqualTo(RedisPassword.of("datanode-password"));
|
||||
}
|
||||
|
||||
@Test // GH-2860
|
||||
void readSentinelDataNodeDatabaseFromConfigProperty() {
|
||||
|
||||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.redis.sentinel.dataNode.database", "5");
|
||||
|
||||
RedisSentinelConfiguration config = new RedisSentinelConfiguration(propertySource);
|
||||
RedisSentinelConfiguration config = RedisSentinelConfiguration.of(propertySource);
|
||||
|
||||
assertThat(config.getDatabase()).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test // GH-2860
|
||||
void shouldThrowErrorWhen() {
|
||||
|
||||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.redis.sentinel.dataNode.database", "thisIsNotAnInteger");
|
||||
|
||||
ThrowableAssert.ThrowingCallable call = () -> new RedisSentinelConfiguration(propertySource);
|
||||
ThrowableAssert.ThrowingCallable call = () -> RedisSentinelConfiguration.of(propertySource);
|
||||
|
||||
assertThatThrownBy(call).isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("Invalid DB index '%s'; integer required", "thisIsNotAnInteger");
|
||||
@@ -233,10 +238,11 @@ class RedisSentinelConfigurationUnitTests {
|
||||
|
||||
@Test // GH-2860
|
||||
void shouldThrowErrorWhen2() {
|
||||
|
||||
MockPropertySource propertySource = new MockPropertySource();
|
||||
propertySource.setProperty("spring.redis.sentinel.dataNode.database", "null");
|
||||
|
||||
ThrowableAssert.ThrowingCallable call = () -> new RedisSentinelConfiguration(propertySource);
|
||||
ThrowableAssert.ThrowingCallable call = () -> RedisSentinelConfiguration.of(propertySource);
|
||||
|
||||
assertThatThrownBy(call).isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("Invalid DB index '%s'; integer required", "null");
|
||||
|
||||
Reference in New Issue
Block a user