Skip to content

Commit ef4ab40

Browse files
authored
Add SSL support to JedisCluster (#1896)
1 parent 79baab4 commit ef4ab40

File tree

9 files changed

+428
-18
lines changed

9 files changed

+428
-18
lines changed

Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,21 @@ pid = /tmp/stunnel.pid
218218
[redis]
219219
accept = 127.0.0.1:6390
220220
connect = 127.0.0.1:6379
221+
[redis_cluster_1]
222+
accept = 127.0.0.1:8379
223+
connect = 127.0.0.1:7379
224+
[redis_cluster_2]
225+
accept = 127.0.0.1:8380
226+
connect = 127.0.001:7380
227+
[redis_cluster_3]
228+
accept = 127.0.0.1:8381
229+
connect = 127.0.001:7381
230+
[redis_cluster_4]
231+
accept = 127.0.0.1:8382
232+
connect = 127.0.0.1:7382
233+
[redis_cluster_5]
234+
accept = 127.0.0.1:8383
235+
connect = 127.0.0.1:7383
221236
endef
222237

223238
export REDIS1_CONF

src/main/java/redis/clients/jedis/BinaryJedisCluster.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import redis.clients.jedis.params.SetParams;
88
import redis.clients.jedis.params.ZAddParams;
99
import redis.clients.jedis.params.ZIncrByParams;
10+
import redis.clients.jedis.util.JedisClusterHashTagUtil;
1011
import redis.clients.jedis.util.KeyMergeUtil;
1112
import redis.clients.jedis.util.SafeEncoder;
1213

@@ -15,9 +16,11 @@
1516
import java.util.List;
1617
import java.util.Map;
1718
import java.util.Set;
19+
import javax.net.ssl.HostnameVerifier;
20+
import javax.net.ssl.SSLParameters;
21+
import javax.net.ssl.SSLSocketFactory;
1822

1923
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
20-
import redis.clients.jedis.util.JedisClusterHashTagUtil;
2124

2225
public class BinaryJedisCluster implements BinaryJedisClusterCommands,
2326
MultiKeyBinaryJedisClusterCommands, JedisClusterBinaryScriptingCommands, Closeable {
@@ -64,6 +67,18 @@ public BinaryJedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeo
6467
this.maxAttempts = maxAttempts;
6568
}
6669

70+
public BinaryJedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, int soTimeout, int maxAttempts, String password, String clientName, GenericObjectPoolConfig poolConfig,
71+
boolean ssl) {
72+
this(jedisClusterNode, connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig, ssl, null, null, null, null);
73+
}
74+
75+
public BinaryJedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, int soTimeout, int maxAttempts, String password, String clientName, GenericObjectPoolConfig poolConfig,
76+
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters, HostnameVerifier hostnameVerifier, JedisClusterHostAndPortMap hostAndPortMap) {
77+
this.connectionHandler = new JedisSlotBasedConnectionHandler(jedisClusterNode, poolConfig,
78+
connectionTimeout, soTimeout, password, clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMap);
79+
this.maxAttempts = maxAttempts;
80+
}
81+
6782
@Override
6883
public void close() {
6984
if (connectionHandler != null) {

src/main/java/redis/clients/jedis/JedisCluster.java

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
11
package redis.clients.jedis;
22

33
import redis.clients.jedis.params.GeoRadiusParam;
4+
import redis.clients.jedis.params.SetParams;
45
import redis.clients.jedis.params.ZAddParams;
56
import redis.clients.jedis.params.ZIncrByParams;
67
import redis.clients.jedis.commands.JedisClusterCommands;
78
import redis.clients.jedis.commands.JedisClusterScriptingCommands;
89
import redis.clients.jedis.commands.MultiKeyJedisClusterCommands;
10+
import redis.clients.jedis.util.JedisClusterHashTagUtil;
911
import redis.clients.jedis.util.KeyMergeUtil;
1012

1113
import java.util.Collections;
1214
import java.util.List;
1315
import java.util.Map;
1416
import java.util.Map.Entry;
1517
import java.util.Set;
18+
import javax.net.ssl.HostnameVerifier;
19+
import javax.net.ssl.SSLParameters;
20+
import javax.net.ssl.SSLSocketFactory;
1621

1722
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
1823

19-
import redis.clients.jedis.params.SetParams;
20-
import redis.clients.jedis.util.JedisClusterHashTagUtil;
21-
2224
public class JedisCluster extends BinaryJedisCluster implements JedisClusterCommands,
2325
MultiKeyJedisClusterCommands, JedisClusterScriptingCommands {
2426

@@ -62,6 +64,20 @@ public JedisCluster(HostAndPort node, int connectionTimeout, int soTimeout,
6264
this(Collections.singleton(node), connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig);
6365
}
6466

67+
public JedisCluster(HostAndPort node, int connectionTimeout, int soTimeout,
68+
int maxAttempts, String password, String clientName, final GenericObjectPoolConfig poolConfig,
69+
boolean ssl) {
70+
this(Collections.singleton(node), connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig, ssl);
71+
}
72+
73+
public JedisCluster(HostAndPort node, int connectionTimeout, int soTimeout,
74+
int maxAttempts, String password, String clientName, final GenericObjectPoolConfig poolConfig,
75+
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
76+
HostnameVerifier hostnameVerifier, JedisClusterHostAndPortMap hostAndPortMap) {
77+
this(Collections.singleton(node), connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig,
78+
ssl, sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMap);
79+
}
80+
6581
public JedisCluster(Set<HostAndPort> nodes) {
6682
this(nodes, DEFAULT_TIMEOUT);
6783
}
@@ -100,7 +116,21 @@ public JedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, in
100116
public JedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, int soTimeout,
101117
int maxAttempts, String password, String clientName, final GenericObjectPoolConfig poolConfig) {
102118
super(jedisClusterNode, connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig);
103-
}
119+
}
120+
121+
public JedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, int soTimeout,
122+
int maxAttempts, String password, String clientName, final GenericObjectPoolConfig poolConfig,
123+
boolean ssl) {
124+
super(jedisClusterNode, connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig, ssl);
125+
}
126+
127+
public JedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, int soTimeout,
128+
int maxAttempts, String password, String clientName, final GenericObjectPoolConfig poolConfig,
129+
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
130+
HostnameVerifier hostnameVerifier, JedisClusterHostAndPortMap hostAndPortMap) {
131+
super(jedisClusterNode, connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig,
132+
ssl, sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMap);
133+
}
104134

