38
38
39
39
/**
40
40
* Topology provider using Redis Standalone and the {@code INFO REPLICATION} output. Replicas are listed as {@code slaveN=...}
41
- * entries.
41
+ * entries. This provider parses the {@code INFO REPLICATION} output to discover master and replica nodes, using regular
42
+ * expression patterns defined in the {@link InfoPatterns} enum.
42
43
*
43
44
* @author Mark Paluch
44
45
* @since 4.1
45
46
*/
46
47
class ReplicaTopologyProvider implements TopologyProvider {
47
48
48
- public static final Pattern ROLE_PATTERN = Pattern .compile ("^role\\ :([a-z]+)$" , Pattern .MULTILINE );
49
+ /**
50
+ * Enum containing regular expression patterns for parsing Redis {@code INFO REPLICATION} output. Each constant provides a
51
+ * compiled {@link Pattern} and a {@link Matcher} for convenient pattern matching.
52
+ */
53
+ enum InfoPatterns {
54
+
55
+ ROLE (Pattern .compile ("^role\\ :([a-z]+)$" , Pattern .MULTILINE )),
56
+
57
+ SLAVE (Pattern .compile ("^slave(\\ d+)\\ :([a-zA-Z\\ ,\\ =\\ d\\ .\\ :\\ -]+)$" , Pattern .MULTILINE )),
58
+
59
+ MASTER_HOST (Pattern .compile ("^master_host\\ :([a-zA-Z\\ ,\\ =\\ d\\ .\\ :\\ -]+)$" , Pattern .MULTILINE )),
60
+
61
+ MASTER_PORT (Pattern .compile ("^master_port\\ :(\\ d+)$" , Pattern .MULTILINE )),
49
62
50
- public static final Pattern SLAVE_PATTERN = Pattern .compile ("^slave(\\ d+)\\ :([a-zA-Z\\ ,\\ =\\ d\\ .\\ :\\ -]+)$" ,
51
- Pattern .MULTILINE );
63
+ IP (Pattern .compile ("ip\\ =([a-zA-Z\\ d\\ .\\ :\\ -]+)" )),
52
64
53
- public static final Pattern MASTER_HOST_PATTERN = Pattern .compile ("^master_host\\ :([a-zA-Z\\ ,\\ =\\ d\\ .\\ :\\ -]+)$" ,
54
- Pattern .MULTILINE );
65
+ PORT (Pattern .compile ("port\\ =([\\ d]+)" ));
55
66
56
- public static final Pattern MASTER_PORT_PATTERN = Pattern . compile ( "^master_port \\ :( \\ d+)$" , Pattern . MULTILINE ) ;
67
+ private final Pattern pattern ;
57
68
58
- public static final Pattern IP_PATTERN = Pattern .compile ("ip\\ =([a-zA-Z\\ d\\ .\\ :\\ -]+)" );
69
+ InfoPatterns (Pattern pattern ) {
70
+ this .pattern = pattern ;
71
+ }
72
+
73
+ public Pattern getPattern () {
74
+ return pattern ;
75
+ }
59
76
60
- public static final Pattern PORT_PATTERN = Pattern .compile ("port\\ =([\\ d]+)" );
77
+ public Matcher matcher (String input ) {
78
+ return pattern .matcher (input );
79
+ }
80
+
81
+ }
61
82
62
83
private static final InternalLogger logger = InternalLoggerFactory .getInstance (ReplicaTopologyProvider .class );
63
84
@@ -126,7 +147,7 @@ protected List<RedisNodeDescription> getNodesFromInfo(String info) {
126
147
127
148
private RedisNodeDescription getCurrentNodeDescription (String info ) {
128
149
129
- Matcher matcher = ROLE_PATTERN .matcher (info );
150
+ Matcher matcher = InfoPatterns . ROLE .matcher (info );
130
151
131
152
if (!matcher .find ()) {
132
153
throw new IllegalStateException ("No role property in info " + info );
@@ -139,12 +160,12 @@ private List<RedisNodeDescription> getReplicasFromInfo(String info) {
139
160
140
161
List <RedisNodeDescription > replicas = new ArrayList <>();
141
162
142
- Matcher matcher = SLAVE_PATTERN .matcher (info );
163
+ Matcher matcher = InfoPatterns . SLAVE .matcher (info );
143
164
while (matcher .find ()) {
144
165
145
166
String group = matcher .group (2 );
146
- String ip = getNested (IP_PATTERN , group , 1 );
147
- String port = getNested (PORT_PATTERN , group , 1 );
167
+ String ip = getNested (InfoPatterns . IP , group , 1 );
168
+ String port = getNested (InfoPatterns . PORT , group , 1 );
148
169
149
170
replicas .add (new RedisMasterReplicaNode (ip , Integer .parseInt (port ), redisURI , RedisInstance .Role .SLAVE ));
150
171
}
@@ -154,8 +175,8 @@ private List<RedisNodeDescription> getReplicasFromInfo(String info) {
154
175
155
176
private RedisNodeDescription getMasterFromInfo (String info ) {
156
177
157
- Matcher masterHostMatcher = MASTER_HOST_PATTERN .matcher (info );
158
- Matcher masterPortMatcher = MASTER_PORT_PATTERN .matcher (info );
178
+ Matcher masterHostMatcher = InfoPatterns . MASTER_HOST .matcher (info );
179
+ Matcher masterPortMatcher = InfoPatterns . MASTER_PORT .matcher (info );
159
180
160
181
boolean foundHost = masterHostMatcher .find ();
161
182
boolean foundPort = masterPortMatcher .find ();
@@ -170,14 +191,15 @@ private RedisNodeDescription getMasterFromInfo(String info) {
170
191
return new RedisMasterReplicaNode (host , port , redisURI , RedisInstance .Role .UPSTREAM );
171
192
}
172
193
173
- private String getNested (Pattern pattern , String string , int group ) {
194
+ private String getNested (InfoPatterns pattern , String string , int group ) {
174
195
175
196
Matcher matcher = pattern .matcher (string );
176
197
if (matcher .find ()) {
177
198
return matcher .group (group );
178
199
}
179
200
180
- throw new IllegalArgumentException ("Cannot extract group " + group + " with pattern " + pattern + " from " + string );
201
+ throw new IllegalArgumentException (
202
+ "Cannot extract group " + group + " with pattern " + pattern .getPattern () + " from " + string );
181
203
182
204
}
183
205
0 commit comments