Skip to content

Commit b1ad59d

Browse files
PnPieDaveCTurner
authored andcommitted
Add coordinating_only node selector (#30313)
Today we can execute cluster API actions on only master, data or ingest nodes using the `master:true`, `data:true` and `ingest:true` filters, but it is not so easy to select coordinating-only nodes (i.e. those nodes that are neither master nor data nor ingest nodes). This change fixes this by adding support for a `coordinating_only` filter such that `coordinating_only:true` adds all coordinating-only nodes to the set of selected nodes, and `coordinating_only:false` deletes them. Resolves #28831.
1 parent f8c1235 commit b1ad59d

File tree

4 files changed

+43
-4
lines changed

4 files changed

+43
-4
lines changed

docs/CHANGELOG.asciidoc

+3
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ started or stopped. ({pull}30118[#30118])
333333

334334
Added put index template API to the high level rest client ({pull}30400[#30400])
335335

336+
Add ability to filter coordinating-only nodes when interacting with cluster
337+
APIs. ({pull}30313[#30313])
338+
336339
[float]
337340
=== Bug Fixes
338341

server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNode.java

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
*/
4545
public class DiscoveryNode implements Writeable, ToXContentFragment {
4646

47+
static final String COORDINATING_ONLY = "coordinating_only";
48+
4749
public static boolean nodeRequiresLocalStorage(Settings settings) {
4850
boolean localStorageEnable = Node.NODE_LOCAL_STORAGE_SETTING.get(settings);
4951
if (localStorageEnable == false &&

server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodes.java

+20-1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,19 @@ public ImmutableOpenMap<String, DiscoveryNode> getMasterAndDataNodes() {
147147
return nodes.build();
148148
}
149149

150+
/**
151+
* Get a {@link Map} of the coordinating only nodes (nodes which are neither master, nor data, nor ingest nodes) arranged by their ids
152+
*
153+
* @return {@link Map} of the coordinating only nodes arranged by their ids
154+
*/
155+
public ImmutableOpenMap<String, DiscoveryNode> getCoordinatingOnlyNodes() {
156+
ImmutableOpenMap.Builder<String, DiscoveryNode> nodes = ImmutableOpenMap.builder(this.nodes);
157+
nodes.removeAll(masterNodes.keys());
158+
nodes.removeAll(dataNodes.keys());
159+
nodes.removeAll(ingestNodes.keys());
160+
return nodes.build();
161+
}
162+
150163
/**
151164
* Get a node by its id
152165
*
@@ -294,7 +307,7 @@ public DiscoveryNode resolveNode(String node) {
294307
* - "_local" or "_master" for the relevant nodes
295308
* - a node id
296309
* - a wild card pattern that will be matched against node names
297-
* - a "attr:value" pattern, where attr can be a node role (master, data, ingest etc.) in which case the value can be true of false
310+
* - a "attr:value" pattern, where attr can be a node role (master, data, ingest etc.) in which case the value can be true or false,
298311
* or a generic node attribute name in which case value will be treated as a wildcard and matched against the node attribute values.
299312
*/
300313
public String[] resolveNodes(String... nodes) {
@@ -346,6 +359,12 @@ public String[] resolveNodes(String... nodes) {
346359
} else {
347360
resolvedNodesIds.removeAll(ingestNodes.keys());
348361
}
362+
} else if (DiscoveryNode.COORDINATING_ONLY.equals(matchAttrName)) {
363+
if (Booleans.parseBoolean(matchAttrValue, true)) {
364+
resolvedNodesIds.addAll(getCoordinatingOnlyNodes().keys());
365+
} else {
366+
resolvedNodesIds.removeAll(getCoordinatingOnlyNodes().keys());
367+
}
349368
} else {
350369
for (DiscoveryNode node : this) {
351370
for (Map.Entry<String, String> entry : node.getAttributes().entrySet()) {

server/src/test/java/org/elasticsearch/cluster/node/DiscoveryNodesTests.java

+18-3
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,17 @@ public void testCoordinatorOnlyNodes() {
101101
.map(DiscoveryNode::getId)
102102
.toArray(String[]::new);
103103

104-
assertThat(
105-
discoveryNodes.resolveNodes("_all", "data:false", "ingest:false", "master:false"),
106-
arrayContainingInAnyOrder(coordinatorOnlyNodes));
104+
final String[] nonCoordinatorOnlyNodes =
105+
StreamSupport.stream(discoveryNodes.getNodes().values().spliterator(), false)
106+
.map(n -> n.value)
107+
.filter(n -> n.isMasterNode() || n.isDataNode() || n.isIngestNode())
108+
.map(DiscoveryNode::getId)
109+
.toArray(String[]::new);
110+
111+
assertThat(discoveryNodes.resolveNodes("coordinating_only:true"), arrayContainingInAnyOrder(coordinatorOnlyNodes));
112+
assertThat(discoveryNodes.resolveNodes("_all", "data:false", "ingest:false", "master:false"),
113+
arrayContainingInAnyOrder(coordinatorOnlyNodes));
114+
assertThat(discoveryNodes.resolveNodes("_all", "coordinating_only:false"), arrayContainingInAnyOrder(nonCoordinatorOnlyNodes));
107115
}
108116

109117
public void testResolveNodesIds() {
@@ -266,6 +274,13 @@ Set<String> matchingNodeIds(DiscoveryNodes nodes) {
266274
nodes.getIngestNodes().keysIt().forEachRemaining(ids::add);
267275
return ids;
268276
}
277+
}, COORDINATING_ONLY(DiscoveryNode.COORDINATING_ONLY + ":true") {
278+
@Override
279+
Set<String> matchingNodeIds(DiscoveryNodes nodes) {
280+
Set<String> ids = new HashSet<>();
281+
nodes.getCoordinatingOnlyNodes().keysIt().forEachRemaining(ids::add);
282+
return ids;
283+
}
269284
}, CUSTOM_ATTRIBUTE("attr:value") {
270285
@Override
271286
Set<String> matchingNodeIds(DiscoveryNodes nodes) {

0 commit comments

Comments
 (0)