Skip to content

Commit 57b24c5

Browse files
committed
Add convenience factory method to convert RedisURI to RedisConfiguration
Fixes gh-2116
1 parent edde436 commit 57b24c5

File tree

2 files changed

+173
-19
lines changed

2 files changed

+173
-19
lines changed

src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactory.java

+57-14
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,16 @@
1515
*/
1616
package org.springframework.data.redis.connection.lettuce;
1717

18-
import static org.springframework.data.redis.connection.lettuce.LettuceConnection.*;
18+
import java.nio.ByteBuffer;
19+
import java.time.Duration;
20+
import java.util.ArrayList;
21+
import java.util.List;
22+
import java.util.Optional;
23+
import java.util.concurrent.CompletableFuture;
24+
import java.util.concurrent.CompletionStage;
25+
import java.util.concurrent.TimeUnit;
26+
import java.util.function.Consumer;
27+
import java.util.stream.Collectors;
1928

2029
import io.lettuce.core.AbstractRedisClient;
2130
import io.lettuce.core.ClientOptions;
@@ -30,18 +39,6 @@
3039
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;
3140
import io.lettuce.core.codec.RedisCodec;
3241
import io.lettuce.core.resource.ClientResources;
33-
34-
import java.nio.ByteBuffer;
35-
import java.time.Duration;
36-
import java.util.ArrayList;
37-
import java.util.List;
38-
import java.util.Optional;
39-
import java.util.concurrent.CompletableFuture;
40-
import java.util.concurrent.CompletionStage;
41-
import java.util.concurrent.TimeUnit;
42-
import java.util.function.Consumer;
43-
import java.util.stream.Collectors;
44-
4542
import org.apache.commons.logging.Log;
4643
import org.apache.commons.logging.LogFactory;
4744

@@ -52,17 +49,37 @@
5249
import org.springframework.data.redis.ExceptionTranslationStrategy;
5350
import org.springframework.data.redis.PassThroughExceptionTranslationStrategy;
5451
import org.springframework.data.redis.RedisConnectionFailureException;
55-
import org.springframework.data.redis.connection.*;
52+
import org.springframework.data.redis.connection.ClusterCommandExecutor;
53+
import org.springframework.data.redis.connection.ClusterTopologyProvider;
54+
import org.springframework.data.redis.connection.Pool;
55+
import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;
56+
import org.springframework.data.redis.connection.RedisClusterConfiguration;
57+
import org.springframework.data.redis.connection.RedisClusterConnection;
58+
import org.springframework.data.redis.connection.RedisConfiguration;
5659
import org.springframework.data.redis.connection.RedisConfiguration.ClusterConfiguration;
5760
import org.springframework.data.redis.connection.RedisConfiguration.DomainSocketConfiguration;
5861
import org.springframework.data.redis.connection.RedisConfiguration.WithDatabaseIndex;
5962
import org.springframework.data.redis.connection.RedisConfiguration.WithPassword;
63+
import org.springframework.data.redis.connection.RedisConnection;
64+
import org.springframework.data.redis.connection.RedisConnectionFactory;
65+
import org.springframework.data.redis.connection.RedisNode;
66+
import org.springframework.data.redis.connection.RedisPassword;
67+
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
68+
import org.springframework.data.redis.connection.RedisSentinelConnection;
69+
import org.springframework.data.redis.connection.RedisSocketConfiguration;
70+
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
71+
import org.springframework.data.redis.connection.RedisStaticMasterReplicaConfiguration;
6072
import org.springframework.data.util.Optionals;
6173
import org.springframework.lang.Nullable;
6274
import org.springframework.util.Assert;
6375
import org.springframework.util.ClassUtils;
76+
import org.springframework.util.ObjectUtils;
6477
import org.springframework.util.StringUtils;
6578

