Skip to content

Commit 020ef9c

Browse files
TheTweakmp911de
authored andcommitted
Add support for bracket-less IPv6 addresses to CLUSTER NODES Converter.
Closes #2678 Original pull request: #2679
1 parent 236b072 commit 020ef9c

File tree

2 files changed

+53
-4
lines changed

2 files changed

+53
-4
lines changed

src/main/java/org/springframework/data/redis/connection/convert/Converters.java

+14-4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
* @author Thomas Darimont
5858
* @author Mark Paluch
5959
* @author Christoph Strobl
60+
* @author John Blum
61+
* @author Sorokin Evgeniy
6062
*/
6163
public abstract class Converters {
6264

@@ -554,20 +556,28 @@ enum ClusterNodesConverter implements Converter<String, RedisClusterNode> {
554556
public RedisClusterNode convert(String source) {
555557

556558
String[] args = source.split(" ");
557-
String[] hostAndPort = StringUtils.split(args[HOST_PORT_INDEX], ":");
558559

559-
Assert.notNull(hostAndPort, "ClusterNode information does not define host and port");
560+
int lastColonIndex = args[HOST_PORT_INDEX].lastIndexOf(":");
561+
562+
Assert.isTrue(lastColonIndex >= 0 && lastColonIndex < args[HOST_PORT_INDEX].length() - 1,
563+
"ClusterNode information does not define host and port");
564+
565+
String portPart = args[HOST_PORT_INDEX].substring(lastColonIndex + 1);
566+
String hostPart = args[HOST_PORT_INDEX].substring(0, lastColonIndex);
560567

561568
SlotRange range = parseSlotRange(args);
562569
Set<Flag> flags = parseFlags(args);
563570

564-
String portPart = hostAndPort[1];
565571
if (portPart.contains("@")) {
566572
portPart = portPart.substring(0, portPart.indexOf('@'));
567573
}
568574

575+
if (hostPart.startsWith("[") && hostPart.endsWith("]")) {
576+
hostPart = hostPart.substring(1, hostPart.length() - 1);
577+
}
578+
569579
RedisClusterNodeBuilder nodeBuilder = RedisClusterNode.newRedisClusterNode()
570-
.listeningAt(hostAndPort[0], Integer.valueOf(portPart)) //
580+
.listeningAt(hostPart, Integer.valueOf(portPart)) //
571581
.withId(args[ID_INDEX]) //
572582
.promotedAs(flags.contains(Flag.MASTER) ? NodeType.MASTER : NodeType.REPLICA) //
573583
.serving(range) //

src/test/java/org/springframework/data/redis/connection/convert/ConvertersUnitTests.java

+39
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
*
3232
* @author Christoph Strobl
3333
* @author Mark Paluch
34+
* @author Sorokin Evgeniy
3435
*/
3536
class ConvertersUnitTests {
3637

@@ -60,6 +61,12 @@ class ConvertersUnitTests {
6061

6162
private static final String CLUSTER_NODE_WITHOUT_HOST = "ef570f86c7b1a953846668debc177a3a16733420 :6379 fail,master - 0 0 1 connected";
6263

64+
private static final String CLUSTER_NODE_WITH_SINGLE_IPV6_HOST = "67adfe3df1058896e3cb49d2863e0f70e7e159fa 2a02:6b8:c67:9c:0:6d8b:33da:5a2c:6380@16380,redis-master master,nofailover - 0 1692108412315 1 connected 0-5460";
65+
66+
private static final String CLUSTER_NODE_WITH_SINGLE_IPV6_HOST_SQUARE_BRACKETS = "67adfe3df1058896e3cb49d2863e0f70e7e159fa [2a02:6b8:c67:9c:0:6d8b:33da:5a2c]:6380@16380,redis-master master,nofailover - 0 1692108412315 1 connected 0-5460";
67+
68+
private static final String CLUSTER_NODE_WITH_SINGLE_INVALID_IPV6_HOST = "67adfe3df1058896e3cb49d2863e0f70e7e159fa 2a02:6b8:c67:9c:0:6d8b:33da:5a2c: master,nofailover - 0 1692108412315 1 connected 0-5460";
69+
6370
@Test // DATAREDIS-315
6471
void toSetOfRedis30ClusterNodesShouldConvertSingleStringNodesResponseCorrectly() {
6572

@@ -222,4 +229,36 @@ void toSetOfRedisClusterNodesShouldAllowEmptyHostname() {
222229
assertThat(node.getSlotRange().getSlots().size()).isEqualTo(0);
223230
}
224231

232+
@Test // https://github.com/spring-projects/spring-data-redis/issues/2678
233+
void toClusterNodeWithIPv6Hostname() {
234+
RedisClusterNode node = Converters.toClusterNode(CLUSTER_NODE_WITH_SINGLE_IPV6_HOST);
235+
236+
assertThat(node.getId()).isEqualTo("67adfe3df1058896e3cb49d2863e0f70e7e159fa");
237+
assertThat(node.getHost()).isEqualTo("2a02:6b8:c67:9c:0:6d8b:33da:5a2c");
238+
assertThat(node.hasValidHost()).isTrue();
239+
assertThat(node.getPort()).isEqualTo(6380);
240+
assertThat(node.getType()).isEqualTo(NodeType.MASTER);
241+
assertThat(node.getFlags()).contains(Flag.MASTER);
242+
assertThat(node.getLinkState()).isEqualTo(LinkState.CONNECTED);
243+
assertThat(node.getSlotRange().getSlots().size()).isEqualTo(5461);
244+
}
245+
246+
@Test // https://github.com/spring-projects/spring-data-redis/issues/2678
247+
void toClusterNodeWithIPv6HostnameSquareBrackets() {
248+
RedisClusterNode node = Converters.toClusterNode(CLUSTER_NODE_WITH_SINGLE_IPV6_HOST_SQUARE_BRACKETS);
249+
250+
assertThat(node.getId()).isEqualTo("67adfe3df1058896e3cb49d2863e0f70e7e159fa");
251+
assertThat(node.getHost()).isEqualTo("2a02:6b8:c67:9c:0:6d8b:33da:5a2c");
252+
assertThat(node.hasValidHost()).isTrue();
253+
assertThat(node.getPort()).isEqualTo(6380);
254+
assertThat(node.getType()).isEqualTo(NodeType.MASTER);
255+
assertThat(node.getFlags()).contains(Flag.MASTER);
256+
assertThat(node.getLinkState()).isEqualTo(LinkState.CONNECTED);
257+
assertThat(node.getSlotRange().getSlots().size()).isEqualTo(5461);
258+
}
259+
260+
@Test // https://github.com/spring-projects/spring-data-redis/issues/2678
261+
void toClusterNodeWithInvalidIPv6Hostname() {
262+
assertThatIllegalArgumentException().isThrownBy(() -> Converters.toClusterNode(CLUSTER_NODE_WITH_SINGLE_INVALID_IPV6_HOST));
263+
}
225264
}

0 commit comments

Comments
 (0)