Skip to content

Commit ac35b51

Browse files
committed
Run TransportGetSettingsAction on local node
This action solely needs the cluster state, it can run on any node. Additionally, it needs to be cancellable to avoid doing unnecessary work after a client failure or timeout. Relates #101805
1 parent a97e006 commit ac35b51

File tree

13 files changed

+85
-173
lines changed

13 files changed

+85
-173
lines changed

qa/smoke-test-http/src/internalClusterTest/java/org/elasticsearch/http/RestActionCancellationIT.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesAction;
1818
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsAction;
1919
import org.elasticsearch.action.admin.indices.recovery.RecoveryAction;
20+
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsAction;
2021
import org.elasticsearch.action.admin.indices.template.get.GetComponentTemplateAction;
2122
import org.elasticsearch.action.admin.indices.template.get.GetComposableIndexTemplateAction;
2223
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesAction;
@@ -114,6 +115,11 @@ public void testGetMappingsCancellation() {
114115
runRestActionCancellationTest(new Request(HttpGet.METHOD_NAME, "/test/_mappings"), GetMappingsAction.NAME);
115116
}
116117

118+
public void testGetIndexSettingsCancellation() {
119+
createIndex("test");
120+
runRestActionCancellationTest(new Request(HttpGet.METHOD_NAME, "/test/_settings"), GetSettingsAction.NAME);
121+
}
122+
117123
private void runRestActionCancellationTest(Request request, String actionName) {
118124
final var node = usually() ? internalCluster().getRandomNodeName() : internalCluster().startCoordinatingOnlyNode(Settings.EMPTY);
119125

rest-api-spec/src/main/resources/rest-api-spec/api/indices.get_settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
"description":"Return settings in flat format (default: false)"
9090
},
9191
"local":{
92+
"deprecated":true,
9293
"type":"boolean",
9394
"description":"Return local information, do not retrieve the state from master node (default: false)"
9495
},

rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.get_settings/10_basic.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,14 @@ setup:
164164

165165
---
166166
"Get /_settings with local flag":
167+
- requires:
168+
test_runner_features: ["allowed_warnings"]
167169

168170
- do:
169171
indices.get_settings:
170172
local: true
173+
allowed_warnings:
174+
- "the [?local] query parameter to this API has no effect, is now deprecated, and will be removed in a future version"
171175

172176
- is_true: test_1
173177
- is_true: test_2

server/src/internalClusterTest/java/org/elasticsearch/action/IndicesRequestIT.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@
3434
import org.elasticsearch.action.admin.indices.refresh.TransportShardRefreshAction;
3535
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentsAction;
3636
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentsRequest;
37-
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsAction;
38-
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
3937
import org.elasticsearch.action.admin.indices.settings.put.TransportUpdateSettingsAction;
4038
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
4139
import org.elasticsearch.action.admin.indices.stats.IndicesStatsAction;
@@ -524,16 +522,6 @@ public void testPutMapping() {
524522
assertSameIndices(putMappingRequest, TransportPutMappingAction.TYPE.name());
525523
}
526524

