1515 */
1616package org .springframework .data .redis .connection .jedis ;
1717
18- import redis .clients .jedis .Client ;
18+ import redis .clients .jedis .DefaultJedisClientConfig ;
1919import redis .clients .jedis .HostAndPort ;
2020import redis .clients .jedis .Jedis ;
21+ import redis .clients .jedis .JedisClientConfig ;
2122import redis .clients .jedis .JedisCluster ;
2223import redis .clients .jedis .JedisPool ;
2324import redis .clients .jedis .JedisPoolConfig ;
4142import org .apache .commons .logging .Log ;
4243import org .apache .commons .logging .LogFactory ;
4344import org .apache .commons .pool2 .impl .GenericObjectPoolConfig ;
45+
4446import org .springframework .beans .factory .DisposableBean ;
4547import org .springframework .beans .factory .InitializingBean ;
4648import org .springframework .dao .DataAccessException ;
5860import org .springframework .util .Assert ;
5961import org .springframework .util .ClassUtils ;
6062import org .springframework .util .CollectionUtils ;
63+ import org .springframework .util .ObjectUtils ;
6164import org .springframework .util .StringUtils ;
6265
6366/**
@@ -88,6 +91,7 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
8891
8992 private final JedisClientConfiguration clientConfiguration ;
9093 private @ Nullable JedisShardInfo shardInfo ;
94+ private JedisClientConfig clientConfig = DefaultJedisClientConfig .builder ().build ();
9195 private boolean providedShardInfo = false ;
9296 private @ Nullable Pool <Jedis > pool ;
9397 private boolean convertPipelineAndTxResults = true ;
@@ -290,17 +294,7 @@ private Jedis createJedis() {
290294 return new Jedis (getShardInfo ());
291295 }
292296
293- Jedis jedis = new Jedis (getHostName (), getPort (), getConnectTimeout (), getReadTimeout (), isUseSsl (),
294- clientConfiguration .getSslSocketFactory ().orElse (null ), //
295- clientConfiguration .getSslParameters ().orElse (null ), //
296- clientConfiguration .getHostnameVerifier ().orElse (null ));
297-
298- Client client = jedis .getClient ();
299-
300- getRedisPassword ().map (String ::new ).ifPresent (client ::setPassword );
301- client .setDb (getDatabase ());
302-
303- return jedis ;
297+ return new Jedis (new HostAndPort (getHostName (), getPort ()), this .clientConfig );
304298 }
305299
306300 /**
@@ -320,6 +314,8 @@ protected JedisConnection postProcessConnection(JedisConnection connection) {
320314 */
321315 public void afterPropertiesSet () {
322316
317+ clientConfig = createClientConfig (getRedisUsername (), getRedisPassword ());
318+
323319 if (shardInfo == null && clientConfiguration instanceof MutableJedisClientConfiguration ) {
324320
325321 providedShardInfo = false ;
@@ -357,6 +353,33 @@ public void afterPropertiesSet() {
357353 }
358354 }
359355
356+ private JedisClientConfig createClientConfig (@ Nullable String username , RedisPassword password ) {
357+
358+ DefaultJedisClientConfig .Builder builder = DefaultJedisClientConfig .builder ();
359+
360+ clientConfiguration .getClientName ().ifPresent (builder ::clientName );
361+ builder .connectionTimeoutMillis (getConnectTimeout ());
362+ builder .socketTimeoutMillis (getReadTimeout ());
363+
364+ builder .databse (getDatabase ());
365+
366+ if (!ObjectUtils .isEmpty (username )) {
367+ builder .user (username );
368+ }
369+ password .toOptional ().map (String ::new ).ifPresent (builder ::password );
370+
371+ if (isUseSsl ()) {
372+
373+ builder .ssl (true );
374+
375+ clientConfiguration .getSslSocketFactory ().ifPresent (builder ::sslSocketFactory );
376+ clientConfiguration .getHostnameVerifier ().ifPresent (builder ::hostnameVerifier );
377+ clientConfiguration .getSslParameters ().ifPresent (builder ::sslParameters );
378+ }
379+
380+ return builder .build ();
381+ }
382+
360383 private Pool <Jedis > createPool () {
361384
362385 if (isRedisSentinelAware ()) {
@@ -374,13 +397,12 @@ private Pool<Jedis> createPool() {
374397 */
375398 protected Pool <Jedis > createRedisSentinelPool (RedisSentinelConfiguration config ) {
376399
377- GenericObjectPoolConfig <? > poolConfig = getPoolConfig () != null ? getPoolConfig () : new JedisPoolConfig ();
400+ GenericObjectPoolConfig <Jedis > poolConfig = getPoolConfig () != null ? getPoolConfig () : new JedisPoolConfig ();
378401 String sentinelUser = null ;
379- String sentinelPassword = config .getSentinelPassword ().toOptional ().map (String ::new ).orElse (null );
380402
403+ JedisClientConfig sentinelConfig = createClientConfig (sentinelUser , config .getSentinelPassword ());
381404 return new JedisSentinelPool (config .getMaster ().getName (), convertToJedisSentinelSet (config .getSentinels ()),
382- poolConfig , getConnectTimeout (), getReadTimeout (), getUsername (), getPassword (), getDatabase (), getClientName (),
383- getConnectTimeout (), getReadTimeout (), sentinelUser , sentinelPassword , getClientName ());
405+ poolConfig , this .clientConfig , sentinelConfig );
384406 }
385407
386408 /**
@@ -390,12 +412,7 @@ poolConfig, getConnectTimeout(), getReadTimeout(), getUsername(), getPassword(),
390412 * @since 1.4
391413 */
392414 protected Pool <Jedis > createRedisPool () {
393-
394- return new JedisPool (getPoolConfig (), getHostName (), getPort (), getConnectTimeout (), getReadTimeout (),
395- getUsername (), getPassword (), getDatabase (), getClientName (), isUseSsl (),
396- clientConfiguration .getSslSocketFactory ().orElse (null ), //
397- clientConfiguration .getSslParameters ().orElse (null ), //
398- clientConfiguration .getHostnameVerifier ().orElse (null ));
415+ return new JedisPool (getPoolConfig (), new HostAndPort (getHostName (), getPort ()), this .clientConfig );
399416 }
400417
401418 private JedisCluster createCluster () {
@@ -423,7 +440,8 @@ protected ClusterTopologyProvider createTopologyProvider(JedisCluster cluster) {
423440 * @return the actual {@link JedisCluster}.
424441 * @since 1.7
425442 */
426- protected JedisCluster createCluster (RedisClusterConfiguration clusterConfig , GenericObjectPoolConfig <?> poolConfig ) {
443+ protected JedisCluster createCluster (RedisClusterConfiguration clusterConfig ,
444+ GenericObjectPoolConfig <Jedis > poolConfig ) {
427445
428446 Assert .notNull (clusterConfig , "Cluster configuration must not be null!" );
429447
@@ -434,10 +452,7 @@ protected JedisCluster createCluster(RedisClusterConfiguration clusterConfig, Ge
434452
435453 int redirects = clusterConfig .getMaxRedirects () != null ? clusterConfig .getMaxRedirects () : 5 ;
436454
437- return new JedisCluster (hostAndPort , getConnectTimeout (), getReadTimeout (), redirects , getUsername (), getPassword (),
438- getClientName (), poolConfig , isUseSsl (), clientConfiguration .getSslSocketFactory ().orElse (null ),
439- clientConfiguration .getSslParameters ().orElse (null ), clientConfiguration .getHostnameVerifier ().orElse (null ),
440- null );
455+ return new JedisCluster (hostAndPort , this .clientConfig , redirects , poolConfig );
441456 }
442457
443458 /*
@@ -553,16 +568,6 @@ public void setUseSsl(boolean useSsl) {
553568 getMutableConfiguration ().setUseSsl (useSsl );
554569 }
555570
556- /**
557- * Returns the username used for authenticating with the Redis server.
558- *
559- * @return username for authentication.
560- */
561- @ Nullable
562- private String getUsername () {
563- return getRedisUsername ();
564- }
565-
566571 /**
567572 * Returns the password used for authenticating with the Redis server.
568573 *
@@ -715,7 +720,7 @@ public void setUsePool(boolean usePool) {
715720 * @return the poolConfig
716721 */
717722 @ Nullable
718- public GenericObjectPoolConfig getPoolConfig () {
723+ public GenericObjectPoolConfig < Jedis > getPoolConfig () {
719724 return clientConfiguration .getPoolConfig ().orElse (null );
720725 }
721726
@@ -877,35 +882,41 @@ private Jedis getActiveSentinel() {
877882 Assert .isTrue (RedisConfiguration .isSentinelConfiguration (configuration ), "SentinelConfig must not be null!" );
878883 SentinelConfiguration sentinelConfiguration = (SentinelConfiguration ) configuration ;
879884
885+ JedisClientConfig clientConfig = createClientConfig (null , sentinelConfiguration .getSentinelPassword ());
880886 for (RedisNode node : sentinelConfiguration .getSentinels ()) {
881887
882- Jedis jedis = new Jedis ( node . getHost (), node . getPort (), getConnectTimeout (), getReadTimeout ()) ;
883- sentinelConfiguration . getSentinelPassword (). toOptional (). map ( String :: new ). ifPresent ( jedis :: auth ) ;
888+ Jedis jedis = null ;
889+ boolean success = false ;
884890
885891 try {
886- if (jedis .ping ().equalsIgnoreCase ("pong" )) {
887892
888- potentiallySetClientName (jedis );
893+ jedis = new Jedis (new HostAndPort (node .getHost (), node .getPort ()), clientConfig );
894+ if (jedis .ping ().equalsIgnoreCase ("pong" )) {
895+ success = true ;
889896 return jedis ;
890897 }
891898 } catch (Exception ex ) {
892899 log .warn (String .format ("Ping failed for sentinel host:%s" , node .getHost ()), ex );
900+ } finally {
901+ if (!success && jedis != null ) {
902+ jedis .close ();
903+ }
893904 }
894905 }
895906
896907 throw new InvalidDataAccessResourceUsageException ("No Sentinel found" );
897908 }
898909
899- private Set <String > convertToJedisSentinelSet (Collection <RedisNode > nodes ) {
910+ private static Set <HostAndPort > convertToJedisSentinelSet (Collection <RedisNode > nodes ) {
900911
901912 if (CollectionUtils .isEmpty (nodes )) {
902913 return Collections .emptySet ();
903914 }
904915
905- Set <String > convertedNodes = new LinkedHashSet <>(nodes .size ());
916+ Set <HostAndPort > convertedNodes = new LinkedHashSet <>(nodes .size ());
906917 for (RedisNode node : nodes ) {
907918 if (node != null ) {
908- convertedNodes .add (node .asString ( ));
919+ convertedNodes .add (new HostAndPort ( node .getHost (), node . getPort () ));
909920 }
910921 }
911922 return convertedNodes ;
0 commit comments