Polishing.

Use Regex to capture the various styles of CLUSTER NODES endpoint representations.

See #2678
Original pull request: #2679
This commit is contained in:
Mark Paluch
2023-08-16 11:53:31 +02:00
parent d1908fdbfc
commit 372d26ab21
2 changed files with 75 additions and 26 deletions

View File

@@ -20,6 +20,8 @@ import java.nio.ByteBuffer;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -178,8 +180,8 @@ public abstract class Converters {
public static Set<RedisClusterNode> toSetOfRedisClusterNodes(String clusterNodes) {
return StringUtils.hasText(clusterNodes)
? toSetOfRedisClusterNodes(Arrays.asList(clusterNodes.split(CLUSTER_NODES_LINE_SEPARATOR)))
: Collections.emptySet();
? toSetOfRedisClusterNodes(Arrays.asList(clusterNodes.split(CLUSTER_NODES_LINE_SEPARATOR)))
: Collections.emptySet();
}
public static List<Object> toObjects(Set<Tuple> tuples) {
@@ -386,8 +388,7 @@ public abstract class Converters {
if (targetType == null) {
String alternatePath = sourcePath.contains(".")
? sourcePath.substring(0, sourcePath.lastIndexOf(".")) + ".*"
String alternatePath = sourcePath.contains(".") ? sourcePath.substring(0, sourcePath.lastIndexOf(".")) + ".*"
: sourcePath;
targetType = typeHintMap.get(alternatePath);
@@ -527,8 +528,9 @@ public abstract class Converters {
List<GeoResult<GeoLocation<V>>> values = new ArrayList<>(source.getContent().size());
for (GeoResult<GeoLocation<byte[]>> value : source.getContent()) {
values.add(new GeoResult<>(new GeoLocation<>(serializer.deserialize(value.getContent().getName()),
value.getContent().getPoint()), value.getDistance()));
values.add(new GeoResult<>(
new GeoLocation<>(serializer.deserialize(value.getContent().getName()), value.getContent().getPoint()),
value.getDistance()));
}
return new GeoResults<>(values, source.getAverageDistance().getMetric());
@@ -539,6 +541,16 @@ public abstract class Converters {
INSTANCE;
/**
* Support following printf patterns:
* <ul>
* <li>{@code %s:%i} (Redis 3)</li>
* <li>{@code %s:%i@%i} (Redis 4, with bus port)</li>
* <li>{@code %s:%i@%i,%s} (Redis 7, with announced hostname)</li>
* </ul>
*/
static final Pattern clusterEndpointPattern = Pattern
.compile("\\[?([0-9a-zA-Z\\-_\\.:]*)\\]?:([0-9]+)(?:@[0-9]+(?:,([^,].*))?)?");
private static final Map<String, Flag> flagLookupMap;
static {
@@ -562,33 +574,29 @@ public abstract class Converters {
String[] args = source.split(" ");
int lastColonIndex = args[HOST_PORT_INDEX].lastIndexOf(":");
Matcher matcher = clusterEndpointPattern.matcher(args[HOST_PORT_INDEX]);
Assert.isTrue(lastColonIndex >= 0 && lastColonIndex < args[HOST_PORT_INDEX].length() - 1,
"ClusterNode information does not define host and port");
Assert.isTrue(matcher.matches(), "ClusterNode information does not define host and port");
String portPart = args[HOST_PORT_INDEX].substring(lastColonIndex + 1);
String hostPart = args[HOST_PORT_INDEX].substring(0, lastColonIndex);
String addressPart = matcher.group(1);
String portPart = matcher.group(2);
String hostnamePart = matcher.group(3);
SlotRange range = parseSlotRange(args);
Set<Flag> flags = parseFlags(args);
if (portPart.contains("@")) {
portPart = portPart.substring(0, portPart.indexOf('@'));
}
if (hostPart.startsWith("[") && hostPart.endsWith("]")) {
hostPart = hostPart.substring(1, hostPart.length() - 1);
}
RedisClusterNodeBuilder nodeBuilder = RedisClusterNode.newRedisClusterNode()
.listeningAt(hostPart, Integer.parseInt(portPart)) //
.listeningAt(addressPart, Integer.parseInt(portPart)) //
.withId(args[ID_INDEX]) //
.promotedAs(flags.contains(Flag.MASTER) ? NodeType.MASTER : NodeType.REPLICA) //
.serving(range) //
.withFlags(flags) //
.linkState(parseLinkState(args));
if (hostnamePart != null) {
nodeBuilder.withName(hostnamePart);
}
if (!args[MASTER_ID_INDEX].isEmpty() && !args[MASTER_ID_INDEX].startsWith("-")) {
nodeBuilder.replicaOf(args[MASTER_ID_INDEX]);
}