527-
public void testGetSettings() {
528-
interceptTransportActions(GetSettingsAction.NAME);
529-
530-
GetSettingsRequest getSettingsRequest = new GetSettingsRequest(TEST_REQUEST_TIMEOUT).indices(randomIndicesOrAliases());
531-
internalCluster().coordOnlyNodeClient().admin().indices().getSettings(getSettingsRequest).actionGet();
532-
533-
clearInterceptedActions();
534-
assertSameIndices(getSettingsRequest, GetSettingsAction.NAME);
535-
}
536-
537525
public void testUpdateSettings() {
538526
interceptTransportActions(TransportUpdateSettingsAction.TYPE.name());
539527

server/src/main/java/org/elasticsearch/action/admin/indices/settings/get/GetSettingsRequest.java

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,21 @@
1313
import org.elasticsearch.action.IndicesRequest;
1414
import org.elasticsearch.action.ValidateActions;
1515
import org.elasticsearch.action.support.IndicesOptions;
16-
import org.elasticsearch.action.support.master.MasterNodeReadRequest;
16+
import org.elasticsearch.action.support.local.LocalClusterStateRequest;
1717
import org.elasticsearch.common.Strings;
1818
import org.elasticsearch.common.io.stream.StreamInput;
19-
import org.elasticsearch.common.io.stream.StreamOutput;
2019
import org.elasticsearch.core.TimeValue;
20+
import org.elasticsearch.core.UpdateForV10;
21+
import org.elasticsearch.tasks.CancellableTask;
22+
import org.elasticsearch.tasks.Task;
23+
import org.elasticsearch.tasks.TaskId;
2124

2225
import java.io.IOException;
2326
import java.util.Arrays;
27+
import java.util.Map;
2428
import java.util.Objects;
2529

26-
public class GetSettingsRequest extends MasterNodeReadRequest<GetSettingsRequest> implements IndicesRequest.Replaceable {
30+
public class GetSettingsRequest extends LocalClusterStateRequest implements IndicesRequest.Replaceable {
2731

2832
public static final IndicesOptions DEFAULT_INDICES_OPTIONS = IndicesOptions.fromOptions(false, true, true, true);
2933

@@ -57,6 +61,11 @@ public GetSettingsRequest(TimeValue masterTimeout) {
5761
super(masterTimeout);
5862
}
5963

64+
/**
65+
* NB prior to 9.1 this was a TransportMasterNodeReadAction so for BwC we must remain able to read these requests until
66+
* we no longer need to support calling this action remotely.
67+
*/
68+
@UpdateForV10(owner = UpdateForV10.Owner.DATA_MANAGEMENT)
6069
public GetSettingsRequest(StreamInput in) throws IOException {
6170
super(in);
6271
indices = in.readStringArray();
@@ -66,16 +75,6 @@ public GetSettingsRequest(StreamInput in) throws IOException {
6675
includeDefaults = in.readBoolean();
6776
}
6877

69-
@Override
70-
public void writeTo(StreamOutput out) throws IOException {
71-
super.writeTo(out);
72-
out.writeStringArray(indices);
73-
indicesOptions.writeIndicesOptions(out);
74-
out.writeStringArray(names);
75-
out.writeBoolean(humanReadable);
76-
out.writeBoolean(includeDefaults);
77-
}
78-
7978
@Override
8079
public String[] indices() {
8180
return indices;
@@ -122,6 +121,11 @@ public ActionRequestValidationException validate() {
122121
return validationException;
123122
}
124123

124+
@Override
125+
public Task createTask(long id, String type, String action, TaskId parentTaskId, Map<String, String> headers) {
126+
return new CancellableTask(id, type, action, "", parentTaskId, headers);
127+
}
128+
125129
@Override
126130
public boolean equals(Object o) {
127131
if (this == o) return true;

server/src/main/java/org/elasticsearch/action/admin/indices/settings/get/GetSettingsRequestBuilder.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,13 @@
99

1010
package org.elasticsearch.action.admin.indices.settings.get;
1111

12+
import org.elasticsearch.action.ActionRequestBuilder;
1213
import org.elasticsearch.action.support.IndicesOptions;
13-
import org.elasticsearch.action.support.master.MasterNodeReadOperationRequestBuilder;
1414
import org.elasticsearch.client.internal.ElasticsearchClient;
1515
import org.elasticsearch.common.util.ArrayUtils;
1616
import org.elasticsearch.core.TimeValue;
1717

18-
public class GetSettingsRequestBuilder extends MasterNodeReadOperationRequestBuilder<
19-
GetSettingsRequest,
20-
GetSettingsResponse,
21-
GetSettingsRequestBuilder> {
18+
public class GetSettingsRequestBuilder extends ActionRequestBuilder<GetSettingsRequest, GetSettingsResponse> {
2219

2320
public GetSettingsRequestBuilder(ElasticsearchClient client, TimeValue masterTimeout, String... indices) {
2421
super(client, GetSettingsAction.INSTANCE, new GetSettingsRequest(masterTimeout).indices(indices));

server/src/main/java/org/elasticsearch/action/admin/indices/settings/get/GetSettingsResponse.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
import org.elasticsearch.action.ActionResponse;
1313
import org.elasticsearch.common.Strings;
1414
import org.elasticsearch.common.collect.Iterators;
15-
import org.elasticsearch.common.io.stream.StreamInput;
1615
import org.elasticsearch.common.io.stream.StreamOutput;
1716
import org.elasticsearch.common.settings.Settings;
1817
import org.elasticsearch.common.xcontent.ChunkedToXContentObject;
18+
import org.elasticsearch.core.UpdateForV10;
1919
import org.elasticsearch.xcontent.ToXContent;
2020
import org.elasticsearch.xcontent.XContentBuilder;
2121
import org.elasticsearch.xcontent.json.JsonXContent;
@@ -36,11 +36,6 @@ public GetSettingsResponse(Map<String, Settings> indexToSettings, Map<String, Se
3636
this.indexToDefaultSettings = indexToDefaultSettings;
3737
}
3838

39-
public GetSettingsResponse(StreamInput in) throws IOException {
40-
indexToSettings = in.readImmutableMap(Settings::readSettingsFromStream);
41-
indexToDefaultSettings = in.readImmutableMap(Settings::readSettingsFromStream);
42-
}
43-
4439
/**
4540
* Returns a map of index name to {@link Settings} object. The returned {@link Settings}
4641
* objects contain only those settings explicitly set on a given index.
@@ -82,6 +77,11 @@ public String getSetting(String index, String setting) {
8277
}
8378
}
8479

80+
/**
81+
* NB prior to 9.1 this was a TransportMasterNodeReadAction so for BwC we must remain able to write these responses until
82+
* we no longer need to support calling this action remotely.
83+
*/
84+
@UpdateForV10(owner = UpdateForV10.Owner.DATA_MANAGEMENT)
8585
@Override
8686
public void writeTo(StreamOutput out) throws IOException {
8787
out.writeMap(indexToSettings, StreamOutput::writeWriteable);

server/src/main/java/org/elasticsearch/action/admin/indices/settings/get/TransportGetSettingsAction.java

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,22 @@
1111

1212
import org.elasticsearch.action.ActionListener;
1313
import org.elasticsearch.action.support.ActionFilters;
14-
import org.elasticsearch.action.support.master.TransportMasterNodeReadAction;
15-
import org.elasticsearch.cluster.ClusterState;
14+
import org.elasticsearch.action.support.ChannelActionListener;
15+
import org.elasticsearch.action.support.local.TransportLocalProjectMetadataAction;
16+
import org.elasticsearch.cluster.ProjectState;
1617
import org.elasticsearch.cluster.block.ClusterBlockException;
1718
import org.elasticsearch.cluster.block.ClusterBlockLevel;
1819
import org.elasticsearch.cluster.metadata.IndexMetadata;
1920
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
21+
import org.elasticsearch.cluster.project.ProjectResolver;
2022
import org.elasticsearch.cluster.service.ClusterService;
2123
import org.elasticsearch.common.regex.Regex;
2224
import org.elasticsearch.common.settings.IndexScopedSettings;
2325
import org.elasticsearch.common.settings.Settings;
2426
import org.elasticsearch.common.settings.SettingsFilter;
2527
import org.elasticsearch.common.util.CollectionUtils;
2628
import org.elasticsearch.common.util.Maps;
29+
import org.elasticsearch.core.UpdateForV10;
2730
import org.elasticsearch.index.Index;
2831
import org.elasticsearch.injection.guice.Inject;
2932
import org.elasticsearch.tasks.Task;
@@ -35,62 +38,80 @@
3538

3639
import static java.util.Collections.unmodifiableMap;
3740

38-
public class TransportGetSettingsAction extends TransportMasterNodeReadAction<GetSettingsRequest, GetSettingsResponse> {
41+
public class TransportGetSettingsAction extends TransportLocalProjectMetadataAction<GetSettingsRequest, GetSettingsResponse> {
3942

4043
private final SettingsFilter settingsFilter;
4144
private final IndexScopedSettings indexScopedSettings;
4245
private final IndexNameExpressionResolver indexNameExpressionResolver;
4346

47+
/**
48+
* NB prior to 9.1 this was a TransportMasterNodeReadAction so for BwC it must be registered with the TransportService until
49+
* we no longer need to support calling this action remotely.
50+
*/
51+
@UpdateForV10(owner = UpdateForV10.Owner.DATA_MANAGEMENT)
52+
@SuppressWarnings("this-escape")
4453
@Inject
4554
public TransportGetSettingsAction(
4655
TransportService transportService,
4756
ClusterService clusterService,
4857
ThreadPool threadPool,
4958
SettingsFilter settingsFilter,
5059
ActionFilters actionFilters,
60+
ProjectResolver projectResolver,
5161
IndexNameExpressionResolver indexNameExpressionResolver,
5262
IndexScopedSettings indexedScopedSettings
5363
) {
5464
super(
5565
GetSettingsAction.NAME,
56-
transportService,
57-
clusterService,
58-
threadPool,
5966
actionFilters,
60-
GetSettingsRequest::new,
61-
GetSettingsResponse::new,
62-
threadPool.executor(ThreadPool.Names.MANAGEMENT)
67+
transportService.getTaskManager(),
68+
clusterService,
69+
threadPool.executor(ThreadPool.Names.MANAGEMENT),
70+
projectResolver
6371
);
6472
this.settingsFilter = settingsFilter;
6573
this.indexScopedSettings = indexedScopedSettings;
6674
this.indexNameExpressionResolver = indexNameExpressionResolver;
75+
76+
transportService.registerRequestHandler(
77+
actionName,
78+
executor,
79+
false,
80+
true,
81+
GetSettingsRequest::new,
82+
(request, channel, task) -> executeDirect(task, request, new ChannelActionListener<>(channel))
83+
);
6784
}
6885

6986
@Override
70-
protected ClusterBlockException checkBlock(GetSettingsRequest request, ClusterState state) {
87+
protected ClusterBlockException checkBlock(GetSettingsRequest request, ProjectState state) {
7188
return state.blocks()
72-
.indicesBlockedException(ClusterBlockLevel.METADATA_READ, indexNameExpressionResolver.concreteIndexNames(state, request));
89+
.indicesBlockedException(
90+
state.projectId(),
91+
ClusterBlockLevel.METADATA_READ,
92+
indexNameExpressionResolver.concreteIndexNames(state.metadata(), request)
93+
);
7394
}
7495

7596
private static boolean isFilteredRequest(GetSettingsRequest request) {
7697
return CollectionUtils.isEmpty(request.names()) == false;
7798
}
7899

79100
@Override
80-
protected void masterOperation(
101+
protected void localClusterStateOperation(
81102
Task task,
82103
GetSettingsRequest request,
83-
ClusterState state,
104+
ProjectState state,
84105
ActionListener<GetSettingsResponse> listener
85106
) {
86107
assert Transports.assertNotTransportThread("O(indices) work is too much for a transport thread");
87-
final Index[] concreteIndices = indexNameExpressionResolver.concreteIndices(state, request);
108+
final Index[] concreteIndices = indexNameExpressionResolver.concreteIndices(state.metadata(), request);
88109
final Map<String, Settings> indexToSettings = Maps.newHashMapWithExpectedSize(concreteIndices.length);
89110
final Map<String, Settings> indexToDefaultSettings = request.includeDefaults()
90111
? Maps.newHashMapWithExpectedSize(concreteIndices.length)
91112
: null;
92113
for (Index concreteIndex : concreteIndices) {
93-
IndexMetadata indexMetadata = state.getMetadata().findIndex(concreteIndex).orElse(null);
114+
IndexMetadata indexMetadata = state.metadata().index(concreteIndex);
94115
if (indexMetadata == null) {
95116
continue;
96117
}

server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetSettingsAction.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.elasticsearch.rest.RestUtils;
2020
import org.elasticsearch.rest.Scope;
2121
import org.elasticsearch.rest.ServerlessScope;
22+
import org.elasticsearch.rest.action.RestCancellableNodeClient;
2223
import org.elasticsearch.rest.action.RestRefCountedChunkedToXContentListener;
2324

2425
import java.io.IOException;
@@ -58,7 +59,9 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC
5859
.humanReadable(request.hasParam("human"))
5960
.includeDefaults(renderDefaults)
6061
.names(names);
61-
getSettingsRequest.local(request.paramAsBoolean("local", getSettingsRequest.local()));
62-
return channel -> client.admin().indices().getSettings(getSettingsRequest, new RestRefCountedChunkedToXContentListener<>(channel));
62+
RestUtils.consumeDeprecatedLocalParameter(request);
63+
return channel -> new RestCancellableNodeClient(client, request.getHttpChannel()).admin()
64+
.indices()
65+
.getSettings(getSettingsRequest, new RestRefCountedChunkedToXContentListener<>(channel));
6366
}
6467
}

server/src/main/java/org/elasticsearch/rest/action/cat/RestIndicesAction.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ public RestResponse buildResponse(Void ignored) throws Exception {
123123
.indices()
124124
.prepareGetSettings(masterNodeTimeout, indices)
125125
.setIndicesOptions(indicesOptions)
126-
.setMasterNodeTimeout(masterNodeTimeout)
127126
.execute(listeners.acquire(indexSettingsRef::set));
128127

129128
// The other requests just provide additional detail, and wildcards may be resolved differently depending on the type of

0 commit comments

Comments
 (0)