Skip to content

Commit e917e85

Browse files
olcbeanjavanna
authored andcommitted
REST high-level client: add support for Indices Update Settings API (#28892)
Relates to #27205
1 parent 0c97d1b commit e917e85

File tree

20 files changed

+830
-26
lines changed

20 files changed

+830
-26
lines changed

buildSrc/src/main/resources/checkstyle_suppressions.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@
151151
<suppress files="server[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]action[/\\]support[/\\]broadcast[/\\]BroadcastOperationRequestBuilder.java" checks="LineLength" />
152152
<suppress files="server[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]action[/\\]support[/\\]broadcast[/\\]TransportBroadcastAction.java" checks="LineLength" />
153153
<suppress files="server[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]action[/\\]support[/\\]broadcast[/\\]node[/\\]TransportBroadcastByNodeAction.java" checks="LineLength" />
154-
<suppress files="server[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]action[/\\]support[/\\]master[/\\]AcknowledgedRequest.java" checks="LineLength" />
155154
<suppress files="server[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]action[/\\]support[/\\]master[/\\]AcknowledgedRequestBuilder.java" checks="LineLength" />
156155
<suppress files="server[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]action[/\\]support[/\\]master[/\\]MasterNodeOperationRequestBuilder.java" checks="LineLength" />
157156
<suppress files="server[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]action[/\\]support[/\\]master[/\\]MasterNodeReadOperationRequestBuilder.java" checks="LineLength" />

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
4646
import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
4747
import org.elasticsearch.action.admin.indices.rollover.RolloverResponse;
48+
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
49+
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse;
4850
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
4951
import org.elasticsearch.action.admin.indices.shrink.ResizeResponse;
5052

@@ -406,4 +408,28 @@ public void rolloverAsync(RolloverRequest rolloverRequest, ActionListener<Rollov
406408
restHighLevelClient.performRequestAsyncAndParseEntity(rolloverRequest, Request::rollover, RolloverResponse::fromXContent,
407409
listener, emptySet(), headers);
408410
}
411+
412+
/**
413+
* Updates specific index level settings using the Update Indices Settings API
414+
* <p>
415+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html"> Update Indices Settings
416+
* API on elastic.co</a>
417+
*/
418+
public UpdateSettingsResponse putSettings(UpdateSettingsRequest updateSettingsRequest, Header... headers) throws IOException {
419+
return restHighLevelClient.performRequestAndParseEntity(updateSettingsRequest, Request::indexPutSettings,
420+
UpdateSettingsResponse::fromXContent, emptySet(), headers);
421+
}
422+
423+
/**
424+
* Asynchronously updates specific index level settings using the Update Indices Settings API
425+
* <p>
426+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html"> Update Indices Settings
427+
* API on elastic.co</a>
428+
*/
429+
public void putSettingsAsync(UpdateSettingsRequest updateSettingsRequest, ActionListener<UpdateSettingsResponse> listener,
430+
Header... headers) {
431+
restHighLevelClient.performRequestAsyncAndParseEntity(updateSettingsRequest, Request::indexPutSettings,
432+
UpdateSettingsResponse::fromXContent, listener, emptySet(), headers);
433+
}
434+
409435
}

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
4444
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
4545
import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
46+
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
4647
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
4748
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
4849
import org.elasticsearch.action.bulk.BulkRequest;
@@ -600,7 +601,7 @@ static Request rollover(RolloverRequest rolloverRequest) throws IOException {
600601
}
601602

