Skip to content

Commit 717a196

Browse files
mp911dechristophstrobl
authored andcommitted
DATAREDIS-1145 - Support Sentinel password for Jedis.
We now support password-protected Sentinel configurations when using Jedis. Original Pull Request: #558
1 parent d97c5df commit 717a196

File tree

6 files changed

+86
-9
lines changed

6 files changed

+86
-9
lines changed

Makefile

+22-2
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,29 @@ work/sentinel-%.conf:
9393
echo save \"\" >> $@
9494
echo sentinel monitor mymaster 127.0.0.1 6379 2 >> $@
9595

96+
# Password-protected Sentinel
97+
work/sentinel-26382.conf:
98+
@mkdir -p $(@D)
99+
100+
echo port 26382 >> $@
101+
echo daemonize yes >> $@
102+
echo protected-mode no >> $@
103+
echo bind 0.0.0.0 >> $@
104+
echo pidfile $(shell pwd)/work/sentinel-26382.pid >> $@
105+
echo logfile $(shell pwd)/work/sentinel-26382.log >> $@
106+
echo save \"\" >> $@
107+
echo "requirepass foobared" >> $@
108+
echo "user default on #1b58ee375b42e41f0e48ef2ff27d10a5b1f6924a9acdcdba7cae868e7adce6bf ~* +@all" >> $@
109+
echo "user spring on #3a6eb0790f39ac87c94f3856b2dd2c5d110e6811602261a9a923d3bb23adc8b7 +@all" >> $@
110+
echo sentinel monitor mymaster 127.0.0.1 6382 2 >> $@
111+
echo sentinel auth-pass mymaster foobared >> $@
112+
96113
work/sentinel-%.pid: work/sentinel-%.conf work/redis-6379.pid work/redis/bin/redis-server
97114
work/redis/bin/redis-server $< --sentinel
98115

99-
sentinel-start: work/sentinel-26379.pid work/sentinel-26380.pid work/sentinel-26381.pid
116+
sentinel-start: work/sentinel-26379.pid work/sentinel-26380.pid work/sentinel-26381.pid work/sentinel-26382.pid
100117

101-
sentinel-stop: stop-26379 stop-26380 stop-26381
118+
sentinel-stop: stop-26379 stop-26380 stop-26381 stop-26382
102119

103120

104121
#########
@@ -171,6 +188,9 @@ stop-%: work/redis/bin/redis-cli
171188
stop-6382: work/redis/bin/redis-cli
172189
-work/redis/bin/redis-cli -a foobared -p 6382 shutdown
173190

191+
stop-26382: work/redis/bin/redis-cli
192+
-work/redis/bin/redis-cli -a foobared -p 26382 shutdown
193+
174194
stop: redis-stop sentinel-stop cluster-stop
175195

176196
test:

src/main/asciidoc/new-features.adoc

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This section briefly covers items that are new and noteworthy in the latest rele
88

99
* `RedisCache` now exposes `CacheStatistics`.
1010
* ACL authentication support for Redis Standalone, Redis Cluster and Master/Replica.
11+
* Password support for Redis Sentinel using Jedis.
1112

1213
[[new-in-2.3.0]]
1314
== New in Spring Data Redis 2.3

src/main/asciidoc/reference/redis.adoc

