20
20
import java .time .Duration ;
21
21
import java .util .*;
22
22
import java .util .concurrent .TimeUnit ;
23
+ import java .util .regex .Matcher ;
24
+ import java .util .regex .Pattern ;
23
25
24
26
import org .apache .commons .logging .Log ;
25
27
import org .apache .commons .logging .LogFactory ;
@@ -178,8 +180,8 @@ public static Set<RedisClusterNode> toSetOfRedisClusterNodes(Collection<String>
178
180
public static Set <RedisClusterNode > toSetOfRedisClusterNodes (String clusterNodes ) {
179
181
180
182
return StringUtils .hasText (clusterNodes )
181
- ? toSetOfRedisClusterNodes (Arrays .asList (clusterNodes .split (CLUSTER_NODES_LINE_SEPARATOR )))
182
- : Collections .emptySet ();
183
+ ? toSetOfRedisClusterNodes (Arrays .asList (clusterNodes .split (CLUSTER_NODES_LINE_SEPARATOR )))
184
+ : Collections .emptySet ();
183
185
}
184
186
185
187
public static List <Object > toObjects (Set <Tuple > tuples ) {
@@ -386,8 +388,7 @@ public static Object parse(Object source, String sourcePath, Map<String, Class<?
386
388
387
389
if (targetType == null ) {
388
390
389
- String alternatePath = sourcePath .contains ("." )
390
- ? sourcePath .substring (0 , sourcePath .lastIndexOf ("." )) + ".*"
391
+ String alternatePath = sourcePath .contains ("." ) ? sourcePath .substring (0 , sourcePath .lastIndexOf ("." )) + ".*"
391
392
: sourcePath ;
392
393
393
394
targetType = typeHintMap .get (alternatePath );
@@ -527,8 +528,9 @@ public GeoResults<GeoLocation<V>> convert(GeoResults<GeoLocation<byte[]>> source
527
528
List <GeoResult <GeoLocation <V >>> values = new ArrayList <>(source .getContent ().size ());
528
529
529
530
for (GeoResult <GeoLocation <byte []>> value : source .getContent ()) {
530
- values .add (new GeoResult <>(new GeoLocation <>(serializer .deserialize (value .getContent ().getName ()),
531
- value .getContent ().getPoint ()), value .getDistance ()));
531
+ values .add (new GeoResult <>(
532
+ new GeoLocation <>(serializer .deserialize (value .getContent ().getName ()), value .getContent ().getPoint ()),
533
+ value .getDistance ()));
532
534
}
533
535
534
536
return new GeoResults <>(values , source .getAverageDistance ().getMetric ());
@@ -539,6 +541,16 @@ enum ClusterNodesConverter implements Converter<String, RedisClusterNode> {
539
541
540
542
INSTANCE ;
541
543
544
+ /**
545
+ * Support following printf patterns:
546
+ * <ul>
547
+ * <li>{@code %s:%i} (Redis 3)</li>
548
+ * <li>{@code %s:%i@%i} (Redis 4, with bus port)</li>
549
+ * <li>{@code %s:%i@%i,%s} (Redis 7, with announced hostname)</li>
550
+ * </ul>
551
+ */
552
+ static final Pattern clusterEndpointPattern = Pattern
553
+ .compile ("\\ [?([0-9a-zA-Z\\ -_\\ .:]*)\\ ]?:([0-9]+)(?:@[0-9]+(?:,([^,].*))?)?" );
542
554
private static final Map <String , Flag > flagLookupMap ;
543
555
544
556
static {
@@ -562,33 +574,29 @@ public RedisClusterNode convert(String source) {
562
574
563
575
String [] args = source .split (" " );
564
576
565
- int lastColonIndex = args [HOST_PORT_INDEX ]. lastIndexOf ( ":" );
577
+ Matcher matcher = clusterEndpointPattern . matcher ( args [HOST_PORT_INDEX ]);
566
578
567
- Assert .isTrue (lastColonIndex >= 0 && lastColonIndex < args [HOST_PORT_INDEX ].length () - 1 ,
568
- "ClusterNode information does not define host and port" );
579
+ Assert .isTrue (matcher .matches (), "ClusterNode information does not define host and port" );
569
580
570
- String portPart = args [HOST_PORT_INDEX ].substring (lastColonIndex + 1 );
571
- String hostPart = args [HOST_PORT_INDEX ].substring (0 , lastColonIndex );
581
+ String addressPart = matcher .group (1 );
582
+ String portPart = matcher .group (2 );
583
+ String hostnamePart = matcher .group (3 );
572
584
573
585
SlotRange range = parseSlotRange (args );
574
586
Set <Flag > flags = parseFlags (args );
575
587
576
- if (portPart .contains ("@" )) {
577
- portPart = portPart .substring (0 , portPart .indexOf ('@' ));
578
- }
579
-
580
- if (hostPart .startsWith ("[" ) && hostPart .endsWith ("]" )) {
581
- hostPart = hostPart .substring (1 , hostPart .length () - 1 );
582
- }
583
-
584
588
RedisClusterNodeBuilder nodeBuilder = RedisClusterNode .newRedisClusterNode ()
585
- .listeningAt (hostPart , Integer .parseInt (portPart )) //
589
+ .listeningAt (addressPart , Integer .parseInt (portPart )) //
586
590
.withId (args [ID_INDEX ]) //
587
591
.promotedAs (flags .contains (Flag .MASTER ) ? NodeType .MASTER : NodeType .REPLICA ) //
588
592
.serving (range ) //
589
593
.withFlags (flags ) //
590
594
.linkState (parseLinkState (args ));
591
595
596
+ if (hostnamePart != null ) {
597
+ nodeBuilder .withName (hostnamePart );
598
+ }
599
+
592
600
if (!args [MASTER_ID_INDEX ].isEmpty () && !args [MASTER_ID_INDEX ].startsWith ("-" )) {
593
601
nodeBuilder .replicaOf (args [MASTER_ID_INDEX ]);
594
602
}
0 commit comments