Skip to content

Commit 17901ba

Browse files
jorodas-sathish
authored andcommitted
Add SSL support to JedisCluster (#1550)
* Add SSL support to JedisCluster * Remove unused imports from SSLJedisClusterTest * Add JedisClusterPortMap interface for mapping between plaintext and SSL ports. * Fix casing in JedisClusterPortMap * Add new constructor for JedisClusterInfoCache instead of modifying existing one to fix backwards compatibility issue * Undo unintended formatting changes. * Improve name of test case in SSLJedisClusterTest * Fix logic for closing JedisCluster objects in SSLJedisClusterTest * Add option to specify mapping between redis and ssl hostnames * Remove unneeded public access modifiers
1 parent cf31202 commit 17901ba

File tree

9 files changed

+434
-14
lines changed

9 files changed

+434
-14
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: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
import java.util.Map;
1717
import java.util.Set;
1818

19+
import javax.net.ssl.HostnameVerifier;
20+
import javax.net.ssl.SSLParameters;
21+
import javax.net.ssl.SSLSocketFactory;
22+
1923
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
2024
import redis.clients.jedis.util.JedisClusterHashTagUtil;
2125

@@ -63,6 +67,19 @@ public BinaryJedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeo
6367
connectionTimeout, soTimeout, password, clientName);
6468
this.maxAttempts = maxAttempts;
6569
}
70+
71+
public BinaryJedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, int soTimeout, int maxAttempts, String password, String clientName, GenericObjectPoolConfig poolConfig,
72+
boolean ssl) {
73+
this(jedisClusterNode, connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig, ssl, null, null, null, null);
74+
}
75+
76+
public BinaryJedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, int soTimeout, int maxAttempts, String password, String clientName, GenericObjectPoolConfig poolConfig,
77+
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
78+
HostnameVerifier hostnameVerifier, JedisClusterHostAndPortMap hostAndPortMap) {
79+
this.connectionHandler = new JedisSlotBasedConnectionHandler(jedisClusterNode, poolConfig,
80+
connectionTimeout, soTimeout, password, clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMap);
81+
this.maxAttempts = maxAttempts;
82+
}
6683

6784
@Override
6885
public void close() {

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

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
import java.util.Map.Entry;
1515
import java.util.Set;
1616

17+
import javax.net.ssl.HostnameVerifier;
18+
import javax.net.ssl.SSLParameters;
19+
import javax.net.ssl.SSLSocketFactory;
20+
1721
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
1822

1923
import redis.clients.jedis.params.SetParams;
@@ -61,6 +65,20 @@ public JedisCluster(HostAndPort node, int connectionTimeout, int soTimeout,
6165
int maxAttempts, String password, String clientName, final GenericObjectPoolConfig poolConfig) {
6266
this(Collections.singleton(node), connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig);
6367
}
68+
69+
public JedisCluster(HostAndPort node, int connectionTimeout, int soTimeout,
70+
int maxAttempts, String password, String clientName, final GenericObjectPoolConfig poolConfig,
71+
boolean ssl) {
72+
super(Collections.singleton(node), connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig, ssl);
73+
}
74+
75+
public JedisCluster(HostAndPort node, int connectionTimeout, int soTimeout,
76+
int maxAttempts, String password, String clientName, final GenericObjectPoolConfig poolConfig,
77+
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
78+
HostnameVerifier hostnameVerifier, JedisClusterHostAndPortMap hostAndPortMap) {
79+
super(Collections.singleton(node), connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig,
80+
ssl, sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMap);
81+
}
6482

6583
public JedisCluster(Set<HostAndPort> nodes) {
6684
this(nodes, DEFAULT_TIMEOUT);
@@ -100,7 +118,21 @@ public JedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, in
100118
public JedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, int soTimeout,
101119
int maxAttempts, String password, String clientName, final GenericObjectPoolConfig poolConfig) {
102120
super(jedisClusterNode, connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig);
103-
}
121+
}
122+
123+
public JedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, int soTimeout,
124+
int maxAttempts, String password, String clientName, final GenericObjectPoolConfig poolConfig,
125+
boolean ssl) {
126+
super(jedisClusterNode, connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig, ssl);
127+
}
128+
129+
public JedisCluster(Set<HostAndPort> jedisClusterNode, int connectionTimeout, int soTimeout,
130+
int maxAttempts, String password, String clientName, final GenericObjectPoolConfig poolConfig,
131+
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
132+
HostnameVerifier hostnameVerifier, JedisClusterHostAndPortMap hostAndPortMap) {
133+
super(jedisClusterNode, connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig,
134+
ssl, sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMap);
135+
}
104136

