Skip to content

Commit 9b326d5

Browse files
tobi-laawilkinsona
authored andcommitted
Fix handling of Redis nodes with IPv6 addresses
See gh-39819
1 parent ca4d64e commit 9b326d5

File tree

5 files changed

+37
-15
lines changed

5 files changed

+37
-15
lines changed

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,10 @@ public Cluster getCluster() {
113113
}
114114

115115
private Node asNode(String node) {
116-
String[] components = node.split(":");
117-
return new Node(components[0], Integer.parseInt(components[1]));
116+
int portSeparatorIndex = node.lastIndexOf(':');
117+
String host = node.substring(0, portSeparatorIndex);
118+
int port = Integer.parseInt(node.substring(portSeparatorIndex + 1));
119+
return new Node(host, port);
118120
}
119121

120122
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ protected final RedisClusterConfiguration getClusterConfiguration() {
139139
}
140140

141141
private List<String> getNodes(Cluster cluster) {
142-
return cluster.getNodes().stream().map((node) -> "%s:%d".formatted(node.host(), node.port())).toList();
142+
return cluster.getNodes().stream().map(Node::asString).toList();
143143
}
144144

145145
protected final RedisProperties getProperties() {
@@ -162,7 +162,7 @@ protected boolean isPoolEnabled(Pool pool) {
162162
private List<RedisNode> createSentinels(Sentinel sentinel) {
163163
List<RedisNode> nodes = new ArrayList<>();
164164
for (Node node : sentinel.getNodes()) {
165-
nodes.add(new RedisNode(node.host(), node.port()));
165+
nodes.add(RedisNode.fromString(node.asString()));
166166
}
167167
return nodes;
168168
}

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

+3
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ interface Cluster {
185185
*/
186186
record Node(String host, int port) {
187187

188+
String asString() {
189+
return this.host + ":" + this.port;
190+
}
188191
}
189192

190193
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/PropertiesRedisConnectionDetailsTests.java

+14-3
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,23 @@ void standaloneIsConfiguredFromProperties() {
119119
@Test
120120
void clusterIsConfigured() {
121121
RedisProperties.Cluster cluster = new RedisProperties.Cluster();
122-
cluster.setNodes(List.of("first:1111", "second:2222", "third:3333"));
122+
cluster.setNodes(List.of("localhost:1111", "127.0.0.1:2222", "[::1]:3333"));
123123
this.properties.setCluster(cluster);
124124
PropertiesRedisConnectionDetails connectionDetails = new PropertiesRedisConnectionDetails(this.properties);
125125
assertThat(connectionDetails.getCluster().getNodes()).containsExactly(
126-
new RedisConnectionDetails.Node("first", 1111), new RedisConnectionDetails.Node("second", 2222),
127-
new RedisConnectionDetails.Node("third", 3333));
126+
new RedisConnectionDetails.Node("localhost", 1111), new RedisConnectionDetails.Node("127.0.0.1", 2222),
127+
new RedisConnectionDetails.Node("[::1]", 3333));
128+
}
129+
130+
@Test
131+
void sentinelIsConfigured() {
132+
RedisProperties.Sentinel sentinel = new RedisProperties.Sentinel();
133+
sentinel.setNodes(List.of("localhost:1111", "127.0.0.1:2222", "[::1]:3333"));
134+
this.properties.setSentinel(sentinel);
135+
PropertiesRedisConnectionDetails connectionDetails = new PropertiesRedisConnectionDetails(this.properties);
136+
assertThat(connectionDetails.getSentinel().getNodes()).containsExactly(
137+
new RedisConnectionDetails.Node("localhost", 1111), new RedisConnectionDetails.Node("127.0.0.1", 2222),
138+
new RedisConnectionDetails.Node("[::1]", 3333));
128139
}
129140

130141
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/redis/RedisAutoConfigurationTests.java

+14-8
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,14 @@ void testRedisConfigurationWithIpv6Sentinel() {
308308
this.contextRunner
309309
.withPropertyValues("spring.data.redis.sentinel.master:mymaster",
310310
"spring.data.redis.sentinel.nodes:" + StringUtils.collectionToCommaDelimitedString(sentinels))
311-
.run((context) -> assertThat(context.getBean(LettuceConnectionFactory.class).isRedisSentinelAware())
312-
.isTrue());
311+
.run((context) -> {
312+
assertThat(context.getBean(LettuceConnectionFactory.class).isRedisSentinelAware()).isTrue();
313+
assertThat(context.getBean(LettuceConnectionFactory.class).getSentinelConfiguration()).isNotNull();
314+
assertThat(context.getBean(LettuceConnectionFactory.class).getSentinelConfiguration().getSentinels())
315+
.isNotNull()
316+
.extracting(RedisNode::toString)
317+
.containsExactlyInAnyOrder("[0:0:0:0:0:0:0:1]:26379", "[0:0:0:0:0:0:0:1]:26380");
318+
});
313319
}
314320

315321
@Test
@@ -394,17 +400,17 @@ void testRedisSentinelUrlConfiguration() {
394400

395401
@Test
396402
void testRedisConfigurationWithCluster() {
397-
List<String> clusterNodes = Arrays.asList("127.0.0.1:27379", "127.0.0.1:27380");
403+
List<String> clusterNodes = Arrays.asList("127.0.0.1:27379", "127.0.0.1:27380", "[::1]:27381");
398404
this.contextRunner
399405
.withPropertyValues("spring.data.redis.cluster.nodes[0]:" + clusterNodes.get(0),
400-
"spring.data.redis.cluster.nodes[1]:" + clusterNodes.get(1))
406+
"spring.data.redis.cluster.nodes[1]:" + clusterNodes.get(1),
407+
"spring.data.redis.cluster.nodes[2]:" + clusterNodes.get(2))
401408
.run((context) -> {
402409
RedisClusterConfiguration clusterConfiguration = context.getBean(LettuceConnectionFactory.class)
403410
.getClusterConfiguration();
404-
assertThat(clusterConfiguration.getClusterNodes()).hasSize(2);
405-
assertThat(clusterConfiguration.getClusterNodes())
406-
.extracting((node) -> node.getHost() + ":" + node.getPort())
407-
.containsExactlyInAnyOrder("127.0.0.1:27379", "127.0.0.1:27380");
411+
assertThat(clusterConfiguration.getClusterNodes()).hasSize(3);
412+
assertThat(clusterConfiguration.getClusterNodes()).extracting(RedisNode::asString)
413+
.containsExactlyInAnyOrder("127.0.0.1:27379", "127.0.0.1:27380", "[::1]:27381");
408414
});
409415

410416
}

0 commit comments

Comments
 (0)