602603
static Request indicesExist(GetIndexRequest request) {
603-
//this can be called with no indices as argument by transport client, not via REST though
604+
// this can be called with no indices as argument by transport client, not via REST though
604605
if (request.indices() == null || request.indices().length == 0) {
605606
throw new IllegalArgumentException("indices are mandatory");
606607
}
@@ -614,6 +615,20 @@ static Request indicesExist(GetIndexRequest request) {
614615
return new Request(HttpHead.METHOD_NAME, endpoint, params.getParams(), null);
615616
}
616617

618+
static Request indexPutSettings(UpdateSettingsRequest updateSettingsRequest) throws IOException {
619+
Params parameters = Params.builder();
620+
parameters.withTimeout(updateSettingsRequest.timeout());
621+
parameters.withMasterTimeout(updateSettingsRequest.masterNodeTimeout());
622+
parameters.withIndicesOptions(updateSettingsRequest.indicesOptions());
623+
parameters.withFlatSettings(updateSettingsRequest.flatSettings());
624+
parameters.withPreserveExisting(updateSettingsRequest.isPreserveExisting());
625+
626+
String[] indices = updateSettingsRequest.indices() == null ? Strings.EMPTY_ARRAY : updateSettingsRequest.indices();
627+
String endpoint = endpoint(indices, "_settings");
628+
HttpEntity entity = createEntity(updateSettingsRequest, REQUEST_BODY_CONTENT_TYPE);
629+
return new Request(HttpPut.METHOD_NAME, endpoint, parameters.getParams(), entity);
630+
}
631+
617632
private static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) throws IOException {
618633
BytesRef source = XContentHelper.toXContent(toXContent, xContentType, false).toBytesRef();
619634
return new ByteArrayEntity(source.bytes, source.offset, source.length, createContentType(xContentType));
@@ -842,6 +857,13 @@ Params withIncludeDefaults(boolean includeDefaults) {
842857
return this;
843858
}
844859

860+
Params withPreserveExisting(boolean preserveExisting) {
861+
if (preserveExisting) {
862+
return putParam("preserve_existing", Boolean.TRUE.toString());
863+
}
864+
return this;
865+
}
866+
845867
Map<String, String> getParams() {
846868
return Collections.unmodifiableMap(params);
847869
}

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

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,25 @@
5050
import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
5151
import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
5252
import org.elasticsearch.action.admin.indices.rollover.RolloverResponse;
53+
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
54+
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse;
5355
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
5456
import org.elasticsearch.action.admin.indices.shrink.ResizeResponse;
5557
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
5658
import org.elasticsearch.action.index.IndexRequest;
5759
import org.elasticsearch.action.support.IndicesOptions;
5860
import org.elasticsearch.action.support.WriteRequest;
5961
import org.elasticsearch.action.support.broadcast.BroadcastResponse;
62+
import org.elasticsearch.cluster.metadata.IndexMetaData;
63+
import org.elasticsearch.common.settings.Setting;
6064
import org.elasticsearch.common.settings.Settings;
6165
import org.elasticsearch.common.unit.ByteSizeUnit;
6266
import org.elasticsearch.common.unit.ByteSizeValue;
6367
import org.elasticsearch.common.unit.TimeValue;
6468
import org.elasticsearch.common.xcontent.XContentBuilder;
6569
import org.elasticsearch.common.xcontent.json.JsonXContent;
6670
import org.elasticsearch.common.xcontent.support.XContentMapValues;
71+
import org.elasticsearch.index.IndexSettings;
6772
import org.elasticsearch.rest.RestStatus;
6873

6974
import java.io.IOException;
@@ -73,6 +78,7 @@
7378
import static org.hamcrest.CoreMatchers.hasItem;
7479
import static org.hamcrest.Matchers.equalTo;
7580
import static org.hamcrest.Matchers.not;
81+
import static org.hamcrest.Matchers.startsWith;
7682

7783
public class IndicesClientIT extends ESRestHighLevelClientTestCase {
7884

@@ -611,4 +617,97 @@ public void testRollover() throws IOException {
611617
assertEquals("test_new", rolloverResponse.getNewIndex());
612618
}
613619
}
620+
621+
public void testIndexPutSettings() throws IOException {
622+
623+
final Setting<Integer> dynamicSetting = IndexMetaData.INDEX_NUMBER_OF_REPLICAS_SETTING;
624+
final String dynamicSettingKey = IndexMetaData.SETTING_NUMBER_OF_REPLICAS;
625+
final int dynamicSettingValue = 0;
626+
627+
final Setting<String> staticSetting = IndexSettings.INDEX_CHECK_ON_STARTUP;
628+
final String staticSettingKey = IndexSettings.INDEX_CHECK_ON_STARTUP.getKey();
629+
final String staticSettingValue = "true";
630+
631+
final Setting<Integer> unmodifiableSetting = IndexMetaData.INDEX_NUMBER_OF_SHARDS_SETTING;
632+
final String unmodifiableSettingKey = IndexMetaData.SETTING_NUMBER_OF_SHARDS;
633+
final int unmodifiableSettingValue = 3;
634+
635+
String index = "index";
636+
createIndex(index, Settings.EMPTY);
637+
638+
assertThat(dynamicSetting.getDefault(Settings.EMPTY), not(dynamicSettingValue));
639+
UpdateSettingsRequest dynamicSettingRequest = new UpdateSettingsRequest();
640+
dynamicSettingRequest.settings(Settings.builder().put(dynamicSettingKey, dynamicSettingValue).build());
641+
UpdateSettingsResponse response = execute(dynamicSettingRequest, highLevelClient().indices()::putSettings,
642+
highLevelClient().indices()::putSettingsAsync);
643+
644+
assertTrue(response.isAcknowledged());
645+
Map<String, Object> indexSettingsAsMap = getIndexSettingsAsMap(index);
646+
assertThat(indexSettingsAsMap.get(dynamicSettingKey), equalTo(String.valueOf(dynamicSettingValue)));
647+
648+
assertThat(staticSetting.getDefault(Settings.EMPTY), not(staticSettingValue));
649+
UpdateSettingsRequest staticSettingRequest = new UpdateSettingsRequest();
650+
staticSettingRequest.settings(Settings.builder().put(staticSettingKey, staticSettingValue).build());
651+
ElasticsearchException exception = expectThrows(ElasticsearchException.class, () -> execute(staticSettingRequest,
652+
highLevelClient().indices()::putSettings, highLevelClient().indices()::putSettingsAsync));
653+
assertThat(exception.getMessage(),
654+
startsWith("Elasticsearch exception [type=illegal_argument_exception, "
655+
+ "reason=Can't update non dynamic settings [[index.shard.check_on_startup]] for open indices [[index/"));
656+
657+
indexSettingsAsMap = getIndexSettingsAsMap(index);
658+
assertNull(indexSettingsAsMap.get(staticSettingKey));
659+
660+
closeIndex(index);
661+
response = execute(staticSettingRequest, highLevelClient().indices()::putSettings,
662+
highLevelClient().indices()::putSettingsAsync);
663+
assertTrue(response.isAcknowledged());
664+
openIndex(index);
665+
indexSettingsAsMap = getIndexSettingsAsMap(index);
666+
assertThat(indexSettingsAsMap.get(staticSettingKey), equalTo(staticSettingValue));
667+
668+
assertThat(unmodifiableSetting.getDefault(Settings.EMPTY), not(unmodifiableSettingValue));
669+
UpdateSettingsRequest unmodifiableSettingRequest = new UpdateSettingsRequest();
670+
unmodifiableSettingRequest.settings(Settings.builder().put(unmodifiableSettingKey, unmodifiableSettingValue).build());
671+
exception = expectThrows(ElasticsearchException.class, () -> execute(unmodifiableSettingRequest,
672+
highLevelClient().indices()::putSettings, highLevelClient().indices()::putSettingsAsync));
673+
assertThat(exception.getMessage(), startsWith(
674+
"Elasticsearch exception [type=illegal_argument_exception, "
675+
+ "reason=Can't update non dynamic settings [[index.number_of_shards]] for open indices [[index/"));
676+
closeIndex(index);
677+
exception = expectThrows(ElasticsearchException.class, () -> execute(unmodifiableSettingRequest,
678+
highLevelClient().indices()::putSettings, highLevelClient().indices()::putSettingsAsync));
679+
assertThat(exception.getMessage(), startsWith(
680+
"Elasticsearch exception [type=illegal_argument_exception, "
681+
+ "reason=final index setting [index.number_of_shards], not updateable"));
682+
}
683+
684+
@SuppressWarnings("unchecked")
685+
private Map<String, Object> getIndexSettingsAsMap(String index) throws IOException {
686+
Map<String, Object> indexSettings = getIndexSettings(index);
687+
return (Map<String, Object>)((Map<String, Object>) indexSettings.get(index)).get("settings");
688+
}
689+
690+
public void testIndexPutSettingNonExistent() throws IOException {
691+
692+
String index = "index";
693+
UpdateSettingsRequest indexUpdateSettingsRequest = new UpdateSettingsRequest(index);
694+
String setting = "no_idea_what_you_are_talking_about";
695+
int value = 10;
696+
indexUpdateSettingsRequest.settings(Settings.builder().put(setting, value).build());
697+
698+
ElasticsearchException exception = expectThrows(ElasticsearchException.class, () -> execute(indexUpdateSettingsRequest,
699+
highLevelClient().indices()::putSettings, highLevelClient().indices()::putSettingsAsync));
700+
assertEquals(RestStatus.NOT_FOUND, exception.status());
701+
assertThat(exception.getMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]"));
702+
703+
createIndex(index, Settings.EMPTY);
704+
exception = expectThrows(ElasticsearchException.class, () -> execute(indexUpdateSettingsRequest,
705+
highLevelClient().indices()::putSettings, highLevelClient().indices()::putSettingsAsync));
706+
assertThat(exception.status(), equalTo(RestStatus.BAD_REQUEST));
707+
assertThat(exception.getMessage(), equalTo(
708+
"Elasticsearch exception [type=illegal_argument_exception, "
709+
+ "reason=unknown setting [index.no_idea_what_you_are_talking_about] please check that any required plugins are installed, "
710+
+ "or check the breaking changes documentation for removed settings]"));
711+
}
712+
614713
}

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
4747
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
4848
import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
49+
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
4950
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
5051
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
5152
import org.elasticsearch.action.bulk.BulkRequest;
@@ -1366,6 +1367,33 @@ public void testRollover() throws IOException {
13661367
assertEquals(expectedParams, request.getParameters());
13671368
}
13681369

