Skip to content

Commit 17b4550

Browse files
sazzad16yapei
and
yapei
authored
Add ability to reset password in JedisFactory (II) (#2315)
* Add ability to reset password in JedisFactory for JedisPool and JedisSentinelPool * Modify JedisFactory tests and support ACL * reduce new public * volatile password instead of AtomicReference * apply acl tests * Add ability to reset password in JedisFactory for JedisPool and JedisSentinelPool * Modify JedisFactory tests and support ACL * Modify JedisFactory and Pool - Added JedisFactory constructor without host and port as there is option to set those later. - Prepared to private internalPool in Pool. * Adddress gkorland's suggestion * Deprecation and JavaDoc * address change requests * address change requests * Unbreak (both JedisFactory and JedisSentinelPool are errored) * update with config pattern * Remove checking of 'user' while updating password * update deprecation messages Co-authored-by: yapei <[email protected]>
1 parent a7d2147 commit 17b4550

10 files changed

+265
-61
lines changed

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package redis.clients.jedis;
22

3+
import java.util.Objects;
34
import javax.net.ssl.HostnameVerifier;
45
import javax.net.ssl.SSLParameters;
56
import javax.net.ssl.SSLSocketFactory;
@@ -11,7 +12,7 @@ public final class DefaultJedisClientConfig implements JedisClientConfig {
1112
private final int infiniteSoTimeoutMillis;
1213

1314
private final String user;
14-
private final String password;
15+
private volatile String password;
1516
private final int database;
1617
private final String clientName;
1718

@@ -65,6 +66,13 @@ public String getPassword() {
6566
return password;
6667
}
6768

69+
@Override
70+
public synchronized void updatePassword(String password) {
71+
if (!Objects.equals(this.password, password)) {
72+
this.password = password;
73+
}
74+
}
75+
6876
@Override
6977
public int getDatabase() {
7078
return database;

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

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ default String getPassword() {
3939
return null;
4040
}
4141

42+
default void updatePassword(String password) {
43+
}
44+
4245
default int getDatabase() {
4346
return Protocol.DEFAULT_DATABASE;
4447
}

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

+32-11
Original file line numberDiff line numberDiff line change
@@ -20,72 +20,89 @@
2020
/**
2121
* PoolableObjectFactory custom impl.
2222
*/
23-
class JedisFactory implements PooledObjectFactory<Jedis> {
23+
public class JedisFactory implements PooledObjectFactory<Jedis> {
2424

2525
private static final Logger logger = LoggerFactory.getLogger(JedisFactory.class);
2626

2727
private final AtomicReference<HostAndPort> hostAndPort = new AtomicReference<>();
2828

2929
private final JedisClientConfig config;
3030

31-
JedisFactory(final String host, final int port, final int connectionTimeout,
31+
protected JedisFactory(final String host, final int port, final int connectionTimeout,
3232
final int soTimeout, final String password, final int database, final String clientName) {
3333
this(host, port, connectionTimeout, soTimeout, password, database, clientName, false, null, null, null);
3434
}
3535

36-
JedisFactory(final String host, final int port, final int connectionTimeout,
36+
protected JedisFactory(final String host, final int port, final int connectionTimeout,
3737
final int soTimeout, final String user, final String password, final int database, final String clientName) {
3838
this(host, port, connectionTimeout, soTimeout, 0, user, password, database, clientName);
3939
}
4040

41-
JedisFactory(final String host, final int port, final int connectionTimeout, final int soTimeout,
41+
protected JedisFactory(final String host, final int port, final int connectionTimeout, final int soTimeout,
4242
final int infiniteSoTimeout, final String user, final String password, final int database, final String clientName) {
4343
this(host, port, connectionTimeout, soTimeout, infiniteSoTimeout, user, password, database, clientName, false, null, null, null);
4444
}
4545

46-
JedisFactory(final String host, final int port, final int connectionTimeout,
46+
/**
47+
* {@link #setHostAndPort(redis.clients.jedis.HostAndPort) setHostAndPort} must be called later.
48+
*/
49+
protected JedisFactory(final int connectionTimeout, final int soTimeout, final int infiniteSoTimeout,
50+
final String user, final String password, final int database, final String clientName) {
51+
this(connectionTimeout, soTimeout, infiniteSoTimeout, user, password, database, clientName, false, null, null, null);
52+
}
53+
54+
protected JedisFactory(final String host, final int port, final int connectionTimeout,
4755
final int soTimeout, final String password, final int database, final String clientName,
4856
final boolean ssl, final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
4957
final HostnameVerifier hostnameVerifier) {
5058
this(host, port, connectionTimeout, soTimeout, null, password, database, clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier);
5159
}
5260

53-
JedisFactory(final String host, final int port, final int connectionTimeout,
61+
protected JedisFactory(final String host, final int port, final int connectionTimeout,
5462
final int soTimeout, final String user, final String password, final int database, final String clientName,
5563
final boolean ssl, final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
5664
final HostnameVerifier hostnameVerifier) {
5765
this(host, port, connectionTimeout, soTimeout, 0, user, password, database, clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier);
5866
}
5967

60-
JedisFactory(final HostAndPort hostAndPort, final JedisClientConfig clientConfig) {
68+
protected JedisFactory(final HostAndPort hostAndPort, final JedisClientConfig clientConfig) {
6169
this.hostAndPort.set(hostAndPort);
6270
this.config = DefaultJedisClientConfig.copyConfig(clientConfig);
6371
}
6472

65-
JedisFactory(final String host, final int port, final int connectionTimeout, final int soTimeout,
73+
protected JedisFactory(final String host, final int port, final int connectionTimeout, final int soTimeout,
6674
final int infiniteSoTimeout, final String user, final String password, final int database,
6775
final String clientName, final boolean ssl, final SSLSocketFactory sslSocketFactory,
6876
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
77+
this(connectionTimeout, soTimeout, infiniteSoTimeout, user, password, database, clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier);
6978
this.hostAndPort.set(new HostAndPort(host, port));
79+
}
80+
81+
/**
82+
* {@link #setHostAndPort(redis.clients.jedis.HostAndPort) setHostAndPort} must be called later.
83+
*/
84+
protected JedisFactory(final int connectionTimeout, final int soTimeout, final int infiniteSoTimeout,
85+
final String user, final String password, final int database, final String clientName, final boolean ssl,
86+
final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
7087
this.config = DefaultJedisClientConfig.builder().withConnectionTimeoutMillis(connectionTimeout)
7188
.withSoTimeoutMillis(soTimeout).withInfiniteSoTimeoutMillis(infiniteSoTimeout).withUser(user)
7289
.withPassword(password).withDatabse(database).withClientName(clientName)
7390
.withSsl(ssl).withSslSocketFactory(sslSocketFactory)
7491
.withSslParameters(sslParameters).withHostnameVerifier(hostnameVerifier).build();
7592
}
7693

77-
JedisFactory(final URI uri, final int connectionTimeout, final int soTimeout,
94+
protected JedisFactory(final URI uri, final int connectionTimeout, final int soTimeout,
7895
final String clientName) {
7996
this(uri, connectionTimeout, soTimeout, clientName, null, null, null);
8097
}
8198

82-
JedisFactory(final URI uri, final int connectionTimeout, final int soTimeout,
99+
protected JedisFactory(final URI uri, final int connectionTimeout, final int soTimeout,
83100
final String clientName, final SSLSocketFactory sslSocketFactory,
84101
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
85102
this(uri, connectionTimeout, soTimeout, 0, clientName, sslSocketFactory, sslParameters, hostnameVerifier);
86103
}
87104

88-
JedisFactory(final URI uri, final int connectionTimeout, final int soTimeout,
105+
protected JedisFactory(final URI uri, final int connectionTimeout, final int soTimeout,
89106
final int infiniteSoTimeout, final String clientName, final SSLSocketFactory sslSocketFactory,
90107
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
91108
if (!JedisURIHelper.isValid(uri)) {
@@ -105,6 +122,10 @@ public void setHostAndPort(final HostAndPort hostAndPort) {
105122
this.hostAndPort.set(hostAndPort);
106123
}
107124

125+
public void setPassword(final String password) {
126+
this.config.updatePassword(password);
127+
}
128+
108129
@Override
109130
public void activateObject(PooledObject<Jedis> pooledJedis) throws Exception {
110131
final BinaryJedis jedis = pooledJedis.getObject();

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

+29-10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import javax.net.ssl.SSLParameters;
66
import javax.net.ssl.SSLSocketFactory;
77

8+
import org.apache.commons.pool2.PooledObjectFactory;
89
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
910
import org.slf4j.Logger;
1011
import org.slf4j.LoggerFactory;
@@ -27,29 +28,43 @@ public JedisPool(String host, int port) {
2728
this(new GenericObjectPoolConfig<Jedis>(), host, port);
2829
}
2930

30-
public JedisPool(final String host) {
31-
URI uri = URI.create(host);
31+
/**
32+
* @param url
33+
* @deprecated This constructor will not accept a host string in future. It will accept only a uri
34+
* string. You can use {@link JedisURIHelper#isValid(java.net.URI)} before this.
35+
*/
36+
@Deprecated
37+
public JedisPool(final String url) {
38+
URI uri = URI.create(url);
3239
if (JedisURIHelper.isValid(uri)) {
3340
initPool(new GenericObjectPoolConfig<Jedis>(), new JedisFactory(uri,
3441
Protocol.DEFAULT_TIMEOUT, Protocol.DEFAULT_TIMEOUT, null));
3542
} else {
36-
initPool(new GenericObjectPoolConfig<Jedis>(),
37-
new JedisFactory(host, Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT,
38-
Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE, null));
43+
initPool(new GenericObjectPoolConfig<Jedis>(), new JedisFactory(url, Protocol.DEFAULT_PORT,
44+
Protocol.DEFAULT_TIMEOUT, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE, null));
3945
}
4046
}
4147

42-
public JedisPool(final String host, final SSLSocketFactory sslSocketFactory,
48+
/**
49+
* @param url
50+
* @param sslSocketFactory
51+
* @param sslParameters
52+
* @param hostnameVerifier
53+
* @deprecated This constructor will not accept a host string in future. It will accept only a uri
54+
* string. You can use {@link JedisURIHelper#isValid(java.net.URI)} before this.
55+
*/
56+
@Deprecated
57+
public JedisPool(final String url, final SSLSocketFactory sslSocketFactory,
4358
final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
44-
URI uri = URI.create(host);
59+
URI uri = URI.create(url);
4560
if (JedisURIHelper.isValid(uri)) {
4661
initPool(new GenericObjectPoolConfig<Jedis>(), new JedisFactory(uri,
4762
Protocol.DEFAULT_TIMEOUT, Protocol.DEFAULT_TIMEOUT, null, sslSocketFactory,
4863
sslParameters, hostnameVerifier));
4964
} else {
50-
initPool(new GenericObjectPoolConfig<Jedis>(), new JedisFactory(host, Protocol.DEFAULT_PORT,
51-
Protocol.DEFAULT_TIMEOUT, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE,
52-
null, false, null, null, null));
65+
initPool(new GenericObjectPoolConfig<Jedis>(), new JedisFactory(url, Protocol.DEFAULT_PORT,
66+
Protocol.DEFAULT_TIMEOUT, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE, null,
67+
false, null, null, null));
5368
}
5469
}
5570

@@ -337,6 +352,10 @@ public JedisPool(final GenericObjectPoolConfig<Jedis> poolConfig, final URI uri,
337352
sslSocketFactory, sslParameters, hostnameVerifier));
338353
}
339354

355+
public JedisPool(GenericObjectPoolConfig poolConfig, PooledObjectFactory<Jedis> factory) {
356+
super(poolConfig, factory);
357+
}
358+
340359
@Override
341360
public Jedis getResource() {
342361
Jedis jedis = super.getResource();

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

+6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
@Deprecated
1313
public class JedisPoolAbstract extends Pool<Jedis> {
1414

15+
/**
16+
* Using this constructor means you have to set and initialize the internalPool yourself.
17+
*
18+
* @deprecated This constructor will be removed in future.
19+
*/
20+
@Deprecated
1521
public JedisPoolAbstract() {
1622
super();
1723
}

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

+34-37
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,25 @@ public class JedisSentinelPool extends JedisPoolAbstract {
2222
protected static Logger log = LoggerFactory.getLogger(JedisSentinelPool.class);
2323

2424
protected final GenericObjectPoolConfig<Jedis> poolConfig;
25+
private final JedisFactory factory;
2526

26-
protected final int connectionTimeout;
27-
protected final int soTimeout;
28-
protected final int infiniteSoTimeout;
27+
@Deprecated protected int connectionTimeout;
28+
@Deprecated protected int soTimeout;
29+
@Deprecated protected int infiniteSoTimeout;
2930

30-
protected final String user;
31-
protected final String password;
32-
protected final int database;
33-
protected final String clientName;
31+
@Deprecated protected String user;
32+
@Deprecated protected String password;
33+
@Deprecated protected int database;
34+
@Deprecated protected String clientName;
3435

35-
protected int sentinelConnectionTimeout;
36-
protected int sentinelSoTimeout;
37-
protected String sentinelUser;
38-
protected String sentinelPassword;
39-
protected String sentinelClientName;
36+
@Deprecated protected int sentinelConnectionTimeout;
37+
@Deprecated protected int sentinelSoTimeout;
38+
@Deprecated protected String sentinelUser;
39+
@Deprecated protected String sentinelPassword;
40+
@Deprecated protected String sentinelClientName;
4041

4142
protected final Set<MasterListener> masterListeners = new HashSet<>();
4243

43-
private volatile JedisFactory factory;
4444
private volatile HostAndPort currentHostMaster;
4545

4646
private final Object initPoolLock = new Object();
@@ -160,8 +160,7 @@ public JedisSentinelPool(String masterName, Set<String> sentinels,
160160
final String user, final String password, final int database, final String clientName,
161161
final int sentinelConnectionTimeout, final int sentinelSoTimeout, final String sentinelUser,
162162
final String sentinelPassword, final String sentinelClientName) {
163-
164-
this.poolConfig = poolConfig;
163+
this(masterName, sentinels, poolConfig, new JedisFactory(connectionTimeout, soTimeout, infiniteSoTimeout, user, password, database, clientName));
165164
this.connectionTimeout = connectionTimeout;
166165
this.soTimeout = soTimeout;
167166
this.infiniteSoTimeout = infiniteSoTimeout;
@@ -174,9 +173,16 @@ public JedisSentinelPool(String masterName, Set<String> sentinels,
174173
this.sentinelUser = sentinelUser;
175174
this.sentinelPassword = sentinelPassword;
176175
this.sentinelClientName = sentinelClientName;
176+
}
177+
178+
public JedisSentinelPool(String masterName, Set<String> sentinels,
179+
final GenericObjectPoolConfig<Jedis> poolConfig, final JedisFactory factory) {
180+
super(poolConfig, factory);
181+
this.poolConfig = poolConfig;
182+
this.factory = factory;
177183

178184
HostAndPort master = initSentinels(sentinels, masterName);
179-
initPool(master);
185+
initMaster(master);
180186
}
181187

182188
@Override
@@ -192,22 +198,16 @@ public HostAndPort getCurrentHostMaster() {
192198
return currentHostMaster;
193199
}
194200

195-
private void initPool(HostAndPort master) {
196-
synchronized(initPoolLock){
201+
private void initMaster(HostAndPort master) {
202+
synchronized (initPoolLock) {
197203
if (!master.equals(currentHostMaster)) {
198204
currentHostMaster = master;
199-
if (factory == null) {
200-
factory = new JedisFactory(master.getHost(), master.getPort(), connectionTimeout,
201-
soTimeout, infiniteSoTimeout, user, password, database, clientName);
202-
initPool(poolConfig, factory);
203-
} else {
204-
factory.setHostAndPort(currentHostMaster);
205-
// although we clear the pool, we still have to check the returned object in getResource,
206-
// this call only clears idle instances, not borrowed instances
207-
clearInternalPool();
208-
}
205+
factory.setHostAndPort(currentHostMaster);
206+
// although we clear the pool, we still have to check the returned object in getResource,
207+
// this call only clears idle instances, not borrowed instances
208+
clearInternalPool();
209209

210-
log.info("Created JedisPool to master at {}", master);
210+
log.info("Created JedisSentinelPool to master at {}", master);
211211
}
212212
}
213213
}
@@ -224,8 +224,7 @@ private HostAndPort initSentinels(Set<String> sentinels, final String masterName
224224

225225
log.debug("Connecting to Sentinel {}", hap);
226226

227-
228-
try (Jedis jedis = new Jedis(hap.getHost(), hap.getPort(), sentinelConnectionTimeout, sentinelSoTimeout)){
227+
try (Jedis jedis = new Jedis(hap.getHost(), hap.getPort(), sentinelConnectionTimeout, sentinelSoTimeout)) {
229228
if (sentinelUser != null) {
230229
jedis.auth(sentinelUser, sentinelPassword);
231230
} else if (sentinelPassword != null) {
@@ -249,10 +248,8 @@ private HostAndPort initSentinels(Set<String> sentinels, final String masterName
249248
log.debug("Found Redis master at {}", master);
250249
break;
251250
} catch (JedisException e) {
252-
// resolves #1036, it should handle JedisException there's another chance
253-
// of raising JedisDataException
254-
log.warn(
255-
"Cannot get master address from sentinel running @ {}. Reason: {}. Trying next one.", hap, e);
251+
// resolves #1036, it should handle JedisException there's another chance of raising JedisDataException
252+
log.warn("Cannot get master address from sentinel running @ {}. Reason: {}. Trying next one.", hap, e);
256253
}
257254
}
258255

@@ -375,7 +372,7 @@ public void run() {
375372
if (masterAddr == null || masterAddr.size() != 2) {
376373
log.warn("Can not get master addr, master name: {}. Sentinel: {}:{}.", masterName, host, port);
377374
} else {
378-
initPool(toHostAndPort(masterAddr));
375+
initMaster(toHostAndPort(masterAddr));
379376
}
380377

381378
j.subscribe(new JedisPubSub() {
@@ -388,7 +385,7 @@ public void onMessage(String channel, String message) {
388385
if (switchMasterMsg.length > 3) {
389386

390387
if (masterName.equals(switchMasterMsg[0])) {
391-
initPool(toHostAndPort(Arrays.asList(switchMasterMsg[3], switchMasterMsg[4])));
388+
initMaster(toHostAndPort(Arrays.asList(switchMasterMsg[3], switchMasterMsg[4])));
392389
} else {
393390
log.debug(
394391
"Ignoring message on +switch-master for master name {}, our master name is {}",

0 commit comments

Comments
 (0)