Skip to content

Commit d0f17b1

Browse files
committed
Polishing.
Reformat code. Consider sentinel username in JedisConnectionFactory. Update years in license headers. See #2218 Original pull request: #2224.
1 parent f333b18 commit d0f17b1

File tree

10 files changed

+95
-42
lines changed

10 files changed

+95
-42
lines changed

src/main/asciidoc/index.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ ifdef::backend-epub3[:front-cover-image: image:epub-cover.png[Front Cover,1050,1
66
:spring-data-commons-include: ../../../../spring-data-commons/src/main/asciidoc
77
:spring-data-commons-docs: https://raw.githubusercontent.com/spring-projects/spring-data-commons/master/src/main/asciidoc
88

9-
(C) 2011-2021 The original authors.
9+
(C) 2011-2022 The original authors.
1010

1111
NOTE: Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.
1212

src/main/asciidoc/new-features.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

44
This section briefly covers items that are new and noteworthy in the latest releases.
55

6+
[[new-in-2.7.0]]
7+
== New in Spring Data Redis 2.7
8+
9+
* Sentinel ACL authentication considering a sentinel-specific username. Setting a username enables username and password authentication requiring Redis 6.
10+
611
[[new-in-2.6.0]]
712
== New in Spring Data Redis 2.6
813

src/main/asciidoc/reference/redis.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ public RedisConnectionFactory lettuceConnectionFactory() {
319319
.Configuration Properties
320320
* `spring.redis.sentinel.master`: name of the master node.
321321
* `spring.redis.sentinel.nodes`: Comma delimited list of host:port pairs.
322+
* `spring.redis.sentinel.username`: The username to apply when authenticating with Redis Sentinel (requires Redis 6)
322323
* `spring.redis.sentinel.password`: The password to apply when authenticating with Redis Sentinel
323324
====
324325

src/main/java/org/springframework/data/redis/connection/RedisConfiguration.java

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018-2021 the original author or authors.
2+
* Copyright 2018-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -400,6 +400,23 @@ default RedisPassword getDataNodePassword() {
400400
return getPassword();
401401
}
402402

403+
/**
404+
* Create and set a username with the given {@link String}. Requires Redis 6 or newer.
405+
*
406+
* @param sentinelUsername the username for sentinel.
407+
* @since 2.7
408+
*/
409+
void setSentinelUsername(@Nullable String sentinelUsername);
410+
411+
/**
412+
* Get the username to use when connecting.
413+
*
414+
* @return {@literal null} if none set.
415+
* @since 2.7
416+
*/
417+
@Nullable
418+
String getSentinelUsername();
419+
403420
/**
404421
* Create and set a {@link RedisPassword} to be used when authenticating with Redis Sentinel from the given
405422
* {@link String}.
@@ -440,20 +457,6 @@ default void setSentinelPassword(@Nullable char[] password) {
440457
*/
441458
RedisPassword getSentinelPassword();
442459

443-
/**
444-
* Create and set a username with the given {@link String}. Requires Redis 6 or newer.
445-
*
446-
* @param sentinelUsername the username for sentinel.
447-
*/
448-
void setSentinelUsername(@Nullable String sentinelUsername);
449-
450-
/**
451-
* Get the username to use when connecting.
452-
*
453-
* @return {@literal null} if none set.
454-
*/
455-
@Nullable
456-
String getSentinelUsername();
457460
}
458461

459462
/**

src/main/java/org/springframework/data/redis/connection/RedisSentinelConfiguration.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2021 the original author or authors.
2+
* Copyright 2014-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -46,8 +46,8 @@ public class RedisSentinelConfiguration implements RedisConfiguration, SentinelC
4646

4747
private static final String REDIS_SENTINEL_MASTER_CONFIG_PROPERTY = "spring.redis.sentinel.master";
4848
private static final String REDIS_SENTINEL_NODES_CONFIG_PROPERTY = "spring.redis.sentinel.nodes";
49-
private static final String REDIS_SENTINEL_PASSWORD_CONFIG_PROPERTY = "spring.redis.sentinel.password";
5049
private static final String REDIS_SENTINEL_USERNAME_CONFIG_PROPERTY = "spring.redis.sentinel.username";
50+
private static final String REDIS_SENTINEL_PASSWORD_CONFIG_PROPERTY = "spring.redis.sentinel.password";
5151

5252
private @Nullable NamedNode master;
5353
private Set<RedisNode> sentinels;
@@ -343,6 +343,9 @@ public boolean equals(Object o) {
343343
if (!ObjectUtils.nullSafeEquals(dataNodePassword, that.dataNodePassword)) {
344344
return false;
345345
}
346+
if (!ObjectUtils.nullSafeEquals(sentinelUsername, that.sentinelUsername)) {
347+
return false;
348+
}
346349
return ObjectUtils.nullSafeEquals(sentinelPassword, that.sentinelPassword);
347350
}
348351

@@ -357,6 +360,7 @@ public int hashCode() {
357360
result = 31 * result + database;
358361
result = 31 * result + ObjectUtils.nullSafeHashCode(dataNodeUsername);
359362
result = 31 * result + ObjectUtils.nullSafeHashCode(dataNodePassword);
363+
result = 31 * result + ObjectUtils.nullSafeHashCode(sentinelUsername);
360364
result = 31 * result + ObjectUtils.nullSafeHashCode(sentinelPassword);
361365
return result;
362366
}

src/main/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactory.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2021 the original author or authors.
2+
* Copyright 2011-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -360,8 +360,9 @@ public void afterPropertiesSet() {
360360
this.initialized = true;
361361
}
362362

363-
private JedisClientConfig createSentinelClientConfig(SentinelConfiguration sentinelConfiguration) {
364-
return createClientConfig(0, null, sentinelConfiguration.getSentinelPassword());
363+
JedisClientConfig createSentinelClientConfig(SentinelConfiguration sentinelConfiguration) {
364+
return createClientConfig(0, sentinelConfiguration.getSentinelUsername(),
365+
sentinelConfiguration.getSentinelPassword());
365366
}
366367

367368
private JedisClientConfig createClientConfig(int database, @Nullable String username, RedisPassword password) {

src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2021 the original author or authors.
2+
* Copyright 2013-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -516,7 +516,7 @@ public static RedisURI sentinelConfigurationToRedisURI(RedisSentinelConfiguratio
516516
String sentinelUsername = sentinelConfiguration.getSentinelUsername();
517517
if (StringUtils.hasText(sentinelUsername) && sentinelPassword.isPresent()) {
518518
// See https://github.com/lettuce-io/lettuce-core/issues/1404
519-
sentinelBuilder.withAuthentication(sentinelUsername, new String(sentinelPassword.toOptional().orElse((new char[0]))));
519+
sentinelBuilder.withAuthentication(sentinelUsername, sentinelPassword.get());
520520
} else {
521521
sentinelPassword.toOptional().ifPresent(sentinelBuilder::withPassword);
522522
}
@@ -527,9 +527,9 @@ public static RedisURI sentinelConfigurationToRedisURI(RedisSentinelConfiguratio
527527
String username = sentinelConfiguration.getUsername();
528528
RedisPassword password = sentinelConfiguration.getPassword();
529529

530-
if (StringUtils.hasText(username)) {
530+
if (StringUtils.hasText(username) && password.isPresent()) {
531531
// See https://github.com/lettuce-io/lettuce-core/issues/1404
532-
builder.withAuthentication(username, new String(password.toOptional().orElse(new char[0])));
532+
builder.withAuthentication(username, password.get());
533533
} else {
534534
password.toOptional().ifPresent(builder::withPassword);
535535
}

src/test/java/org/springframework/data/redis/connection/RedisSentinelConfigurationUnitTests.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2021 the original author or authors.
2+
* Copyright 2015-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,11 +23,12 @@
2323

2424
import org.junit.jupiter.api.Test;
2525

26-
import org.springframework.core.env.PropertySource;
2726
import org.springframework.mock.env.MockPropertySource;
2827
import org.springframework.util.StringUtils;
2928

3029
/**
30+
* Unit tests for {@link RedisSentinelConfiguration}.
31+
*
3132
* @author Christoph Strobl
3233
* @author Vikas Garg
3334
*/
@@ -134,13 +135,14 @@ void dataNodePasswordDoesNotAffectSentinelPassword() {
134135
assertThat(configuration.getSentinelPassword()).isEqualTo(RedisPassword.none());
135136
}
136137

137-
@Test
138+
@Test // GH-2218
138139
void dataNodeUsernameDoesNotAffectSentinelUsername() {
139140
RedisSentinelConfiguration configuration = new RedisSentinelConfiguration("myMaster",
140141
Collections.singleton(HOST_AND_PORT_1));
142+
configuration.setUsername("data-admin");
141143
configuration.setSentinelUsername("sentinel-admin");
142-
configuration.setUsername("app");
143144

145+
assertThat(configuration.getDataNodeUsername()).isEqualTo("data-admin");
144146
assertThat(configuration.getSentinelUsername()).isEqualTo("sentinel-admin");
145147
}
146148

@@ -158,17 +160,19 @@ void readSentinelPasswordFromConfigProperty() {
158160
assertThat(config.getSentinels()).hasSize(1).contains(new RedisNode("127.0.0.1", 123));
159161
}
160162

161-
@Test
163+
@Test // GH-2218
162164
void readSentinelUsernameFromConfigProperty() {
163165

164166
MockPropertySource propertySource = new MockPropertySource();
165167
propertySource.setProperty("spring.redis.sentinel.master", "myMaster");
166168
propertySource.setProperty("spring.redis.sentinel.nodes", HOST_AND_PORT_1);
167169
propertySource.setProperty("spring.redis.sentinel.username", "sentinel-admin");
170+
propertySource.setProperty("spring.redis.sentinel.password", "foo");
168171

169172
RedisSentinelConfiguration config = new RedisSentinelConfiguration(propertySource);
170173

171-
assertThat(config.getSentinelUsername()).isEqualTo(RedisPassword.of("sentinel-admin"));
174+
assertThat(config.getSentinelUsername()).isEqualTo("sentinel-admin");
175+
assertThat(config.getSentinelPassword()).isEqualTo(RedisPassword.of("foo"));
172176
assertThat(config.getSentinels()).hasSize(1).contains(new RedisNode("127.0.0.1", 123));
173177
}
174178
}

src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactoryUnitTests.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2021 the original author or authors.
2+
* Copyright 2014-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -282,6 +282,20 @@ void shouldReturnSentinelConfiguration() {
282282
assertThat(connectionFactory.getClusterConfiguration()).isNull();
283283
}
284284

285+
@Test // GH-2218
286+
void shouldConsiderSentinelAuthentication() {
287+
288+
RedisSentinelConfiguration configuration = new RedisSentinelConfiguration();
289+
configuration.setSentinelUsername("sentinel");
290+
configuration.setSentinelPassword("the-password");
291+
connectionFactory = new JedisConnectionFactory(configuration, JedisClientConfiguration.defaultConfiguration());
292+
293+
JedisClientConfig clientConfig = connectionFactory.createSentinelClientConfig(configuration);
294+
295+
assertThat(clientConfig.getUser()).isEqualTo("sentinel");
296+
assertThat(clientConfig.getPassword()).isEqualTo("the-password");
297+
}
298+
285299
@Test // DATAREDIS-574
286300
void shouldReturnClusterConfiguration() {
287301

src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConvertersUnitTests.java

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2021 the original author or authors.
2+
* Copyright 2014-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -45,6 +45,8 @@
4545
import org.springframework.data.redis.core.types.RedisClientInfo;
4646

4747
/**
48+
* Unit tests for {@link LettuceConverters}.
49+
*
4850
* @author Christoph Strobl
4951
* @author Vikas Garg
5052
*/
@@ -256,54 +258,73 @@ void convertsExpirationToGetExPXAT() {
256258
.isEqualTo(new GetExArgs().pxAt(10));
257259
}
258260

259-
@Test
261+
@Test // GH-2218
260262
void sentinelConfigurationWithAuth() {
261-
RedisPassword password = RedisPassword.of("88888888-8x8-getting-creative-now");
263+
264+
RedisPassword dataPassword = RedisPassword.of("data-secret");
265+
RedisPassword sentinelPassword = RedisPassword.of("sentinel-secret");
266+
262267
RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration()
263268
.master(MASTER_NAME)
264269
.sentinel("127.0.0.1", 26379)
265270
.sentinel("127.0.0.1", 26380);
266-
sentinelConfiguration.setSentinelUsername("admin");
267-
sentinelConfiguration.setSentinelPassword(password);
268271
sentinelConfiguration.setUsername("app");
269-
sentinelConfiguration.setPassword(password);
272+
sentinelConfiguration.setPassword(dataPassword);
273+
274+
sentinelConfiguration.setSentinelUsername("admin");
275+
sentinelConfiguration.setSentinelPassword(sentinelPassword);
276+
270277
RedisURI redisURI = LettuceConverters.sentinelConfigurationToRedisURI(sentinelConfiguration);
278+
271279
assertThat(redisURI.getUsername()).isEqualTo("app");
280+
assertThat(redisURI.getPassword()).isEqualTo(dataPassword.get());
281+
272282
redisURI.getSentinels().forEach(sentinel -> {
273283
assertThat(sentinel.getUsername()).isEqualTo("admin");
284+
assertThat(sentinel.getPassword()).isEqualTo(sentinelPassword.get());
274285
});
275286
}
276287

277-
@Test
288+
@Test // GH-2218
278289
void sentinelConfigurationSetSentinelPasswordIfUsernameNotPresent() {
290+
279291
RedisPassword password = RedisPassword.of("88888888-8x8-getting-creative-now");
292+
280293
RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration()
281294
.master(MASTER_NAME)
282295
.sentinel("127.0.0.1", 26379)
283296
.sentinel("127.0.0.1", 26380);
284-
sentinelConfiguration.setSentinelPassword(password);
285297
sentinelConfiguration.setUsername("app");
286298
sentinelConfiguration.setPassword(password);
299+
sentinelConfiguration.setSentinelPassword(password);
300+
287301
RedisURI redisURI = LettuceConverters.sentinelConfigurationToRedisURI(sentinelConfiguration);
302+
288303
assertThat(redisURI.getUsername()).isEqualTo("app");
304+
289305
redisURI.getSentinels().forEach(sentinel -> {
290306
assertThat(sentinel.getUsername()).isNull();
291307
assertThat(sentinel.getPassword()).isNotNull();
292308
});
293309
}
294310

295-
@Test
311+
@Test // GH-2218
296312
void sentinelConfigurationShouldNotSetSentinelAuthIfUsernameIsPresentWithNoPassword() {
313+
297314
RedisPassword password = RedisPassword.of("88888888-8x8-getting-creative-now");
315+
298316
RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration()
299317
.master(MASTER_NAME)
300318
.sentinel("127.0.0.1", 26379)
301319
.sentinel("127.0.0.1", 26380);
302-
sentinelConfiguration.setSentinelUsername("admin");
303320
sentinelConfiguration.setUsername("app");
304321
sentinelConfiguration.setPassword(password);
322+
sentinelConfiguration.setSentinelUsername("admin");
323+
305324
RedisURI redisURI = LettuceConverters.sentinelConfigurationToRedisURI(sentinelConfiguration);
325+
306326
assertThat(redisURI.getUsername()).isEqualTo("app");
327+
307328
redisURI.getSentinels().forEach(sentinel -> {
308329
assertThat(sentinel.getUsername()).isNull();
309330
assertThat(sentinel.getPassword()).isNull();

0 commit comments

Comments
 (0)