1370+
public void testIndexPutSettings() throws IOException {
1371+
String[] indices = randomBoolean() ? null : randomIndicesNames(0, 2);
1372+
UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest(indices);
1373+
Map<String, String> expectedParams = new HashMap<>();
1374+
setRandomFlatSettings(updateSettingsRequest::flatSettings, expectedParams);
1375+
setRandomMasterTimeout(updateSettingsRequest, expectedParams);
1376+
setRandomTimeout(updateSettingsRequest::timeout, AcknowledgedRequest.DEFAULT_ACK_TIMEOUT, expectedParams);
1377+
setRandomIndicesOptions(updateSettingsRequest::indicesOptions, updateSettingsRequest::indicesOptions, expectedParams);
1378+
if (randomBoolean()) {
1379+
updateSettingsRequest.setPreserveExisting(randomBoolean());
1380+
if (updateSettingsRequest.isPreserveExisting()) {
1381+
expectedParams.put("preserve_existing", "true");
1382+
}
1383+
}
1384+
1385+
Request request = Request.indexPutSettings(updateSettingsRequest);
1386+
StringJoiner endpoint = new StringJoiner("/", "/", "");
1387+
if (indices != null && indices.length > 0) {
1388+
endpoint.add(String.join(",", indices));
1389+
}
1390+
endpoint.add("_settings");
1391+
assertThat(endpoint.toString(), equalTo(request.getEndpoint()));
1392+
assertEquals(HttpPut.METHOD_NAME, request.getMethod());
1393+
assertToXContentBody(updateSettingsRequest, request.getEntity());
1394+
assertEquals(expectedParams, request.getParameters());
1395+
}
1396+
13691397
private static void assertToXContentBody(ToXContent expectedBody, HttpEntity actualEntity) throws IOException {
13701398
BytesReference expectedBytes = XContentHelper.toXContent(expectedBody, REQUEST_BODY_CONTENT_TYPE, false);
13711399
assertEquals(XContentType.JSON.mediaTypeWithoutParameters(), actualEntity.getContentType().getValue());

0 commit comments

Comments
 (0)