105137
@Override
106138
public String set(final String key, final String value) {

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

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
import java.util.Map;
55
import java.util.Set;
66

7+
import javax.net.ssl.HostnameVerifier;
8+
import javax.net.ssl.SSLParameters;
9+
import javax.net.ssl.SSLSocketFactory;
10+
711
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
812

913
import redis.clients.jedis.exceptions.JedisConnectionException;
@@ -18,9 +22,17 @@ public JedisClusterConnectionHandler(Set<HostAndPort> nodes,
1822

1923
public JedisClusterConnectionHandler(Set<HostAndPort> nodes,
2024
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-
}
25+
this(nodes, poolConfig, connectionTimeout, soTimeout, password, clientName, false, null, null, null, null);
26+
}
27+
28+
public JedisClusterConnectionHandler(Set<HostAndPort> nodes,
29+
final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout, String password, String clientName,
30+
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
31+
HostnameVerifier hostnameVerifier, JedisClusterHostAndPortMap portMap) {
32+
this.cache = new JedisClusterInfoCache(poolConfig, connectionTimeout, soTimeout, password, clientName,
33+
ssl, sslSocketFactory, sslParameters, hostnameVerifier, portMap);
34+
initializeSlotsCache(nodes, poolConfig, connectionTimeout, soTimeout, password, clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier);
35+
}
2436

2537
abstract Jedis getConnection();
2638

@@ -34,12 +46,12 @@ public Map<String, JedisPool> getNodes() {
3446
return cache.getNodes();
3547
}
3648

37-
private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig,
38-
int connectionTimeout, int soTimeout, String password, String clientName) {
49+
private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig, 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: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
import java.util.concurrent.locks.Lock;
99
import java.util.concurrent.locks.ReentrantReadWriteLock;
1010

11+
import javax.net.ssl.HostnameVerifier;
12+
import javax.net.ssl.SSLParameters;
13+
import javax.net.ssl.SSLSocketFactory;
14+
1115
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
1216

1317
import redis.clients.jedis.exceptions.JedisConnectionException;
@@ -29,19 +33,37 @@ public class JedisClusterInfoCache {
2933
private String password;
3034
private String clientName;
3135

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

3444
public JedisClusterInfoCache(final GenericObjectPoolConfig poolConfig, int timeout) {
3545
this(poolConfig, timeout, timeout, null, null);
3646
}
37-
47+
3848
public JedisClusterInfoCache(final GenericObjectPoolConfig poolConfig,
3949
final int connectionTimeout, final int soTimeout, final String password, final String clientName) {
50+
this(poolConfig, connectionTimeout, soTimeout, password, clientName, false, null, null, null, null);
51+
}
52+
53+
public JedisClusterInfoCache(final GenericObjectPoolConfig poolConfig,
54+
final int connectionTimeout, final int soTimeout, final String password, final String clientName,
55+
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters,
56+
HostnameVerifier hostnameVerifier, JedisClusterHostAndPortMap hostAndPortMap) {
4057
this.poolConfig = poolConfig;
4158
this.connectionTimeout = connectionTimeout;
4259
this.soTimeout = soTimeout;
4360
this.password = password;
4461
this.clientName = clientName;
62+
this.ssl = ssl;
63+
this.sslSocketFactory = sslSocketFactory;
64+
this.sslParameters = sslParameters;
65+
this.hostnameVerifier = hostnameVerifier;
66+
this.hostAndPortMap = hostAndPortMap;
4567
}
4668

4769
public void discoverClusterNodesAndSlots(Jedis jedis) {
@@ -143,8 +165,15 @@ private void discoverClusterSlots(Jedis jedis) {
143165
}
144166

145167
private HostAndPort generateHostAndPort(List<Object> hostInfos) {
146-
return new HostAndPort(SafeEncoder.encode((byte[]) hostInfos.get(0)),
147-
((Long) hostInfos.get(1)).intValue());
168+
String host = SafeEncoder.encode((byte[]) hostInfos.get(0));
169+
int port = ((Long) hostInfos.get(1)).intValue();
170+
if (ssl && hostAndPortMap != null) {
171+
HostAndPort hostAndPort = hostAndPortMap.getSSLHostAndPort(host, port);
172+
if (hostAndPortMap != null) {
173+
return hostAndPort;
174+
}
175+
}
176+
return new HostAndPort(host, port);
148177
}
149178

150179
public JedisPool setupNodeIfNotExist(HostAndPort node) {
@@ -155,7 +184,8 @@ public JedisPool setupNodeIfNotExist(HostAndPort node) {
155184
if (existingPool != null) return existingPool;
156185

157186
JedisPool nodePool = new JedisPool(poolConfig, node.getHost(), node.getPort(),
158-
connectionTimeout, soTimeout, password, 0, clientName, false, null, null, null);
187+
connectionTimeout, soTimeout, password, 0, clientName,
188+
ssl, sslSocketFactory, sslParameters, hostnameVerifier);
159189
nodes.put(nodeKey, nodePool);
160190
return nodePool;
161191
} finally {

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55

66
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
77

8+
import javax.net.ssl.HostnameVerifier;
9+
import javax.net.ssl.SSLParameters;
10+
import javax.net.ssl.SSLSocketFactory;
11+
812
import redis.clients.jedis.exceptions.JedisException;
913
import redis.clients.jedis.exceptions.JedisNoReachableClusterNodeException;
1014

@@ -27,6 +31,11 @@ public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes, GenericObjectPool
2731
public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes, GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout, String password, String clientName) {
2832
super(nodes, poolConfig, connectionTimeout, soTimeout, password, clientName);
2933
}
34+
35+
public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes, GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout, String password, String clientName,
36+
boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters, HostnameVerifier hostnameVerifier, JedisClusterHostAndPortMap portMap) {
37+
super(nodes, poolConfig, connectionTimeout, soTimeout, password, clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier, portMap);
38+
}
3039

3140
@Override
3241
public Jedis getConnection() {

0 commit comments

Comments
 (0)