Skip to content

Commit b67b5b1

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

File tree

20 files changed

+831
-26
lines changed

20 files changed

+831
-26
lines changed

buildSrc/src/main/resources/checkstyle_suppressions.xml

-1
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

+26
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

+23-1
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;
@@ -598,7 +599,7 @@ static Request rollover(RolloverRequest rolloverRequest) throws IOException {
598599
}
599600

600601
static Request indicesExist(GetIndexRequest request) {
601-
//this can be called with no indices as argument by transport client, not via REST though
602+
// this can be called with no indices as argument by transport client, not via REST though
602603
if (request.indices() == null || request.indices().length == 0) {
603604
throw new IllegalArgumentException("indices are mandatory");
604605
}
@@ -612,6 +613,20 @@ static Request indicesExist(GetIndexRequest request) {
612613
return new Request(HttpHead.METHOD_NAME, endpoint, params.getParams(), null);
613614
}
614615

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

851+
Params withPreserveExisting(boolean preserveExisting) {
852+
if (preserveExisting) {
853+
return putParam("preserve_existing", Boolean.TRUE.toString());
854+
}
855+
return this;
856+
}
857+
836858
Map<String, String> getParams() {
837859
return Collections.unmodifiableMap(params);
838860
}

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

+99
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,25 @@
4949
import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
5050
import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
5151
import org.elasticsearch.action.admin.indices.rollover.RolloverResponse;
52+
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
53+
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse;
5254
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
5355
import org.elasticsearch.action.admin.indices.shrink.ResizeResponse;
5456
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
5557
import org.elasticsearch.action.index.IndexRequest;
5658
import org.elasticsearch.action.support.IndicesOptions;
5759
import org.elasticsearch.action.support.WriteRequest;
5860
import org.elasticsearch.action.support.broadcast.BroadcastResponse;
61+
import org.elasticsearch.cluster.metadata.IndexMetaData;
62+
import org.elasticsearch.common.settings.Setting;
5963
import org.elasticsearch.common.settings.Settings;
6064
import org.elasticsearch.common.unit.ByteSizeUnit;
6165
import org.elasticsearch.common.unit.ByteSizeValue;
6266
import org.elasticsearch.common.unit.TimeValue;
6367
import org.elasticsearch.common.xcontent.XContentBuilder;
6468
import org.elasticsearch.common.xcontent.json.JsonXContent;
6569
import org.elasticsearch.common.xcontent.support.XContentMapValues;
70+
import org.elasticsearch.index.IndexSettings;
6671
import org.elasticsearch.rest.RestStatus;
6772

6873
import java.io.IOException;
@@ -72,6 +77,7 @@
7277
import static org.hamcrest.CoreMatchers.hasItem;
7378
import static org.hamcrest.Matchers.equalTo;
7479
import static org.hamcrest.Matchers.not;
80+
import static org.hamcrest.Matchers.startsWith;
7581

7682
public class IndicesClientIT extends ESRestHighLevelClientTestCase {
7783

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

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

+28
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;
@@ -1363,6 +1364,33 @@ public void testRollover() throws IOException {
13631364
assertEquals(expectedParams, request.getParameters());
13641365
}
13651366

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

0 commit comments

Comments
 (0)