79+
import static org.springframework.data.redis.connection.lettuce.LettuceConnection.CODEC;
80+
import static org.springframework.data.redis.connection.lettuce.LettuceConnection.LettucePoolConnectionProvider;
81+
import static org.springframework.data.redis.connection.lettuce.LettuceConnection.PipeliningFlushPolicy;
82+
6683
/**
6784
* Connection factory creating <a href="https://github.com/mp911de/lettuce">Lettuce</a>-based connections.
6885
* <p>
@@ -279,6 +296,32 @@ public LettuceConnectionFactory(RedisClusterConfiguration clusterConfiguration,
279296
this.configuration = clusterConfiguration;
280297
}
281298

299+
/**
300+
* Converts a {@link RedisURI} into its corresponding {@link RedisConfiguration} according to the following:
301+
* <ul>
302+
* <li>If {@code redisURI} has sentinel info a {@link RedisSentinelConfiguration} is returned</li>
303+
* <li>If {@code redisURI} has socket info a {@link RedisSocketConfiguration} is returned</li>
304+
* <li>Otherwise a {@link RedisStandaloneConfiguration} is returned</li>
305+
* </ul>
306+
*
307+
* @param redisURI the connection info in the format of a RedisURI
308+
* @return an appropriate {@link RedisConfiguration} instance representing the Redis URI.
309+
*/
310+
public static RedisConfiguration redisConfigurationFromRedisUri(RedisURI redisURI) {
311+
312+
Assert.notNull(redisURI, "RedisURI must not be null");
313+
314+
if (!ObjectUtils.isEmpty(redisURI.getSentinels())) {
315+
return LettuceConverters.redisUriToSentinelConfiguration(redisURI);
316+
}
317+
318+
if (!ObjectUtils.isEmpty(redisURI.getSocket())) {
319+
return LettuceConverters.redisUriToSocketConfiguration(redisURI);
320+
}
321+
322+
return LettuceConverters.redisUriToStandaloneConfiguration(redisURI);
323+
}
324+
282325
/*
283326
* (non-Javadoc)
284327
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()

src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java

+116-5
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,43 @@
1515
*/
1616
package org.springframework.data.redis.connection.lettuce;
1717

18-
import io.lettuce.core.*;
19-
import io.lettuce.core.cluster.models.partitions.Partitions;
20-
import io.lettuce.core.cluster.models.partitions.RedisClusterNode.NodeFlag;
21-
2218
import java.nio.ByteBuffer;
2319
import java.nio.charset.StandardCharsets;
24-
import java.util.*;
20+
import java.util.ArrayList;
21+
import java.util.Arrays;
22+
import java.util.Collection;
23+
import java.util.Collections;
24+
import java.util.Date;
25+
import java.util.Iterator;
26+
import java.util.LinkedHashMap;
27+
import java.util.LinkedHashSet;
28+
import java.util.List;
29+
import java.util.Map;
30+
import java.util.Optional;
31+
import java.util.Set;
2532
import java.util.concurrent.TimeUnit;
2633
import java.util.stream.Collectors;
2734