-5
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,6 @@ public RedisConnectionFactory lettuceConnectionFactory() {
324324

325325
Sometimes, direct interaction with one of the Sentinels is required. Using `RedisConnectionFactory.getSentinelConnection()` or `RedisConnection.getSentinelCommands()` gives you access to the first active Sentinel configured.
326326

327-
[NOTE]
328-
====
329-
Sentinel authentication is only available using https://lettuce.io/[Lettuce].
330-
====
331-
332327
[[redis:template]]
333328
== Working with Objects through RedisTemplate
334329

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

+6-2
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,12 @@ private Pool<Jedis> createPool() {
371371
protected Pool<Jedis> createRedisSentinelPool(RedisSentinelConfiguration config) {
372372

373373
GenericObjectPoolConfig<?> poolConfig = getPoolConfig() != null ? getPoolConfig() : new JedisPoolConfig();
374+
String sentinelUser = null;
375+
String sentinelPassword = config.getSentinelPassword().toOptional().map(String::new).orElse(null);
374376

375377
return new JedisSentinelPool(config.getMaster().getName(), convertToJedisSentinelSet(config.getSentinels()),
376378
poolConfig, getConnectTimeout(), getReadTimeout(), getUsername(), getPassword(), getDatabase(),
377-
getClientName());
379+
getClientName(), getConnectTimeout(), getReadTimeout(), sentinelUser, sentinelPassword, getClientName());
378380
}
379381

380382
/**
@@ -868,10 +870,12 @@ public RedisSentinelConnection getSentinelConnection() {
868870
private Jedis getActiveSentinel() {
869871

870872
Assert.isTrue(RedisConfiguration.isSentinelConfiguration(configuration), "SentinelConfig must not be null!");
873+
SentinelConfiguration sentinelConfiguration = (SentinelConfiguration) configuration;
871874

872-
for (RedisNode node : ((SentinelConfiguration) configuration).getSentinels()) {
875+
for (RedisNode node : sentinelConfiguration.getSentinels()) {
873876

874877
Jedis jedis = new Jedis(node.getHost(), node.getPort(), getConnectTimeout(), getReadTimeout());
878+
sentinelConfiguration.getSentinelPassword().toOptional().map(String::new).ifPresent(jedis::auth);
875879

876880
try {
877881
if (jedis.ping().equalsIgnoreCase("pong")) {

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

+25
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,16 @@
1818
import static org.assertj.core.api.Assertions.*;
1919
import static org.junit.Assume.*;
2020

21+
import java.io.IOException;
22+
import java.util.Collections;
23+
2124
import org.junit.Before;
2225
import org.junit.Test;
2326

2427
import org.springframework.data.redis.RedisTestProfileValueSource;
2528
import org.springframework.data.redis.connection.RedisConnection;
29+
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
30+
import org.springframework.data.redis.connection.RedisSentinelConnection;
2631
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
2732

2833
/**
@@ -72,6 +77,26 @@ public void shouldConnectStandaloneWithAclAuthentication() {
7277
connectionFactory.destroy();
7378
}
7479

80+
@Test // DATAREDIS-1145
81+
public void shouldConnectSentinelWithAclAuthentication() throws IOException {
82+
83+
// Note: As per https://github.com/redis/redis/issues/7708, Sentinel does not support ACL authentication yet.
84+
85+
RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration("mymaster",
86+
Collections.singleton("localhost:26382"));
87+
sentinelConfiguration.setSentinelPassword("foobared");
88+
89+
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(sentinelConfiguration);
90+
connectionFactory.afterPropertiesSet();
91+
92+
RedisSentinelConnection connection = connectionFactory.getSentinelConnection();
93+
94+
assertThat(connection.masters()).isNotEmpty();
95+
connection.close();
96+
97+
connectionFactory.destroy();
98+
}
99+
75100
@Test // DATAREDIS-1046
76101
public void shouldConnectStandaloneWithAclAuthenticationAndPooling() {
77102

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

+32
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,20 @@
1818
import static org.assertj.core.api.Assertions.*;
1919
import static org.junit.Assume.*;
2020

21+
import io.lettuce.core.ClientOptions;
22+
import io.lettuce.core.protocol.ProtocolVersion;
23+
24+
import java.io.IOException;
25+
import java.util.Collections;
26+
2127
import org.junit.Before;
2228
import org.junit.Ignore;
2329
import org.junit.Test;
2430

2531
import org.springframework.data.redis.RedisTestProfileValueSource;
2632
import org.springframework.data.redis.connection.RedisConnection;
33+
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
34+
import org.springframework.data.redis.connection.RedisSentinelConnection;
2735
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
2836
import org.springframework.data.redis.connection.RedisStaticMasterReplicaConfiguration;
2937

@@ -76,6 +84,30 @@ public void shouldConnectStandaloneWithAclAuthentication() {
7684
connectionFactory.destroy();
7785
}
7886

87+
@Test // DATAREDIS-1145
88+
public void shouldConnectSentinelWithAuthentication() throws IOException {
89+
90+
// Note: As per https://github.com/redis/redis/issues/7708, Sentinel does not support ACL authentication yet.
91+
92+
LettuceClientConfiguration configuration = LettuceClientConfiguration.builder()
93+
.clientResources(LettuceTestClientResources.getSharedClientResources())
94+
.clientOptions(ClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).build()).build();
95+
96+
RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration("mymaster",
97+
Collections.singleton("localhost:26382"));
98+
sentinelConfiguration.setSentinelPassword("foobared");
99+
100+
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(sentinelConfiguration, configuration);
101+
connectionFactory.afterPropertiesSet();
102+
103+
RedisSentinelConnection connection = connectionFactory.getSentinelConnection();
104+
105+
assertThat(connection.masters()).isNotEmpty();
106+
connection.close();
107+
108+
connectionFactory.destroy();
109+
}
110+
79111
@Test // DATAREDIS-1046
80112
@Ignore("https://github.com/lettuce-io/lettuce-core/issues/1406")
81113
public void shouldConnectMasterReplicaWithAclAuthentication() {

0 commit comments

Comments
 (0)