Skip to content

Commit ac55caa

Browse files
wilkinsonamhalbritterphilwebb
committed
Add ConnectionDetail support to Redis auto-configuration
Update Redis auto-configuration so that `RedisConnectionDetails` beans may be optionally used to provide connection details. See gh-34657 Co-Authored-By: Mortitz Halbritter <[email protected]> Co-Authored-By: Phillip Webb <[email protected]>
1 parent 69f31cb commit ac55caa

File tree

7 files changed

+621
-67
lines changed

7 files changed

+621
-67
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/JedisConnectionConfiguration.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -42,6 +42,9 @@
4242
*
4343
* @author Mark Paluch
4444
* @author Stephane Nicoll
45+
* @author Moritz Halbritter
46+
* @author Andy Wilkinson
47+
* @author Phillip Webb
4548
*/
4649
@Configuration(proxyBeanMethods = false)
4750
@ConditionalOnClass({ GenericObjectPool.class, JedisConnection.class, Jedis.class })
@@ -52,8 +55,10 @@ class JedisConnectionConfiguration extends RedisConnectionConfiguration {
5255
JedisConnectionConfiguration(RedisProperties properties,
5356
ObjectProvider<RedisStandaloneConfiguration> standaloneConfigurationProvider,
5457
ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
55-
ObjectProvider<RedisClusterConfiguration> clusterConfiguration) {
56-
super(properties, standaloneConfigurationProvider, sentinelConfiguration, clusterConfiguration);
58+
ObjectProvider<RedisClusterConfiguration> clusterConfiguration,
59+
ObjectProvider<RedisConnectionDetails> connectionDetailsProvider) {
60+
super(properties, standaloneConfigurationProvider, sentinelConfiguration, clusterConfiguration,
61+
connectionDetailsProvider);
5762
}
5863

5964
@Bean
@@ -90,7 +95,9 @@ private JedisClientConfiguration getJedisClientConfiguration(
9095

9196
private JedisClientConfigurationBuilder applyProperties(JedisClientConfigurationBuilder builder) {
9297
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
93-
map.from(getProperties().isSsl()).whenTrue().toCall(builder::useSsl);
98+
boolean ssl = (!(getConnectionDetails() instanceof PropertiesRedisConnectionDetails)) ? false
99+
: getProperties().isSsl();
100+
map.from(ssl).whenTrue().toCall(builder::useSsl);
94101
map.from(getProperties().getTimeout()).to(builder::readTimeout);
95102
map.from(getProperties().getConnectTimeout()).to(builder::connectTimeout);
96103
map.from(getProperties().getClientName()).whenHasText().to(builder::clientName);
@@ -117,8 +124,7 @@ private JedisPoolConfig jedisPoolConfig(RedisProperties.Pool pool) {
117124
}
118125

119126
private void customizeConfigurationFromUrl(JedisClientConfiguration.JedisClientConfigurationBuilder builder) {
120-
ConnectionInfo connectionInfo = parseUrl(getProperties().getUrl());
121-
if (connectionInfo.isUseSsl()) {
127+
if (urlUsesSsl()) {
122128
builder.useSsl();
123129
}
124130
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/redis/LettuceConnectionConfiguration.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
*
5353
* @author Mark Paluch
5454
* @author Andy Wilkinson
55+
* @author Moritz Halbritter
56+
* @author Phillip Webb
5557
*/
5658
@Configuration(proxyBeanMethods = false)
5759
@ConditionalOnClass(RedisClient.class)
@@ -61,8 +63,10 @@ class LettuceConnectionConfiguration extends RedisConnectionConfiguration {
6163
LettuceConnectionConfiguration(RedisProperties properties,
6264
ObjectProvider<RedisStandaloneConfiguration> standaloneConfigurationProvider,
6365
ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider,
64-
ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider) {
65-
super(properties, standaloneConfigurationProvider, sentinelConfigurationProvider, clusterConfigurationProvider);
66+
ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider,
67+
ObjectProvider<RedisConnectionDetails> connectionDetailsProvider) {
68+
super(properties, standaloneConfigurationProvider, sentinelConfigurationProvider, clusterConfigurationProvider,
69+
connectionDetailsProvider);
6670
}
6771

6872
@Bean(destroyMethod = "shutdown")
@@ -116,7 +120,7 @@ private LettuceClientConfigurationBuilder createBuilder(Pool pool) {
116120

117121
private LettuceClientConfigurationBuilder applyProperties(
118122
LettuceClientConfiguration.LettuceClientConfigurationBuilder builder) {
119-
if (getProperties().isSsl()) {
123+
if (getConnectionDetails() instanceof PropertiesRedisConnectionDetails && getProperties().isSsl()) {
120124
builder.useSsl();
121125
}
122126
if (getProperties().getTimeout() != null) {
@@ -161,8 +165,7 @@ private ClientOptions.Builder initializeClientOptionsBuilder() {
161165
}
162166

163167
private void customizeConfigurationFromUrl(LettuceClientConfiguration.LettuceClientConfigurationBuilder builder) {
164-
ConnectionInfo connectionInfo = parseUrl(getProperties().getUrl());
165-
if (connectionInfo.isUseSsl()) {
168+
if (urlUsesSsl()) {
166169
builder.useSsl();
167170
}
168171
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* Copyright 2012-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.data.redis;
18+
19+
import java.util.List;
20+
21+
import org.springframework.boot.autoconfigure.data.redis.RedisConnectionConfiguration.ConnectionInfo;
22+
23+
/**
24+
* Adapts {@link RedisProperties} to {@link RedisConnectionDetails}.
25+
*
26+
* @author Moritz Halbritter
27+
* @author Andy Wilkinson
28+
* @author Phillip Webb
29+
*/
30+
class PropertiesRedisConnectionDetails implements RedisConnectionDetails {
31+
32+
private final RedisProperties properties;
33+
34+
PropertiesRedisConnectionDetails(RedisProperties properties) {
35+
this.properties = properties;
36+
}
37+
38+
@Override
39+
public String getUsername() {
40+
if (this.properties.getUrl() != null) {
41+
ConnectionInfo connectionInfo = connectionInfo(this.properties.getUrl());
42+
String userInfo = connectionInfo.getUri().getUserInfo();
43+
int index = (userInfo != null) ? userInfo.indexOf(':') : -1;
44+
if (index != -1) {
45+
return userInfo.substring(0, index);
46+
}
47+
}
48+
return this.properties.getUsername();
49+
}
50+
51+
@Override
52+
public String getPassword() {
53+
if (this.properties.getUrl() != null) {
54+
ConnectionInfo connectionInfo = connectionInfo(this.properties.getUrl());
55+
String userInfo = connectionInfo.getUri().getUserInfo();
56+
int index = (userInfo != null) ? userInfo.indexOf(':') : -1;
57+
if (index != -1) {
58+
return userInfo.substring(index + 1);
59+
}
60+
}
61+
return this.properties.getPassword();
62+
}
63+
64+
@Override
65+
public Standalone getStandalone() {
66+
if (this.properties.getUrl() != null) {
67+
ConnectionInfo connectionInfo = connectionInfo(this.properties.getUrl());
68+
return Standalone.of(connectionInfo.getUri().getHost(), connectionInfo.getUri().getPort(),
69+
this.properties.getDatabase());
70+
}
71+
return Standalone.of(this.properties.getHost(), this.properties.getPort(), this.properties.getDatabase());
72+
}
73+
74+
private ConnectionInfo connectionInfo(String url) {
75+
return (url != null) ? RedisConnectionConfiguration.parseUrl(url) : null;
76+
}
77+
78+
@Override
79+
public Sentinel getSentinel() {
80+
org.springframework.boot.autoconfigure.data.redis.RedisProperties.Sentinel sentinel = this.properties
81+
.getSentinel();
82+
if (sentinel == null) {
83+
return null;
84+
}
85+
return new Sentinel() {
86+
87+
@Override
88+
public int getDatabase() {
89+
return PropertiesRedisConnectionDetails.this.properties.getDatabase();
90+
}
91+
92+
@Override
93+
public String getMaster() {
94+
return sentinel.getMaster();
95+
}
96+
97+
@Override
98+
public List<Node> getNodes() {
99+
return sentinel.getNodes().stream().map(PropertiesRedisConnectionDetails.this::asNode).toList();
100+
}
101+
102+
@Override
103+
public String getUsername() {
104+
return sentinel.getUsername();
105+
}
106+
107+
@Override
108+
public String getPassword() {
109+
return sentinel.getPassword();
110+
}
111+
112+
};
113+
}
114+
115+
@Override
116+
public Cluster getCluster() {
117+
RedisProperties.Cluster cluster = this.properties.getCluster();
118+
List<Node> nodes = (cluster != null) ? cluster.getNodes().stream().map(this::asNode).toList() : null;
119+
return (nodes != null) ? () -> nodes : null;
120+
}
121+
122+
private Node asNode(String node) {
123+
String[] components = node.split(":");
124+
return new Node(components[0], Integer.parseInt(components[1]));
125+
}
126+
127+
}

0 commit comments

Comments
 (0)