Skip to content

Commit 02fc16f

Browse files
olcbeanjavanna
authored andcommitted
Add Cluster Put Settings API to the high level REST client (#28633)
Relates to #27205
1 parent 81eda18 commit 02fc16f

File tree

19 files changed

+821
-49
lines changed

19 files changed

+821
-49
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client;
21+
22+
import org.apache.http.Header;
23+
import org.elasticsearch.action.ActionListener;
24+
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
25+
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsResponse;
26+
27+
import java.io.IOException;
28+
29+
import static java.util.Collections.emptySet;
30+
31+
/**
32+
* A wrapper for the {@link RestHighLevelClient} that provides methods for accessing the Cluster API.
33+
* <p>
34+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster.html">Cluster API on elastic.co</a>
35+
*/
36+
public final class ClusterClient {
37+
private final RestHighLevelClient restHighLevelClient;
38+
39+
ClusterClient(RestHighLevelClient restHighLevelClient) {
40+
this.restHighLevelClient = restHighLevelClient;
41+
}
42+
43+
/**
44+
* Updates cluster wide specific settings using the Cluster Update Settings API
45+
* <p>
46+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-update-settings.html"> Cluster Update Settings
47+
* API on elastic.co</a>
48+
*/
49+
public ClusterUpdateSettingsResponse putSettings(ClusterUpdateSettingsRequest clusterUpdateSettingsRequest, Header... headers)
50+
throws IOException {
51+
return restHighLevelClient.performRequestAndParseEntity(clusterUpdateSettingsRequest, Request::clusterPutSettings,
52+
ClusterUpdateSettingsResponse::fromXContent, emptySet(), headers);
53+
}
54+
55+
/**
56+
* Asynchronously updates cluster wide specific settings using the Cluster Update Settings API
57+
* <p>
58+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-update-settings.html"> Cluster Update Settings
59+
* API on elastic.co</a>
60+
*/
61+
public void putSettingsAsync(ClusterUpdateSettingsRequest clusterUpdateSettingsRequest,
62+
ActionListener<ClusterUpdateSettingsResponse> listener, Header... headers) {
63+
restHighLevelClient.performRequestAsyncAndParseEntity(clusterUpdateSettingsRequest, Request::clusterPutSettings,
64+
ClusterUpdateSettingsResponse::fromXContent, listener, emptySet(), headers);
65+
}
66+
}

client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.apache.http.entity.ContentType;
3030
import org.apache.lucene.util.BytesRef;
3131
import org.elasticsearch.action.DocWriteRequest;
32+
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
3233
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
3334
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
3435
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
@@ -528,6 +529,17 @@ private static Request resize(ResizeRequest resizeRequest) throws IOException {
528529
return new Request(HttpPut.METHOD_NAME, endpoint, params.getParams(), entity);
529530
}
530531

532+
static Request clusterPutSettings(ClusterUpdateSettingsRequest clusterUpdateSettingsRequest) throws IOException {
533+
Params parameters = Params.builder();
534+
parameters.withFlatSettings(clusterUpdateSettingsRequest.flatSettings());
535+
parameters.withTimeout(clusterUpdateSettingsRequest.timeout());
536+
parameters.withMasterTimeout(clusterUpdateSettingsRequest.masterNodeTimeout());
537+
538+
String endpoint = buildEndpoint("_cluster/settings");
539+
HttpEntity entity = createEntity(clusterUpdateSettingsRequest, REQUEST_BODY_CONTENT_TYPE);
540+
return new Request(HttpPut.METHOD_NAME, endpoint, parameters.getParams(), entity);
541+
}
542+
531543
private static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) throws IOException {
532544
BytesRef source = XContentHelper.toXContent(toXContent, xContentType, false).toBytesRef();
533545
return new ByteArrayEntity(source.bytes, source.offset, source.length, createContentType(xContentType));

client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ public class RestHighLevelClient implements Closeable {
186186
private final CheckedConsumer<RestClient, IOException> doClose;
187187

188188
private final IndicesClient indicesClient = new IndicesClient(this);
189+
private final ClusterClient clusterClient = new ClusterClient(this);
189190

190191
/**
191192
* Creates a {@link RestHighLevelClient} given the low level {@link RestClientBuilder} that allows to build the
@@ -240,6 +241,15 @@ public final IndicesClient indices() {
240241
return indicesClient;
241242
}
242243

244+
/**
245+
* Provides a {@link ClusterClient} which can be used to access the Cluster API.
246+
*
247+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster.html">Cluster API on elastic.co</a>
248+
*/
249+
public final ClusterClient cluster() {
250+
return clusterClient;
251+
}
252+
243253
/**
244254
* Executes a bulk request using the Bulk API
245255
*
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client;
21+
22+
import org.elasticsearch.ElasticsearchException;
23+
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
24+
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsResponse;
25+
import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider;
26+
import org.elasticsearch.common.settings.Settings;
27+
import org.elasticsearch.common.unit.ByteSizeUnit;
28+
import org.elasticsearch.common.xcontent.XContentType;
29+
import org.elasticsearch.common.xcontent.support.XContentMapValues;
30+
import org.elasticsearch.indices.recovery.RecoverySettings;
31+
import org.elasticsearch.rest.RestStatus;
32+
33+
import java.io.IOException;
34+
import java.util.HashMap;
35+
import java.util.Map;
36+
37+
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
38+
import static org.hamcrest.Matchers.equalTo;
39+
import static org.hamcrest.Matchers.notNullValue;
40+
import static org.hamcrest.Matchers.nullValue;
41+
42+
public class ClusterClientIT extends ESRestHighLevelClientTestCase {
43+
44+
public void testClusterPutSettings() throws IOException {
45+
final String transientSettingKey = RecoverySettings.INDICES_RECOVERY_MAX_BYTES_PER_SEC_SETTING.getKey();
46+
final int transientSettingValue = 10;
47+
48+
final String persistentSettingKey = EnableAllocationDecider.CLUSTER_ROUTING_ALLOCATION_ENABLE_SETTING.getKey();
49+
final String persistentSettingValue = EnableAllocationDecider.Allocation.NONE.name();
50+
51+
Settings transientSettings = Settings.builder().put(transientSettingKey, transientSettingValue, ByteSizeUnit.BYTES).build();
52+
Map<String, Object> map = new HashMap<>();
53+
map.put(persistentSettingKey, persistentSettingValue);
54+
55+
ClusterUpdateSettingsRequest setRequest = new ClusterUpdateSettingsRequest();
56+
setRequest.transientSettings(transientSettings);
57+
setRequest.persistentSettings(map);
58+
59+
ClusterUpdateSettingsResponse setResponse = execute(setRequest, highLevelClient().cluster()::putSettings,
60+
highLevelClient().cluster()::putSettingsAsync);
61+
62+
assertAcked(setResponse);
63+
assertThat(setResponse.getTransientSettings().get(transientSettingKey), notNullValue());
64+
assertThat(setResponse.getTransientSettings().get(persistentSettingKey), nullValue());
65+
assertThat(setResponse.getTransientSettings().get(transientSettingKey),
66+
equalTo(transientSettingValue + ByteSizeUnit.BYTES.getSuffix()));
67+
assertThat(setResponse.getPersistentSettings().get(transientSettingKey), nullValue());
68+
assertThat(setResponse.getPersistentSettings().get(persistentSettingKey), notNullValue());
69+
assertThat(setResponse.getPersistentSettings().get(persistentSettingKey), equalTo(persistentSettingValue));
70+
71+
Map<String, Object> setMap = getAsMap("/_cluster/settings");
72+
String transientSetValue = (String) XContentMapValues.extractValue("transient." + transientSettingKey, setMap);
73+
assertThat(transientSetValue, equalTo(transientSettingValue + ByteSizeUnit.BYTES.getSuffix()));
74+
String persistentSetValue = (String) XContentMapValues.extractValue("persistent." + persistentSettingKey, setMap);
75+
assertThat(persistentSetValue, equalTo(persistentSettingValue));
76+
77+
ClusterUpdateSettingsRequest resetRequest = new ClusterUpdateSettingsRequest();
78+
resetRequest.transientSettings(Settings.builder().putNull(transientSettingKey));
79+
resetRequest.persistentSettings("{\"" + persistentSettingKey + "\": null }", XContentType.JSON);
80+
81+
ClusterUpdateSettingsResponse resetResponse = execute(resetRequest, highLevelClient().cluster()::putSettings,
82+
highLevelClient().cluster()::putSettingsAsync);
83+
84+
assertThat(resetResponse.getTransientSettings().get(transientSettingKey), equalTo(null));
85+
assertThat(resetResponse.getPersistentSettings().get(persistentSettingKey), equalTo(null));
86+
assertThat(resetResponse.getTransientSettings(), equalTo(Settings.EMPTY));
87+
assertThat(resetResponse.getPersistentSettings(), equalTo(Settings.EMPTY));
88+
89+
Map<String, Object> resetMap = getAsMap("/_cluster/settings");
90+
String transientResetValue = (String) XContentMapValues.extractValue("transient." + transientSettingKey, resetMap);
91+
assertThat(transientResetValue, equalTo(null));
92+
String persistentResetValue = (String) XContentMapValues.extractValue("persistent." + persistentSettingKey, resetMap);
93+
assertThat(persistentResetValue, equalTo(null));
94+
}
95+
96+
public void testClusterUpdateSettingNonExistent() {
97+
String setting = "no_idea_what_you_are_talking_about";
98+
int value = 10;
99+
ClusterUpdateSettingsRequest clusterUpdateSettingsRequest = new ClusterUpdateSettingsRequest();
100+
clusterUpdateSettingsRequest.transientSettings(Settings.builder().put(setting, value).build());
101+
102+
ElasticsearchException exception = expectThrows(ElasticsearchException.class, () -> execute(clusterUpdateSettingsRequest,
103+
highLevelClient().cluster()::putSettings, highLevelClient().cluster()::putSettingsAsync));
104+
assertThat(exception.status(), equalTo(RestStatus.BAD_REQUEST));
105+
assertThat(exception.getMessage(), equalTo(
106+
"Elasticsearch exception [type=illegal_argument_exception, reason=transient setting [" + setting + "], not recognized]"));
107+
}
108+
}

client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ public void testCreateIndex() throws IOException {
167167
}
168168
}
169169

170-
@SuppressWarnings({"unchecked", "rawtypes"})
171170
public void testPutMapping() throws IOException {
172171
{
173172
// Add mappings to index

client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.apache.http.entity.StringEntity;
3131
import org.apache.http.util.EntityUtils;
3232
import org.elasticsearch.action.DocWriteRequest;
33+
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
3334
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
3435
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
3536
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
@@ -272,7 +273,7 @@ public void testIndicesExist() {
272273
Map<String, String> expectedParams = new HashMap<>();
273274
setRandomIndicesOptions(getIndexRequest::indicesOptions, getIndexRequest::indicesOptions, expectedParams);
274275
setRandomLocal(getIndexRequest, expectedParams);
275-
setRandomFlatSettings(getIndexRequest, expectedParams);
276+
setRandomFlatSettings(getIndexRequest::flatSettings, expectedParams);
276277
setRandomHumanReadable(getIndexRequest, expectedParams);
277278
setRandomIncludeDefaults(getIndexRequest, expectedParams);
278279

@@ -1115,14 +1116,10 @@ private static void resizeTest(ResizeType resizeType, CheckedFunction<ResizeRequ
11151116
if (randomBoolean()) {
11161117
randomAliases(createIndexRequest);
11171118
}
1118-
if (randomBoolean()) {
1119-
setRandomWaitForActiveShards(createIndexRequest::waitForActiveShards, expectedParams);
1120-
}
1119+
setRandomWaitForActiveShards(createIndexRequest::waitForActiveShards, expectedParams);
11211120
resizeRequest.setTargetIndex(createIndexRequest);
11221121
} else {
1123-
if (randomBoolean()) {
1124-
setRandomWaitForActiveShards(resizeRequest::setWaitForActiveShards, expectedParams);
1125-
}
1122+
setRandomWaitForActiveShards(resizeRequest::setWaitForActiveShards, expectedParams);
11261123
}
11271124

11281125
Request request = function.apply(resizeRequest);
@@ -1133,6 +1130,19 @@ private static void resizeTest(ResizeType resizeType, CheckedFunction<ResizeRequ
11331130
assertEquals(expectedParams, request.getParameters());
11341131
assertToXContentBody(resizeRequest, request.getEntity());
11351132
}
1133+
1134+
public void testClusterPutSettings() throws IOException {
1135+
ClusterUpdateSettingsRequest request = new ClusterUpdateSettingsRequest();
1136+
Map<String, String> expectedParams = new HashMap<>();
1137+
setRandomFlatSettings(request::flatSettings, expectedParams);
1138+
setRandomMasterTimeout(request, expectedParams);
1139+
setRandomTimeout(request::timeout, AcknowledgedRequest.DEFAULT_ACK_TIMEOUT, expectedParams);
1140+
1141+
Request expectedRequest = Request.clusterPutSettings(request);
1142+
assertEquals("/_cluster/settings", expectedRequest.getEndpoint());
1143+
assertEquals(HttpPut.METHOD_NAME, expectedRequest.getMethod());
1144+
assertEquals(expectedParams, expectedRequest.getParameters());
1145+
}
11361146

11371147
private static void assertToXContentBody(ToXContent expectedBody, HttpEntity actualEntity) throws IOException {
11381148
BytesReference expectedBytes = XContentHelper.toXContent(expectedBody, REQUEST_BODY_CONTENT_TYPE, false);
@@ -1289,16 +1299,6 @@ private static void setRandomHumanReadable(GetIndexRequest request, Map<String,
12891299
}
12901300
}
12911301

1292-
private static void setRandomFlatSettings(GetIndexRequest request, Map<String, String> expectedParams) {
1293-
if (randomBoolean()) {
1294-
boolean flatSettings = randomBoolean();
1295-
request.flatSettings(flatSettings);
1296-
if (flatSettings) {
1297-
expectedParams.put("flat_settings", String.valueOf(flatSettings));
1298-
}
1299-
}
1300-
}
1301-
13021302
private static void setRandomLocal(MasterNodeReadRequest<?> request, Map<String, String> expectedParams) {
13031303
if (randomBoolean()) {
13041304
boolean local = randomBoolean();
@@ -1319,6 +1319,16 @@ private static void setRandomTimeout(Consumer<String> setter, TimeValue defaultT
13191319
}
13201320
}
13211321

1322+
private static void setRandomFlatSettings(Consumer<Boolean> setter, Map<String, String> expectedParams) {
1323+
if (randomBoolean()) {
1324+
boolean flatSettings = randomBoolean();
1325+
setter.accept(flatSettings);
1326+
if (flatSettings) {
1327+
expectedParams.put("flat_settings", String.valueOf(flatSettings));
1328+
}
1329+
}
1330+
}
1331+
13221332
private static void setRandomMasterTimeout(MasterNodeRequest<?> request, Map<String, String> expectedParams) {
13231333
if (randomBoolean()) {
13241334
String masterTimeout = randomTimeValue();

0 commit comments

Comments
 (0)