Polishing.

Reorder methods. Remove unnecessary null guards. Introduce hashCode/equals methods to RedisConfiguration implementations. Refactor tests. Let LettuceClientConfiguration.builder apply settings from RedisURI. Introduce SentinelMasterId to implement equals method.

See #2116.
Original pull request: #2117.
This commit is contained in:
Mark Paluch
2021-07-13 16:19:43 +02:00
parent 19e9e7483b
commit 3286d57691
14 changed files with 550 additions and 252 deletions

View File

@@ -18,12 +18,13 @@ package org.springframework.data.redis.connection.lettuce;
import static org.assertj.core.api.Assertions.*;
import io.lettuce.core.ClientOptions;
import io.lettuce.core.RedisURI;
import io.lettuce.core.TimeoutOptions;
import io.lettuce.core.resource.ClientResources;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import org.springframework.data.redis.test.extension.LettuceTestClientResources;
@@ -105,4 +106,29 @@ class LettuceClientConfigurationUnitTests {
void clientConfigurationThrowsExceptionForEmptyClientName() {
assertThatIllegalArgumentException().isThrownBy(() -> LettuceClientConfiguration.builder().clientName(" "));
}
@Test // GH-2116
void shouldApplySettingsFromRedisURI() {
LettuceClientConfiguration configuration = LettuceClientConfiguration.builder() //
.apply(RedisURI.create("rediss://foo?verifyPeer=FULL&clientName=bar&timeout=10s")).build();
assertThat(configuration.isUseSsl()).isTrue();
assertThat(configuration.isVerifyPeer()).isTrue();
assertThat(configuration.isStartTls()).isFalse();
assertThat(configuration.getClientName()).contains("bar");
assertThat(configuration.getCommandTimeout()).isEqualTo(Duration.ofSeconds(10));
}
@Test // GH-2116
void emptySettingsRetainClientConfiguration() {
LettuceClientConfiguration configuration = LettuceClientConfiguration.builder() //
.clientName("hello") //
.commandTimeout(Duration.ofMillis(1)) //
.apply(RedisURI.create("rediss://foo")).build();
assertThat(configuration.getClientName()).contains("hello");
assertThat(configuration.getCommandTimeout()).isEqualTo(Duration.ofMillis(1));
}
}

View File