105135
@Override
106136
public String set(final String key, final String value) {

src/main/java/redis/clients/jedis/JedisClusterConnectionHandler.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import java.io.Closeable;
44
import java.util.Map;
55
import java.util.Set;
6+
import javax.net.ssl.HostnameVerifier;
7+
import javax.net.ssl.SSLParameters;
8+
import javax.net.ssl.SSLSocketFactory;
69

710
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
811

@@ -12,15 +15,23 @@ public abstract class JedisClusterConnectionHandler implements Closeable {
1215
protected final JedisClusterInfoCache cache;
1316

1417
public JedisClusterConnectionHandler(Set<HostAndPort> nodes,
15-
final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout, String password) {
18+
final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout, String password) {
1619
this(nodes, poolConfig, connectionTimeout, soTimeout, password, null);
1720
}
1821

1922
public JedisClusterConnectionHandler(Set<HostAndPort> nodes,
20-
final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout, String password, String clientName) {
21-
this.cache = new JedisClusterInfoCache(poolConfig, connectionTimeout, soTimeout, password, clientName);
22-
initializeSlotsCache(nodes, poolConfig, connectionTimeout, soTimeout, password, clientName);
23-
}
23+
final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout, String password, String clientName) {
24+
this(nodes, poolConfig, connectionTimeout, soTimeout, password, clientName, false, null, null, null, null);
25+
}
26+
27+
public JedisClusterConnectionHandler(Set<HostAndPort> nodes,
28+
final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout, String password, String clientName,
29+
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
30+
HostnameVerifier hostnameVerifier, JedisClusterHostAndPortMap portMap) {
31+
this.cache = new JedisClusterInfoCache(poolConfig, connectionTimeout, soTimeout, password, clientName,
32+
ssl, sslSocketFactory, sslParameters, hostnameVerifier, portMap);
33+
initializeSlotsCache(nodes, poolConfig, connectionTimeout, soTimeout, password, clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier);
34+
}
2435

2536
abstract Jedis getConnection();
2637

@@ -35,11 +46,12 @@ public Map<String, JedisPool> getNodes() {
3546
}
3647

3748
private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig,
38-
int connectionTimeout, int soTimeout, String password, String clientName) {
49+
int connectionTimeout, int soTimeout, String password, String clientName,
50+
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters, HostnameVerifier hostnameVerifier) {
3951
for (HostAndPort hostAndPort : startNodes) {
4052
Jedis jedis = null;
4153
try {
42-
jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort(), connectionTimeout, soTimeout);
54+
jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort(), connectionTimeout, soTimeout, ssl, sslSocketFactory, sslParameters, hostnameVerifier);
4355
if (password != null) {
4456
jedis.auth(password);
4557
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package redis.clients.jedis;
2+
3+
public interface JedisClusterHostAndPortMap {
4+
HostAndPort getSSLHostAndPort(String host, int port);
5+
}

src/main/java/redis/clients/jedis/JedisClusterInfoCache.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import java.util.Map;
88
import java.util.concurrent.locks.Lock;
99
import java.util.concurrent.locks.ReentrantReadWriteLock;
10+
import javax.net.ssl.HostnameVerifier;
11+
import javax.net.ssl.SSLParameters;
12+
import javax.net.ssl.SSLSocketFactory;
1013

1114
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
1215

@@ -29,6 +32,12 @@ public class JedisClusterInfoCache {
2932
private String password;
3033
private String clientName;
3134

35+
private boolean ssl;
36+
private SSLSocketFactory sslSocketFactory;
37+
private SSLParameters sslParameters;
38+
private HostnameVerifier hostnameVerifier;
39+
private JedisClusterHostAndPortMap hostAndPortMap;
40+
3241
private static final int MASTER_NODE_INDEX = 2;
3342

3443
public JedisClusterInfoCache(final GenericObjectPoolConfig poolConfig, int timeout) {
@@ -37,11 +46,23 @@ public JedisClusterInfoCache(final GenericObjectPoolConfig poolConfig, int timeo
3746

3847
public JedisClusterInfoCache(final GenericObjectPoolConfig poolConfig,
3948
final int connectionTimeout, final int soTimeout, final String password, final String clientName) {
49+
this(poolConfig, connectionTimeout, soTimeout, password, clientName, false, null, null, null, null);
50+
}
51+
52+
public JedisClusterInfoCache(final GenericObjectPoolConfig poolConfig,
53+
final int connectionTimeout, final int soTimeout, final String password, final String clientName,
54+
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
55+
HostnameVerifier hostnameVerifier, JedisClusterHostAndPortMap hostAndPortMap) {
4056
this.poolConfig = poolConfig;
4157
this.connectionTimeout = connectionTimeout;
4258
this.soTimeout = soTimeout;
4359
this.password = password;
4460
this.clientName = clientName;
61+
this.ssl = ssl;
62+
this.sslSocketFactory = sslSocketFactory;
63+
this.sslParameters = sslParameters;
64+
this.hostnameVerifier = hostnameVerifier;
65+
this.hostAndPortMap = hostAndPortMap;
4566
}
4667

4768
public void discoverClusterNodesAndSlots(Jedis jedis) {
@@ -148,8 +169,15 @@ private void discoverClusterSlots(Jedis jedis) {
148169
}
149170

150171
private HostAndPort generateHostAndPort(List<Object> hostInfos) {
151-
return new HostAndPort(SafeEncoder.encode((byte[]) hostInfos.get(0)),
152-
((Long) hostInfos.get(1)).intValue());
172+
String host = SafeEncoder.encode((byte[]) hostInfos.get(0));
173+
int port = ((Long) hostInfos.get(1)).intValue();
174+
if (ssl && hostAndPortMap != null) {
175+
HostAndPort hostAndPort = hostAndPortMap.getSSLHostAndPort(host, port);
176+
if (hostAndPort != null) {
177+
return hostAndPort;
178+
}
179+
}
180+
return new HostAndPort(host, port);
153181
}
154182

155183
public JedisPool setupNodeIfNotExist(HostAndPort node) {
@@ -160,7 +188,8 @@ public JedisPool setupNodeIfNotExist(HostAndPort node) {
160188
if (existingPool != null) return existingPool;
161189

162190
JedisPool nodePool = new JedisPool(poolConfig, node.getHost(), node.getPort(),
163-
connectionTimeout, soTimeout, password, 0, clientName, false, null, null, null);
191+
connectionTimeout, soTimeout, password, 0, clientName,
192+
ssl, sslSocketFactory, sslParameters, hostnameVerifier);
164193
nodes.put(nodeKey, nodePool);
165194
return nodePool;
166195
} finally {

src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import java.util.List;
44
import java.util.Set;
5+
import javax.net.ssl.HostnameVerifier;
6+
import javax.net.ssl.SSLParameters;
7+
import javax.net.ssl.SSLSocketFactory;
58

69
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
710

@@ -28,6 +31,11 @@ public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes, GenericObjectPool
2831
super(nodes, poolConfig, connectionTimeout, soTimeout, password, clientName);
2932
}
3033

34+
public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes, GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout, String password, String clientName,
35+
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters, HostnameVerifier hostnameVerifier, JedisClusterHostAndPortMap portMap) {
36+
super(nodes, poolConfig, connectionTimeout, soTimeout, password, clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier, portMap);
37+
}
38+
3139
@Override
3240
public Jedis getConnection() {
3341
// In antirez's redis-rb-cluster implementation,

0 commit comments

Comments
 (0)