Skip to content

Commit c449097

Browse files
Fix the support of RestClient Node Sniffer for version 2.x and update tests (#3487) (#3521)
Fix the support of RestClient Node Sniffer for OpenSearch 2.x, and update unit tests for OpenSearch. The current code contains the logic to be compatible with Elasticsearch 2.x version, which is conflict with OpenSearch 2.x, so removed that part of legacy code. * Update the script create_test_nodes_info.bash to dump the response of Nodes Info API GET _nodes/http for OpenSearch 1.0 and 2.0 version, which used for unit test. * Remove the support of Elasticsearch version 2.x for the Sniffer * Update unit test to validate the Sniffer compatible with OpenSearch 1.x and 2.x * Update the API response parser to meet the array notation (in ES 6.1 and above) for the node attributes setting. It will result the value of `node.attr` setting will not be parsed as array in the Sniffer, when using the Sniffer on cluster in Elasticsearch 6.0 and above. * Replace "master" node role with "cluster_manager" in unit test Signed-off-by: Tianli Feng <[email protected]> (cherry picked from commit ab478ba)
1 parent a93ff13 commit c449097

File tree

8 files changed

+191
-700
lines changed

8 files changed

+191
-700
lines changed

client/sniffer/src/main/java/org/opensearch/client/sniff/OpenSearchNodesSniffer.java

Lines changed: 10 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import java.io.InputStream;
5050
import java.net.URI;
5151
import java.util.ArrayList;
52+
import java.util.Arrays;
5253
import java.util.HashMap;
5354
import java.util.HashSet;
5455
import java.util.List;
@@ -241,74 +242,23 @@ private static Node readNode(String nodeId, JsonParser parser, Scheme scheme) th
241242
}
242243

243244
Map<String, List<String>> realAttributes = new HashMap<>(protoAttributes.size());
244-
List<String> keys = new ArrayList<>(protoAttributes.keySet());
245-
for (String key : keys) {
246-
if (key.endsWith(".0")) {
247-
String realKey = key.substring(0, key.length() - 2);
248-
List<String> values = new ArrayList<>();
249-
int i = 0;
250-
while (true) {
251-
String value = protoAttributes.remove(realKey + "." + i);
252-
if (value == null) {
253-
break;
254-
}
255-
values.add(value);
256-
i++;
257-
}
258-
realAttributes.put(realKey, unmodifiableList(values));
259-
}
260-
}
261245
for (Map.Entry<String, String> entry : protoAttributes.entrySet()) {
262-
realAttributes.put(entry.getKey(), singletonList(entry.getValue()));
263-
}
264-
265-
if (version.startsWith("2.")) {
266-
/*
267-
* 2.x doesn't send roles, instead we try to read them from
268-
* attributes.
269-
*/
270-
boolean clientAttribute = v2RoleAttributeValue(realAttributes, "client", false);
271-
Boolean masterAttribute = v2RoleAttributeValue(realAttributes, "master", null);
272-
Boolean dataAttribute = v2RoleAttributeValue(realAttributes, "data", null);
273-
if ((masterAttribute == null && false == clientAttribute) || masterAttribute) {
274-
roles.add("master");
246+
if (entry.getValue().startsWith("[")) {
247+
// Convert string array to list
248+
String value = entry.getValue();
249+
String[] values = value.substring(1, value.length() - 1).split(", ");
250+
realAttributes.put(entry.getKey(), unmodifiableList(Arrays.asList(values)));
251+
} else {
252+
realAttributes.put(entry.getKey(), singletonList(entry.getValue()));
275253
}
276-
if ((dataAttribute == null && false == clientAttribute) || dataAttribute) {
277-
roles.add("data");
278-
}
279-
} else {
280-
assert sawRoles : "didn't see roles for [" + nodeId + "]";
281254
}
255+
256+
assert sawRoles : "didn't see roles for [" + nodeId + "]";
282257
assert boundHosts.contains(publishedHost) : "[" + nodeId + "] doesn't make sense! publishedHost should be in boundHosts";
283258
logger.trace("adding node [" + nodeId + "]");
284259
return new Node(publishedHost, boundHosts, name, version, new Roles(roles), unmodifiableMap(realAttributes));
285260
}
286261

