diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionConfiguration.java index b870e4a550..12ef2a41c9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/RedisConnectionConfiguration.java @@ -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"); * you may not use this file except in compliance with the License. @@ -99,6 +99,7 @@ abstract class RedisConnectionConfiguration { if (this.properties.getPassword() != null) { config.setPassword(RedisPassword.of(this.properties.getPassword())); } + config.setSentinelUsername(sentinelProperties.getUsername()); if (sentinelProperties.getPassword() != null) { config.setSentinelPassword(RedisPassword.of(sentinelProperties.getPassword())); } 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 d61f578a9f..89cb977a62 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 @@ -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"); * you may not use this file except in compliance with the License. @@ -372,6 +372,11 @@ public class RedisProperties { */ private List nodes; + /** + * Login username for authenticating with sentinel(s). + */ + private String username; + /** * Password for authenticating with sentinel(s). */ @@ -393,6 +398,14 @@ public class RedisProperties { this.nodes = nodes; } + public String getUsername() { + return this.username; + } + + public void setUsername(String username) { + this.username = username; + } + public String getPassword() { return this.password; } 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 cbc0855035..d2547a75a8 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 @@ -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"); * you may not use this file except in compliance with the License. @@ -292,34 +292,57 @@ class RedisAutoConfigurationTests { @Test void testRedisConfigurationWithSentinelAndAuthentication() { - this.contextRunner.withPropertyValues("spring.redis.username=user", "spring.redis.password=password", - "spring.redis.sentinel.master:mymaster", - "spring.redis.sentinel.nodes:127.0.0.1:26379, 127.0.0.1:26380").run((context) -> { - LettuceConnectionFactory connectionFactory = context.getBean(LettuceConnectionFactory.class); - assertThat(getUserName(connectionFactory)).isEqualTo("user"); - assertThat(connectionFactory.getPassword()).isEqualTo("password"); - RedisSentinelConfiguration sentinelConfiguration = connectionFactory.getSentinelConfiguration(); + this.contextRunner + .withPropertyValues("spring.redis.username=user", "spring.redis.password=password", + "spring.redis.sentinel.master:mymaster", + "spring.redis.sentinel.nodes:127.0.0.1:26379, 127.0.0.1:26380") + .run(assertSentinelConfiguration("user", "password", (sentinelConfiguration) -> { assertThat(sentinelConfiguration.getSentinelPassword().isPresent()).isFalse(); - Set sentinels = connectionFactory.getSentinelConfiguration().getSentinels(); + Set sentinels = sentinelConfiguration.getSentinels(); assertThat(sentinels.stream().map(Object::toString).collect(Collectors.toSet())) .contains("127.0.0.1:26379", "127.0.0.1:26380"); - }); + })); } @Test void testRedisConfigurationWithSentinelPasswordAndDataNodePassword() { - this.contextRunner.withPropertyValues("spring.redis.password=password", "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((context) -> { - LettuceConnectionFactory connectionFactory = context.getBean(LettuceConnectionFactory.class); - assertThat(getUserName(connectionFactory)).isNull(); - assertThat(connectionFactory.getPassword()).isEqualTo("password"); - RedisSentinelConfiguration sentinelConfiguration = connectionFactory.getSentinelConfiguration(); + this.contextRunner + .withPropertyValues("spring.redis.password=password", "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(null, "password", (sentinelConfiguration) -> { + assertThat(sentinelConfiguration.getSentinelUsername()).isNull(); assertThat(new String(sentinelConfiguration.getSentinelPassword().get())).isEqualTo("secret"); Set sentinels = sentinelConfiguration.getSentinels(); assertThat(sentinels.stream().map(Object::toString).collect(Collectors.toSet())) .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 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 assertSentinelConfiguration(String userName, String password, + Consumer 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