From c81647725096e996ef4567a58391989e47752651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?seung=20won=20=F0=9F=8F=86?= Date: Fri, 18 Apr 2025 10:18:04 +0900 Subject: [PATCH 1/2] Use InfoPatterns enum for ReplicaTopologyProvider pattern management - Replaced individual static Pattern constants with InfoPatterns enum to group related patterns. - Updated getNested method to accept InfoPatterns for improved type safety and readability. - Added Javadoc for InfoPatterns enum and related methods to clarify usage. - Improved error messages in getCurrentNodeDescription and getNested for better debugging. - No functional changes; maintains backward compatibility. --- .../ReplicaTopologyProvider.java | 56 +++++++++++++------ 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/main/java/io/lettuce/core/masterreplica/ReplicaTopologyProvider.java b/src/main/java/io/lettuce/core/masterreplica/ReplicaTopologyProvider.java index 8c2f3ca71a..ba9ef1a02d 100644 --- a/src/main/java/io/lettuce/core/masterreplica/ReplicaTopologyProvider.java +++ b/src/main/java/io/lettuce/core/masterreplica/ReplicaTopologyProvider.java @@ -38,26 +38,47 @@ /** * Topology provider using Redis Standalone and the {@code INFO REPLICATION} output. Replicas are listed as {@code slaveN=...} - * entries. + * entries. This provider parses the {@code INFO REPLICATION} output to discover master and replica nodes, using regular + * expression patterns defined in the {@link InfoPatterns} enum. * * @author Mark Paluch * @since 4.1 */ class ReplicaTopologyProvider implements TopologyProvider { - public static final Pattern ROLE_PATTERN = Pattern.compile("^role\\:([a-z]+)$", Pattern.MULTILINE); + /** + * Enum containing regular expression patterns for parsing Redis {@code INFO REPLICATION} output. Each constant provides a + * compiled {@link Pattern} and a {@link Matcher} for convenient pattern matching. + */ + enum InfoPatterns { + + ROLE(Pattern.compile("^role\\:([a-z]+)$", Pattern.MULTILINE)), - public static final Pattern SLAVE_PATTERN = Pattern.compile("^slave(\\d+)\\:([a-zA-Z\\,\\=\\d\\.\\:\\-]+)$", - Pattern.MULTILINE); + SLAVE(Pattern.compile("^slave(\\d+)\\:([a-zA-Z\\,\\=\\d\\.\\:\\-]+)$", Pattern.MULTILINE)), - public static final Pattern MASTER_HOST_PATTERN = Pattern.compile("^master_host\\:([a-zA-Z\\,\\=\\d\\.\\:\\-]+)$", - Pattern.MULTILINE); + MASTER_HOST(Pattern.compile("^master_host\\:([a-zA-Z\\,\\=\\d\\.\\:\\-]+)$", Pattern.MULTILINE)), - public static final Pattern MASTER_PORT_PATTERN = Pattern.compile("^master_port\\:(\\d+)$", Pattern.MULTILINE); + MASTER_PORT(Pattern.compile("^master_port\\:(\\d+)$", Pattern.MULTILINE)), - public static final Pattern IP_PATTERN = Pattern.compile("ip\\=([a-zA-Z\\d\\.\\:\\-]+)"); + IP(Pattern.compile("ip\\=([a-zA-Z\\d\\.\\:\\-]+)")), - public static final Pattern PORT_PATTERN = Pattern.compile("port\\=([\\d]+)"); + PORT(Pattern.compile("port\\=([\\d]+)")); + + private final Pattern pattern; + + InfoPatterns(Pattern pattern) { + this.pattern = pattern; + } + + public Pattern getPattern() { + return pattern; + } + + public Matcher matcher(String input) { + return pattern.matcher(input); + } + + } private static final InternalLogger logger = InternalLoggerFactory.getInstance(ReplicaTopologyProvider.class); @@ -126,7 +147,7 @@ protected List getNodesFromInfo(String info) { private RedisNodeDescription getCurrentNodeDescription(String info) { - Matcher matcher = ROLE_PATTERN.matcher(info); + Matcher matcher = InfoPatterns.ROLE.matcher(info); if (!matcher.find()) { throw new IllegalStateException("No role property in info " + info); @@ -139,12 +160,12 @@ private List getReplicasFromInfo(String info) { List replicas = new ArrayList<>(); - Matcher matcher = SLAVE_PATTERN.matcher(info); + Matcher matcher = InfoPatterns.SLAVE.matcher(info); while (matcher.find()) { String group = matcher.group(2); - String ip = getNested(IP_PATTERN, group, 1); - String port = getNested(PORT_PATTERN, group, 1); + String ip = getNested(InfoPatterns.IP, group, 1); + String port = getNested(InfoPatterns.PORT, group, 1); replicas.add(new RedisMasterReplicaNode(ip, Integer.parseInt(port), redisURI, RedisInstance.Role.SLAVE)); } @@ -154,8 +175,8 @@ private List getReplicasFromInfo(String info) { private RedisNodeDescription getMasterFromInfo(String info) { - Matcher masterHostMatcher = MASTER_HOST_PATTERN.matcher(info); - Matcher masterPortMatcher = MASTER_PORT_PATTERN.matcher(info); + Matcher masterHostMatcher = InfoPatterns.MASTER_HOST.matcher(info); + Matcher masterPortMatcher = InfoPatterns.MASTER_PORT.matcher(info); boolean foundHost = masterHostMatcher.find(); boolean foundPort = masterPortMatcher.find(); @@ -170,14 +191,15 @@ private RedisNodeDescription getMasterFromInfo(String info) { return new RedisMasterReplicaNode(host, port, redisURI, RedisInstance.Role.UPSTREAM); } - private String getNested(Pattern pattern, String string, int group) { + private String getNested(InfoPatterns pattern, String string, int group) { Matcher matcher = pattern.matcher(string); if (matcher.find()) { return matcher.group(group); } - throw new IllegalArgumentException("Cannot extract group " + group + " with pattern " + pattern + " from " + string); + throw new IllegalArgumentException( + "Cannot extract group " + group + " with pattern " + pattern.getPattern() + " from " + string); } From 78b134960c7975c5092a89adddc304bb94e53960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?seung=20won=20=F0=9F=8F=86?= Date: Fri, 18 Apr 2025 10:26:45 +0900 Subject: [PATCH 2/2] Apply code formatting to ReplicaTopologyProvider.java --- .../io/lettuce/core/masterreplica/ReplicaTopologyProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/lettuce/core/masterreplica/ReplicaTopologyProvider.java b/src/main/java/io/lettuce/core/masterreplica/ReplicaTopologyProvider.java index ba9ef1a02d..c93ce8a138 100644 --- a/src/main/java/io/lettuce/core/masterreplica/ReplicaTopologyProvider.java +++ b/src/main/java/io/lettuce/core/masterreplica/ReplicaTopologyProvider.java @@ -69,7 +69,7 @@ enum InfoPatterns { InfoPatterns(Pattern pattern) { this.pattern = pattern; } - + public Pattern getPattern() { return pattern; }