287-
/**
288-
* Returns {@code defaultValue} if the attribute didn't come back,
289-
* {@code true} or {@code false} if it did come back as
290-
* either of those, or throws an IOException if the attribute
291-
* came back in a strange way.
292-
*/
293-
private static Boolean v2RoleAttributeValue(Map<String, List<String>> attributes, String name, Boolean defaultValue)
294-
throws IOException {
295-
List<String> valueList = attributes.remove(name);
296-
if (valueList == null) {
297-
return defaultValue;
298-
}
299-
if (valueList.size() != 1) {
300-
throw new IOException("expected only a single attribute value for [" + name + "] but got " + valueList);
301-
}
302-
switch (valueList.get(0)) {
303-
case "true":
304-
return true;
305-
case "false":
306-
return false;
307-
default:
308-
throw new IOException("expected [" + name + "] to be either [true] or [false] but was [" + valueList.get(0) + "]");
309-
}
310-
}
311-
312262
/**
313263
* The supported host schemes.
314264
*/

client/sniffer/src/test/java/org/opensearch/client/sniff/OpenSearchNodesSnifferParseTests.java

Lines changed: 27 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545
import java.io.IOException;
4646
import java.io.InputStream;
4747
import java.util.Arrays;
48-
import java.util.HashMap;
4948
import java.util.HashSet;
49+
import java.util.LinkedHashMap;
5050
import java.util.List;
5151
import java.util.Map;
5252
import java.util.Set;
@@ -85,59 +85,31 @@ private void checkFile(String file, Node... expected) throws IOException {
8585
}
8686
}
8787

