17
17
package org .springframework .boot .data .redis .autoconfigure ;
18
18
19
19
import java .time .Duration ;
20
+ import java .util .Collections ;
21
+ import java .util .List ;
20
22
21
23
import io .lettuce .core .ClientOptions ;
22
24
import io .lettuce .core .ReadFrom ;
37
39
import org .springframework .boot .autoconfigure .condition .ConditionalOnMissingBean ;
38
40
import org .springframework .boot .autoconfigure .condition .ConditionalOnProperty ;
39
41
import org .springframework .boot .autoconfigure .condition .ConditionalOnThreading ;
42
+ import org .springframework .boot .data .redis .autoconfigure .RedisConnectionDetails .Node ;
40
43
import org .springframework .boot .data .redis .autoconfigure .RedisProperties .Lettuce .Cluster .Refresh ;
44
+ import org .springframework .boot .data .redis .autoconfigure .RedisProperties .Lettuce .StaticMasterReplica ;
41
45
import org .springframework .boot .data .redis .autoconfigure .RedisProperties .Pool ;
42
46
import org .springframework .boot .ssl .SslBundle ;
43
47
import org .springframework .boot .ssl .SslOptions ;
55
59
import org .springframework .data .redis .connection .lettuce .LettuceConnectionFactory ;
56
60
import org .springframework .data .redis .connection .lettuce .LettucePoolingClientConfiguration ;
57
61
import org .springframework .util .Assert ;
62
+ import org .springframework .util .CollectionUtils ;
58
63
import org .springframework .util .StringUtils ;
59
64
60
65
/**
@@ -76,10 +81,9 @@ class LettuceConnectionConfiguration extends RedisConnectionConfiguration {
76
81
ObjectProvider <RedisStandaloneConfiguration > standaloneConfigurationProvider ,
77
82
ObjectProvider <RedisSentinelConfiguration > sentinelConfigurationProvider ,
78
83
ObjectProvider <RedisClusterConfiguration > clusterConfigurationProvider ,
79
- ObjectProvider <RedisStaticMasterReplicaConfiguration > staticMasterReplicaConfigurationProvider ,
80
84
RedisConnectionDetails connectionDetails ) {
81
85
super (properties , connectionDetails , standaloneConfigurationProvider , sentinelConfigurationProvider ,
82
- clusterConfigurationProvider , staticMasterReplicaConfigurationProvider );
86
+ clusterConfigurationProvider );
83
87
}
84
88
85
89
@ Bean (destroyMethod = "shutdown" )
@@ -123,6 +127,12 @@ private LettuceConnectionFactory createConnectionFactory(
123
127
LettuceClientConfiguration clientConfiguration = getLettuceClientConfiguration (
124
128
clientConfigurationBuilderCustomizers , clientOptionsBuilderCustomizers , clientResources ,
125
129
getProperties ().getLettuce ().getPool ());
130
+
131
+ RedisStaticMasterReplicaConfiguration staticMasterReplicaConfiguration = getStaticMasterReplicaConfiguration ();
132
+ if (staticMasterReplicaConfiguration != null ) {
133
+ return new LettuceConnectionFactory (staticMasterReplicaConfiguration , clientConfiguration );
134
+ }
135
+
126
136
return switch (this .mode ) {
127
137
case STANDALONE -> new LettuceConnectionFactory (getStandaloneConfig (), clientConfiguration );
128
138
case CLUSTER -> {
@@ -135,15 +145,29 @@ private LettuceConnectionFactory createConnectionFactory(
135
145
Assert .state (sentinelConfig != null , "'sentinelConfig' must not be null" );
136
146
yield new LettuceConnectionFactory (sentinelConfig , clientConfiguration );
137
147
}
138
- case STATIC_MASTER_REPLICA -> {
139
- RedisStaticMasterReplicaConfiguration staticMasterReplicaConfiguration = getStaticMasterReplicaConfiguration ();
140
- Assert .state (staticMasterReplicaConfiguration != null ,
141
- "'staticMasterReplicaConfiguration' must not be null" );
142
- yield new LettuceConnectionFactory (staticMasterReplicaConfiguration , clientConfiguration );
143
- }
144
148
};
145
149
}
146
150
151
+ private @ Nullable RedisStaticMasterReplicaConfiguration getStaticMasterReplicaConfiguration () {
152
+ StaticMasterReplica staticMasterReplica = getProperties ().getLettuce ().getStaticMasterReplica ();
153
+
154
+ if (!CollectionUtils .isEmpty (staticMasterReplica .getNodes ())) {
155
+ List <Node > nodes = asNodes (staticMasterReplica .getNodes ());
156
+ RedisStaticMasterReplicaConfiguration configuration = new RedisStaticMasterReplicaConfiguration (
157
+ nodes .get (0 ).host (), nodes .get (0 ).port ());
158
+ configuration .setUsername (getProperties ().getUsername ());
159
+ if (StringUtils .hasText (getProperties ().getPassword ())) {
160
+ configuration .setPassword (getProperties ().getPassword ());
161
+ }
162
+ configuration .setDatabase (getProperties ().getDatabase ());
163
+ nodes .stream ().skip (1 ).forEach ((node ) -> configuration .addNode (node .host (), node .port ()));
164
+
165
+ return configuration ;
166
+ }
167
+
168
+ return null ;
169
+ }
170
+
147
171
private LettuceClientConfiguration getLettuceClientConfiguration (
148
172
ObjectProvider <LettuceClientConfigurationBuilderCustomizer > clientConfigurationBuilderCustomizers ,
149
173
ObjectProvider <LettuceClientOptionsBuilderCustomizer > clientOptionsBuilderCustomizers ,
@@ -259,6 +283,20 @@ private void customizeConfigurationFromUrl(LettuceClientConfiguration.LettuceCli
259
283
}
260
284
}
261
285
286
+ private List <Node > asNodes (@ Nullable List <String > nodes ) {
287
+ if (nodes == null ) {
288
+ return Collections .emptyList ();
289
+ }
290
+ return nodes .stream ().map (this ::asNode ).toList ();
291
+ }
292
+
293
+ private Node asNode (String node ) {
294
+ int portSeparatorIndex = node .lastIndexOf (':' );
295
+ String host = node .substring (0 , portSeparatorIndex );
296
+ int port = Integer .parseInt (node .substring (portSeparatorIndex + 1 ));
297
+ return new Node (host , port );
298
+ }
299
+
262
300
/**
263
301
* Inner class to allow optional commons-pool2 dependency.
264
302
*/
0 commit comments