@@ -1,193 +0,0 @@
/*
* Copyright 2015-2021 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.data.redis.connection.lettuce;
import static org.assertj.core.api.Assertions.*;
import io.lettuce.core.RedisURI;
import org.assertj.core.api.recursive.comparison.RecursiveComparisonConfiguration;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.data.redis.connection.RedisConfiguration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.RedisSocketConfiguration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
/**
* Unit tests for the {@link LettuceConnectionFactory#createRedisConfiguration(RedisURI)} factory method.
*
* @author Chris Bono
*/
class LettuceConnectionFactoryCreateRedisConfigurationUnitTests {
@Test
void requiresRedisURI() {
assertThatThrownBy(() -> LettuceConnectionFactory.createRedisConfiguration(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("RedisURI must not be null");
}
@Nested // GH-2117
class CreateRedisSentinelConfiguration {
@Test
void minimalFieldsSetOnRedisURI() {
RedisURI redisURI = RedisURI.create("redis-sentinel://myserver?sentinelMasterId=5150");
RedisSentinelConfiguration expectedSentinelConfiguration = new RedisSentinelConfiguration();
expectedSentinelConfiguration.setMaster("5150");
expectedSentinelConfiguration.addSentinel(new RedisNode("myserver", 26379));
RedisConfiguration sentinelConfiguration = LettuceConnectionFactory.createRedisConfiguration(redisURI);
assertThat(sentinelConfiguration).usingRecursiveComparison(sentinelCompareConfig())
.isInstanceOf(RedisSentinelConfiguration.class)
.isEqualTo(expectedSentinelConfiguration);
}
@Test
void allFieldsSetOnRedisURI() {
RedisURI redisURI = RedisURI.create("redis-sentinel://fooUser:fooPass@myserver1:111,myserver2:222/7?sentinelMasterId=5150");
// Set the passwords directly on the sentinels so that it gets picked up by converter
char[] sentinelPass = "changeme".toCharArray();
redisURI.getSentinels().forEach(sentinelRedisUri -> sentinelRedisUri.setPassword(sentinelPass));
RedisSentinelConfiguration expectedSentinelConfiguration = new RedisSentinelConfiguration();
expectedSentinelConfiguration.setMaster("5150");
expectedSentinelConfiguration.setDatabase(7);
expectedSentinelConfiguration.setUsername("fooUser");
expectedSentinelConfiguration.setPassword("fooPass");
expectedSentinelConfiguration.setSentinelPassword(sentinelPass);
expectedSentinelConfiguration.addSentinel(new RedisNode("myserver1", 111));
expectedSentinelConfiguration.addSentinel(new RedisNode("myserver2", 222));
RedisConfiguration sentinelConfiguration = LettuceConnectionFactory.createRedisConfiguration(redisURI);
assertThat(sentinelConfiguration).usingRecursiveComparison(sentinelCompareConfig())
.isInstanceOf(RedisSentinelConfiguration.class)
.isEqualTo(expectedSentinelConfiguration);
}
// RedisSentinelConfiguration does not provide equals impl
private RecursiveComparisonConfiguration sentinelCompareConfig() {
return RecursiveComparisonConfiguration.builder().withComparedFields(
"master",
"username",
"password",
"sentinelPassword",
"database",
"sentinels")
.build();
}
}
@Nested // GH-2117
class CreateRedisSocketConfiguration {
@Test
void minimalFieldsSetOnRedisURI() {
RedisURI redisURI = RedisURI.builder()
.socket("mysocket")
.build();
RedisSocketConfiguration expectedSocketConfiguration = new RedisSocketConfiguration();
expectedSocketConfiguration.setSocket("mysocket");
RedisConfiguration socketConfiguration = LettuceConnectionFactory.createRedisConfiguration(redisURI);
assertThat(socketConfiguration).usingRecursiveComparison(socketCompareConfig())
.isInstanceOf(RedisSocketConfiguration.class)
.isEqualTo(expectedSocketConfiguration);
}
@Test
void allFieldsSetOnRedisURI() {
RedisURI redisURI = RedisURI.builder()
.socket("mysocket")
.withAuthentication("fooUser", "fooPass".toCharArray())
.withDatabase(7)
.build();
RedisSocketConfiguration expectedSocketConfiguration = new RedisSocketConfiguration();
expectedSocketConfiguration.setSocket("mysocket");
expectedSocketConfiguration.setUsername("fooUser");
expectedSocketConfiguration.setPassword("fooPass");
expectedSocketConfiguration.setDatabase(7);
RedisConfiguration socketConfiguration = LettuceConnectionFactory.createRedisConfiguration(redisURI);
assertThat(socketConfiguration).usingRecursiveComparison(socketCompareConfig())
.isInstanceOf(RedisSocketConfiguration.class)
.isEqualTo(expectedSocketConfiguration);
}
// RedisSocketConfiguration does not provide equals impl
private RecursiveComparisonConfiguration socketCompareConfig() {
return RecursiveComparisonConfiguration.builder().withComparedFields(
"socket",
"username",
"password",
"database")
.build();
}
}
@Nested // GH-2117
class CreateRedisStandaloneConfiguration {
@Test
void minimalFieldsSetOnRedisURI() {
RedisURI redisURI = RedisURI.create("redis://myserver");
RedisStandaloneConfiguration expectedStandaloneConfiguration = new RedisStandaloneConfiguration();
expectedStandaloneConfiguration.setHostName("myserver");
RedisConfiguration StandaloneConfiguration = LettuceConnectionFactory.createRedisConfiguration(redisURI);
assertThat(StandaloneConfiguration).usingRecursiveComparison(standaloneCompareConfig())
.isInstanceOf(RedisStandaloneConfiguration.class)
.isEqualTo(expectedStandaloneConfiguration);
}
@Test
void allFieldsSetOnRedisURI() {
RedisURI redisURI = RedisURI.create("redis://fooUser:fooPass@myserver1:111/7");
RedisStandaloneConfiguration expectedStandaloneConfiguration = new RedisStandaloneConfiguration();
expectedStandaloneConfiguration.setHostName("myserver1");
expectedStandaloneConfiguration.setPort(111);
expectedStandaloneConfiguration.setDatabase(7);
expectedStandaloneConfiguration.setUsername("fooUser");
expectedStandaloneConfiguration.setPassword("fooPass");
RedisConfiguration StandaloneConfiguration = LettuceConnectionFactory.createRedisConfiguration(redisURI);
assertThat(StandaloneConfiguration).usingRecursiveComparison(standaloneCompareConfig())
.isInstanceOf(RedisStandaloneConfiguration.class)
.isEqualTo(expectedStandaloneConfiguration);
}
// RedisStandaloneConfiguration does not provide equals impl
private RecursiveComparisonConfiguration standaloneCompareConfig() {
return RecursiveComparisonConfiguration.builder().withComparedFields(
"host",
"port",
"username",
"password",
"database")
.build();
}
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2015-2021 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.data.redis.connection.lettuce;
import io.lettuce.core.RedisURI;
/**
* Unit tests for the {@link LettuceConnectionFactory#createRedisConfiguration(RedisURI)} factory method.
*
* @author Chris Bono
*/
class LettuceConnectionFactoryRedisURITests {
}

View File

@@ -56,6 +56,7 @@ import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisClusterConnection;
import org.springframework.data.redis.connection.RedisConfiguration;
import org.springframework.data.redis.connection.RedisConnection;
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.RedisSocketConfiguration;
@@ -72,6 +73,7 @@ import org.springframework.test.util.ReflectionTestUtils;
* @author Ruben Cervilla
* @author Luis De Bello
* @author Andrea Como
* @author Chris Bono
*/
class LettuceConnectionFactoryUnitTests {
@@ -1026,6 +1028,110 @@ class LettuceConnectionFactoryUnitTests {
assertThatIllegalStateException().isThrownBy(connectionFactory::getReactiveClusterConnection);
}
@Test // GH-2116
void createRedisConfigurationRequiresRedisUri() {
assertThatIllegalArgumentException()
.isThrownBy(() -> LettuceConnectionFactory.createRedisConfiguration((RedisURI) null))
.withMessage("RedisURI must not be null");
}
@Test // GH-2116
void createMinimalRedisStandaloneConfiguration() {
RedisURI redisURI = RedisURI.create("redis://myserver");
RedisStandaloneConfiguration expected = new RedisStandaloneConfiguration();
expected.setHostName("myserver");
RedisConfiguration configuration = LettuceConnectionFactory.createRedisConfiguration(redisURI);
assertThat(configuration).isEqualTo(expected);
}
@Test // GH-2116
void createFullRedisStanaloneConfiguration() {
RedisURI redisURI = RedisURI.create("redis://fooUser:fooPass@myserver1:111/7");
RedisStandaloneConfiguration expected = new RedisStandaloneConfiguration();
expected.setHostName("myserver1");
expected.setPort(111);
expected.setDatabase(7);
expected.setUsername("fooUser");
expected.setPassword("fooPass");
RedisConfiguration configuration = LettuceConnectionFactory.createRedisConfiguration(redisURI);
assertThat(configuration).isEqualTo(expected);
}
@Test // GH-2116
void createMinimalRedisSocketConfiguration() {
RedisURI redisURI = RedisURI.Builder.socket("mysocket").build();
RedisSocketConfiguration expected = new RedisSocketConfiguration();
expected.setSocket("mysocket");
RedisConfiguration socketConfiguration = LettuceConnectionFactory.createRedisConfiguration(redisURI);
assertThat(socketConfiguration).isEqualTo(expected);
}
@Test // GH-2116
void createFullRedisSocketConfiguration() {
RedisURI redisURI = RedisURI.Builder.socket("mysocket").withAuthentication("fooUser", "fooPass".toCharArray())
.withDatabase(7).build();
RedisSocketConfiguration expected = new RedisSocketConfiguration();
expected.setSocket("mysocket");
expected.setUsername("fooUser");
expected.setPassword("fooPass");
expected.setDatabase(7);
RedisConfiguration socketConfiguration = LettuceConnectionFactory.createRedisConfiguration(redisURI);
assertThat(socketConfiguration).isEqualTo(expected);
}
@Test // GH-2116
void createMinimalRedisSentinelConfiguration() {
RedisURI redisURI = RedisURI.create("redis-sentinel://myserver?sentinelMasterId=5150");
RedisSentinelConfiguration expected = new RedisSentinelConfiguration();
expected.setMaster("5150");
expected.addSentinel(new RedisNode("myserver", 26379));
RedisConfiguration sentinelConfiguration = LettuceConnectionFactory.createRedisConfiguration(redisURI);
assertThat(sentinelConfiguration).isEqualTo(expected);
}
@Test // GH-2116
void createFullRedisSentinelConfiguration() {
RedisURI redisURI = RedisURI
.create("redis-sentinel://fooUser:fooPass@myserver1:111,myserver2:222/7?sentinelMasterId=5150");
// Set the passwords directly on the sentinels so that it gets picked up by converter
char[] sentinelPass = "changeme".toCharArray();
redisURI.getSentinels().forEach(sentinelRedisUri -> sentinelRedisUri.setPassword(sentinelPass));
RedisSentinelConfiguration expected = new RedisSentinelConfiguration();
expected.setMaster("5150");
expected.setDatabase(7);
expected.setUsername("fooUser");
expected.setPassword("fooPass");
expected.setSentinelPassword(sentinelPass);
expected.addSentinel(new RedisNode("myserver1", 111));
expected.addSentinel(new RedisNode("myserver2", 222));
RedisConfiguration configuration = LettuceConnectionFactory.createRedisConfiguration(redisURI);
assertThat(configuration).isEqualTo(expected);
}
@Data
@AllArgsConstructor
static class CustomRedisConfiguration implements RedisConfiguration, WithHostAndPort {