88-
public void test2x() throws IOException {
89-
checkFile(
90-
"2.0.0_nodes_http.json",
91-
node(9200, "m1", "2.0.0", true, false, false),
92-
node(9201, "m2", "2.0.0", true, true, false),
93-
node(9202, "m3", "2.0.0", true, false, false),
94-
node(9203, "d1", "2.0.0", false, true, false),
95-
node(9204, "d2", "2.0.0", false, true, false),
96-
node(9205, "d3", "2.0.0", false, true, false),
97-
node(9206, "c1", "2.0.0", false, false, false),
98-
node(9207, "c2", "2.0.0", false, false, false)
99-
);
100-
}
101-
102-
public void test5x() throws IOException {
103-
checkFile(
104-
"5.0.0_nodes_http.json",
105-
node(9200, "m1", "5.0.0", true, false, true),
106-
node(9201, "m2", "5.0.0", true, true, true),
107-
node(9202, "m3", "5.0.0", true, false, true),
108-
node(9203, "d1", "5.0.0", false, true, true),
109-
node(9204, "d2", "5.0.0", false, true, true),
110-
node(9205, "d3", "5.0.0", false, true, true),
111-
node(9206, "c1", "5.0.0", false, false, true),
112-
node(9207, "c2", "5.0.0", false, false, true)
113-
);
114-
}
115-
116-
public void test6x() throws IOException {
88+
public void test1x() throws IOException {
11789
checkFile(
118-
"6.0.0_nodes_http.json",
119-
node(9200, "m1", "6.0.0", true, false, true),
120-
node(9201, "m2", "6.0.0", true, true, true),
121-
node(9202, "m3", "6.0.0", true, false, true),
122-
node(9203, "d1", "6.0.0", false, true, true),
123-
node(9204, "d2", "6.0.0", false, true, true),
124-
node(9205, "d3", "6.0.0", false, true, true),
125-
node(9206, "c1", "6.0.0", false, false, true),
126-
node(9207, "c2", "6.0.0", false, false, true)
90+
"1.0.0_nodes_http.json",
91+
node(9200, "m1", "1.0.0", "master", "ingest"),
92+
node(9201, "m2", "1.0.0", "master", "data", "ingest"),
93+
node(9202, "m3", "1.0.0", "master", "ingest"),
94+
node(9203, "d1", "1.0.0", "data", "ingest"),
95+
node(9204, "d2", "1.0.0", "data", "ingest"),
96+
node(9205, "d3", "1.0.0", "data", "ingest"),
97+
node(9206, "c1", "1.0.0", "ingest"),
98+
node(9207, "c2", "1.0.0", "ingest")
12799
);
128100
}
129101

130-
public void test7x() throws IOException {
102+
public void test2x() throws IOException {
131103
checkFile(
132-
"7.3.0_nodes_http.json",
133-
node(9200, "m1", "7.3.0", "master", "ingest"),
134-
node(9201, "m2", "7.3.0", "master", "data", "ingest"),
135-
node(9202, "m3", "7.3.0", "master", "ingest"),
136-
node(9203, "d1", "7.3.0", "data", "ingest", "ml"),
137-
node(9204, "d2", "7.3.0", "data", "ingest"),
138-
node(9205, "d3", "7.3.0", "data", "ingest"),
139-
node(9206, "c1", "7.3.0", "ingest"),
140-
node(9207, "c2", "7.3.0", "ingest")
104+
"2.0.0_nodes_http.json",
105+
node(9200, "m1", "2.0.0", "cluster_manager", "ingest"),
106+
node(9201, "m2", "2.0.0", "cluster_manager", "data", "ingest"),
107+
node(9202, "m3", "2.0.0", "cluster_manager", "ingest"),
108+
node(9203, "d1", "2.0.0", "data", "ingest"),
109+
node(9204, "d2", "2.0.0", "data", "ingest"),
110+
node(9205, "d3", "2.0.0", "data", "ingest"),
111+
node(9206, "c1", "2.0.0", "ingest"),
112+
node(9207, "c2", "2.0.0", "ingest")
141113
);
142114
}
143115

@@ -163,32 +135,22 @@ public void testParsingPublishAddressWithES7Format() throws IOException {
163135
assertEquals("http", nodes.get(0).getHost().getSchemeName());
164136
}
165137

166-
private Node node(int port, String name, String version, boolean master, boolean data, boolean ingest) {
167-
final Set<String> roles = new TreeSet<>();
168-
if (master) {
169-
roles.add("master");
170-
}
171-
if (data) {
172-
roles.add("data");
173-
}
174-
if (ingest) {
175-
roles.add("ingest");
176-
}
177-
return node(port, name, version, roles);
178-
}
179-
180138
private Node node(int port, String name, String version, String... roles) {
181139
return node(port, name, version, new TreeSet<>(Arrays.asList(roles)));
182140
}
183141

184142
private Node node(int port, String name, String version, Set<String> roles) {
185143
HttpHost host = new HttpHost("127.0.0.1", port);
186144
Set<HttpHost> boundHosts = new HashSet<>(2);
187-
boundHosts.add(host);
188145
boundHosts.add(new HttpHost("[::1]", port));
189-
Map<String, List<String>> attributes = new HashMap<>();
146+
boundHosts.add(host);
147+
Map<String, List<String>> attributes = new LinkedHashMap<>(); // LinkedHashMap to preserve insertion order
190148
attributes.put("dummy", singletonList("everyone_has_me"));
191149
attributes.put("number", singletonList(name.substring(1)));
150+
if (!version.startsWith("1.0") && !version.startsWith("1.1")) {
151+
// Shard Indexing Pressure feature is added in version 1.2.0
152+
attributes.put("shard_indexing_pressure_enabled", singletonList(Boolean.TRUE.toString()));
153+
}
192154
attributes.put("array", Arrays.asList(name.substring(0, 1), name.substring(1)));
193155
return new Node(host, boundHosts, name, version, new Roles(new TreeSet<>(roles)), attributes);
194156
}

client/sniffer/src/test/java/org/opensearch/client/sniff/OpenSearchNodesSnifferTests.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ private static SniffResponse buildSniffResponse(OpenSearchNodesSniffer.Scheme sc
234234

235235
final Set<String> nodeRoles = new TreeSet<>();
236236
if (randomBoolean()) {
237-
nodeRoles.add("master");
237+
nodeRoles.add("cluster_manager");
238238
}
239239
if (randomBoolean()) {
240240
nodeRoles.add("data");
@@ -283,12 +283,12 @@ private static SniffResponse buildSniffResponse(OpenSearchNodesSniffer.Scheme sc
283283
generator.writeEndObject();
284284
}
285285

286-
List<String> roles = Arrays.asList(new String[] { "master", "data", "ingest" });
286+
List<String> roles = Arrays.asList(new String[] { "cluster_manager", "data", "ingest" });
287287
Collections.shuffle(roles, getRandom());
288288
generator.writeArrayFieldStart("roles");
289289
for (String role : roles) {
290-
if ("master".equals(role) && node.getRoles().isMasterEligible()) {
291-
generator.writeString("master");
290+
if ("cluster_manager".equals(role) && node.getRoles().isMasterEligible()) {
291+
generator.writeString("cluster_manager");
292292
}
293293
if ("data".equals(role) && node.getRoles().isData()) {
294294
generator.writeString("data");
@@ -307,13 +307,7 @@ private static SniffResponse buildSniffResponse(OpenSearchNodesSniffer.Scheme sc
307307
if (numAttributes > 0) {
308308
generator.writeObjectFieldStart("attributes");
309309
for (Map.Entry<String, List<String>> entry : attributes.entrySet()) {
310-
if (entry.getValue().size() == 1) {
311-
generator.writeStringField(entry.getKey(), entry.getValue().get(0));
312-
} else {
313-
for (int v = 0; v < entry.getValue().size(); v++) {
314-
generator.writeStringField(entry.getKey() + "." + v, entry.getValue().get(v));
315-
}
316-
}
310+
generator.writeStringField(entry.getKey(), entry.getValue().toString());
317311
}
318312
generator.writeEndObject();
319313
}

0 commit comments

Comments
 (0)