35+
import io.lettuce.core.BitFieldArgs;
36+
import io.lettuce.core.GeoArgs;
37+
import io.lettuce.core.GeoCoordinates;
38+
import io.lettuce.core.GeoWithin;
39+
import io.lettuce.core.GetExArgs;
40+
import io.lettuce.core.KeyScanArgs;
41+
import io.lettuce.core.KeyValue;
42+
import io.lettuce.core.LMoveArgs;
43+
import io.lettuce.core.Limit;
44+
import io.lettuce.core.Range;
45+
import io.lettuce.core.RedisURI;
46+
import io.lettuce.core.ScanArgs;
47+
import io.lettuce.core.ScoredValue;
48+
import io.lettuce.core.ScriptOutputType;
49+
import io.lettuce.core.SetArgs;
50+
import io.lettuce.core.SortArgs;
51+
import io.lettuce.core.TransactionResult;
52+
import io.lettuce.core.cluster.models.partitions.Partitions;
53+
import io.lettuce.core.cluster.models.partitions.RedisClusterNode.NodeFlag;
54+
2855
import org.springframework.core.convert.converter.Converter;
2956
import org.springframework.dao.DataAccessException;
3057
import org.springframework.data.geo.Distance;
@@ -44,6 +71,7 @@
4471
import org.springframework.data.redis.connection.RedisClusterNode.Flag;
4572
import org.springframework.data.redis.connection.RedisClusterNode.LinkState;
4673
import org.springframework.data.redis.connection.RedisClusterNode.SlotRange;
74+
import org.springframework.data.redis.connection.RedisConfiguration;
4775
import org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit;
4876
import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
4977
import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs;
@@ -54,6 +82,8 @@
5482
import org.springframework.data.redis.connection.RedisPassword;
5583
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
5684
import org.springframework.data.redis.connection.RedisServer;
85+
import org.springframework.data.redis.connection.RedisSocketConfiguration;
86+
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
5787
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
5888
import org.springframework.data.redis.connection.RedisZSetCommands;
5989
import org.springframework.data.redis.connection.RedisZSetCommands.Range.Boundary;
@@ -85,6 +115,7 @@
85115
* @author Mark Paluch
86116
* @author Ninad Divadkar
87117
* @author dengliming
118+
* @author Chris Bono
88119
*/
89120
public abstract class LettuceConverters extends Converters {
90121

@@ -535,6 +566,86 @@ public static RedisURI sentinelConfigurationToRedisURI(RedisSentinelConfiguratio
535566
return builder.build();
536567
}
537568

569+
/**
570+
* Converts a {@link RedisURI} to its corresponding {@link RedisSentinelConfiguration}.
571+
*
572+
* @param redisURI the uri containing the Redis Sentinel connection info
573+
* @return a {@link RedisSentinelConfiguration} representing the Redis Sentinel information in the Redis URI.
574+
* @since 2.6
575+
*/
576+
public static RedisSentinelConfiguration redisUriToSentinelConfiguration(RedisURI redisURI) {
577+
578+
Assert.notNull(redisURI, "RedisURI is required");
579+
Assert.hasText(redisURI.getSentinelMasterId(), "RedisURI must have sentinelMasterId param set");
580+
581+
RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration();
582+
sentinelConfiguration.setMaster(redisURI.getSentinelMasterId());
583+
sentinelConfiguration.setDatabase(redisURI.getDatabase());
584+
585+
for (RedisURI sentinelNodeRedisUri : redisURI.getSentinels()) {
586+
RedisNode sentinelNode = new RedisNode(sentinelNodeRedisUri.getHost(), sentinelNodeRedisUri.getPort());
587+
if (sentinelNodeRedisUri.getPassword() != null) {
588+
sentinelConfiguration.setSentinelPassword(sentinelNodeRedisUri.getPassword());
589+
}
590+
sentinelConfiguration.addSentinel(sentinelNode);
591+
}
592+
593+
applyAuthentication(redisURI, sentinelConfiguration);
594+
595+
return sentinelConfiguration;
596+
}
597+
598+
/**
599+
* Converts a {@link RedisURI} to its corresponding {@link RedisSocketConfiguration}.
600+
*
601+
* @param redisURI the uri containing the Redis connection info using a local unix domain socket
602+
* @return a {@link RedisSocketConfiguration} representing the connection information in the Redis URI.
603+
* @since 2.6
604+
*/
605+
public static RedisSocketConfiguration redisUriToSocketConfiguration(RedisURI redisURI) {
606+
607+
Assert.notNull(redisURI, "RedisURI is required");
608+
Assert.hasText(redisURI.getSocket(), "RedisURI must have socket path set");
609+
610+
RedisSocketConfiguration socketConfiguration = new RedisSocketConfiguration();
611+
socketConfiguration.setSocket(redisURI.getSocket());
612+
socketConfiguration.setDatabase(redisURI.getDatabase());
613+
614+
applyAuthentication(redisURI, socketConfiguration);
615+
616+
return socketConfiguration;
617+
}
618+
619+
/**
620+
* Converts a {@link RedisURI} to its corresponding {@link RedisStandaloneConfiguration}.
621+
*
622+
* @param redisURI the uri containing the Redis connection info
623+
* @return a {@link RedisStandaloneConfiguration} representing the connection information in the Redis URI.
624+
* @since 2.6
625+
*/
626+
public static RedisStandaloneConfiguration redisUriToStandaloneConfiguration(RedisURI redisURI) {
627+
628+
Assert.notNull(redisURI, "RedisURI is required");
629+
630+
RedisStandaloneConfiguration standaloneConfiguration = new RedisStandaloneConfiguration();
631+
standaloneConfiguration.setHostName(redisURI.getHost());
632+
standaloneConfiguration.setPort(redisURI.getPort());
633+
standaloneConfiguration.setDatabase(redisURI.getDatabase());
634+
635+
applyAuthentication(redisURI, standaloneConfiguration);
636+
637+
return standaloneConfiguration;
638+
}
639+
640+
private static void applyAuthentication(RedisURI redisURI, RedisConfiguration.WithAuthentication redisConfiguration) {
641+
if (StringUtils.hasText(redisURI.getUsername())) {
642+
redisConfiguration.setUsername(redisURI.getUsername());
643+
}
644+
if (redisURI.getPassword() != null) {
645+
redisConfiguration.setPassword(redisURI.getPassword());
646+
}
647+
}
648+
538649
public static byte[] toBytes(@Nullable String source) {
539650
if (source == null) {
540651
return null;

0 commit comments

Comments
 (0)