Merge pull request #29661 from mourezwell

* pr/29661:
  Polish "Add support for Redis sentinel username"
  Add support for Redis sentinel username

Closes gh-29661
This commit is contained in:
Stephane Nicoll 2022-02-21 09:55:07 +01:00
commit 14c9147621
3 changed files with 57 additions and 20 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2021 the original author or authors. * Copyright 2012-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -99,6 +99,7 @@ abstract class RedisConnectionConfiguration {
if (this.properties.getPassword() != null) { if (this.properties.getPassword() != null) {
config.setPassword(RedisPassword.of(this.properties.getPassword())); config.setPassword(RedisPassword.of(this.properties.getPassword()));
} }
config.setSentinelUsername(sentinelProperties.getUsername());
if (sentinelProperties.getPassword() != null) { if (sentinelProperties.getPassword() != null) {
config.setSentinelPassword(RedisPassword.of(sentinelProperties.getPassword())); config.setSentinelPassword(RedisPassword.of(sentinelProperties.getPassword()));
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2021 the original author or authors. * Copyright 2012-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -372,6 +372,11 @@ public class RedisProperties {
*/ */
private List<String> nodes; private List<String> nodes;
/**
* Login username for authenticating with sentinel(s).
*/
private String username;
/** /**
* Password for authenticating with sentinel(s). * Password for authenticating with sentinel(s).
*/ */
@ -393,6 +398,14 @@ public class RedisProperties {
this.nodes = nodes; this.nodes = nodes;
} }
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() { public String getPassword() {
return this.password; return this.password;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2021 the original author or authors. * Copyright 2012-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -292,34 +292,57 @@ class RedisAutoConfigurationTests {
@Test @Test
void testRedisConfigurationWithSentinelAndAuthentication() { void testRedisConfigurationWithSentinelAndAuthentication() {
this.contextRunner.withPropertyValues("spring.redis.username=user", "spring.redis.password=password", this.contextRunner
"spring.redis.sentinel.master:mymaster", .withPropertyValues("spring.redis.username=user", "spring.redis.password=password",
"spring.redis.sentinel.nodes:127.0.0.1:26379, 127.0.0.1:26380").run((context) -> { "spring.redis.sentinel.master:mymaster",
LettuceConnectionFactory connectionFactory = context.getBean(LettuceConnectionFactory.class); "spring.redis.sentinel.nodes:127.0.0.1:26379, 127.0.0.1:26380")
assertThat(getUserName(connectionFactory)).isEqualTo("user"); .run(assertSentinelConfiguration("user", "password", (sentinelConfiguration) -> {
assertThat(connectionFactory.getPassword()).isEqualTo("password");
RedisSentinelConfiguration sentinelConfiguration = connectionFactory.getSentinelConfiguration();
assertThat(sentinelConfiguration.getSentinelPassword().isPresent()).isFalse(); assertThat(sentinelConfiguration.getSentinelPassword().isPresent()).isFalse();
Set<RedisNode> sentinels = connectionFactory.getSentinelConfiguration().getSentinels(); Set<RedisNode> sentinels = sentinelConfiguration.getSentinels();
assertThat(sentinels.stream().map(Object::toString).collect(Collectors.toSet())) assertThat(sentinels.stream().map(Object::toString).collect(Collectors.toSet()))
.contains("127.0.0.1:26379", "127.0.0.1:26380"); .contains("127.0.0.1:26379", "127.0.0.1:26380");
}); }));
} }
@Test @Test
void testRedisConfigurationWithSentinelPasswordAndDataNodePassword() { void testRedisConfigurationWithSentinelPasswordAndDataNodePassword() {
this.contextRunner.withPropertyValues("spring.redis.password=password", "spring.redis.sentinel.password=secret", this.contextRunner
"spring.redis.sentinel.master:mymaster", .withPropertyValues("spring.redis.password=password", "spring.redis.sentinel.password=secret",
"spring.redis.sentinel.nodes:127.0.0.1:26379, 127.0.0.1:26380").run((context) -> { "spring.redis.sentinel.master:mymaster",
LettuceConnectionFactory connectionFactory = context.getBean(LettuceConnectionFactory.class); "spring.redis.sentinel.nodes:127.0.0.1:26379, 127.0.0.1:26380")
assertThat(getUserName(connectionFactory)).isNull(); .run(assertSentinelConfiguration(null, "password", (sentinelConfiguration) -> {
assertThat(connectionFactory.getPassword()).isEqualTo("password"); assertThat(sentinelConfiguration.getSentinelUsername()).isNull();
RedisSentinelConfiguration sentinelConfiguration = connectionFactory.getSentinelConfiguration();
assertThat(new String(sentinelConfiguration.getSentinelPassword().get())).isEqualTo("secret"); assertThat(new String(sentinelConfiguration.getSentinelPassword().get())).isEqualTo("secret");
Set<RedisNode> sentinels = sentinelConfiguration.getSentinels(); Set<RedisNode> sentinels = sentinelConfiguration.getSentinels();
assertThat(sentinels.stream().map(Object::toString).collect(Collectors.toSet())) assertThat(sentinels.stream().map(Object::toString).collect(Collectors.toSet()))
.contains("127.0.0.1:26379", "127.0.0.1:26380"); .contains("127.0.0.1:26379", "127.0.0.1:26380");
}); }));
}
@Test
void testRedisConfigurationWithSentinelAuthenticationAndDataNodeAuthentication() {
this.contextRunner
.withPropertyValues("spring.redis.username=username", "spring.redis.password=password",
"spring.redis.sentinel.username=sentinel", "spring.redis.sentinel.password=secret",
"spring.redis.sentinel.master:mymaster",
"spring.redis.sentinel.nodes:127.0.0.1:26379, 127.0.0.1:26380")
.run(assertSentinelConfiguration("username", "password", (sentinelConfiguration) -> {
assertThat(sentinelConfiguration.getSentinelUsername()).isEqualTo("sentinel");
assertThat(new String(sentinelConfiguration.getSentinelPassword().get())).isEqualTo("secret");
Set<RedisNode> sentinels = sentinelConfiguration.getSentinels();
assertThat(sentinels.stream().map(Object::toString).collect(Collectors.toSet()))
.contains("127.0.0.1:26379", "127.0.0.1:26380");
}));
}
private ContextConsumer<AssertableApplicationContext> assertSentinelConfiguration(String userName, String password,
Consumer<RedisSentinelConfiguration> sentinelConfiguration) {
return (context) -> {
LettuceConnectionFactory connectionFactory = context.getBean(LettuceConnectionFactory.class);
assertThat(getUserName(connectionFactory)).isEqualTo(userName);
assertThat(connectionFactory.getPassword()).isEqualTo(password);
assertThat(connectionFactory.getSentinelConfiguration()).satisfies(sentinelConfiguration);
};
} }
@Test @Test