mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-25 01:19:02 +00:00
Add Get Settings API support to java high-level rest client (#29229)
This PR adds support for the Get Settings API to the java high-level rest client. Furthermore, logic related to the retrieval of default settings has been moved from the rest layer into the transport layer and now default settings may be retrieved consistency via both the rest API and the transport API.
This commit is contained in:
parent
bf51a21b6c
commit
0a93956194
@ -43,6 +43,8 @@ import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
|
||||
import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
|
||||
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
|
||||
import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
|
||||
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
|
||||
import org.elasticsearch.action.admin.indices.rollover.RolloverResponse;
|
||||
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
|
||||
@ -265,6 +267,28 @@ public final class IndicesClient {
|
||||
listener, emptySet(), headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the settings of one or more indices
|
||||
* <p>
|
||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-get-settings.html">
|
||||
* Indices Get Settings API on elastic.co</a>
|
||||
*/
|
||||
public GetSettingsResponse getSettings(GetSettingsRequest getSettingsRequest, Header... headers) throws IOException {
|
||||
return restHighLevelClient.performRequestAndParseEntity(getSettingsRequest, RequestConverters::getSettings,
|
||||
GetSettingsResponse::fromXContent, emptySet(), headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously retrieve the settings of one or more indices
|
||||
* <p>
|
||||
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-get-settings.html">
|
||||
* Indices Get Settings API on elastic.co</a>
|
||||
*/
|
||||
public void getSettingsAsync(GetSettingsRequest getSettingsRequest, ActionListener<GetSettingsResponse> listener, Header... headers) {
|
||||
restHighLevelClient.performRequestAsyncAndParseEntity(getSettingsRequest, RequestConverters::getSettings,
|
||||
GetSettingsResponse::fromXContent, listener, emptySet(), headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force merge one or more indices using the Force Merge API
|
||||
* <p>
|
||||
|
@ -44,6 +44,7 @@ import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
|
||||
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
|
||||
import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
|
||||
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
|
||||
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
|
||||
import org.elasticsearch.action.bulk.BulkRequest;
|
||||
@ -600,6 +601,22 @@ final class RequestConverters {
|
||||
return request;
|
||||
}
|
||||
|
||||
static Request getSettings(GetSettingsRequest getSettingsRequest) throws IOException {
|
||||
String[] indices = getSettingsRequest.indices() == null ? Strings.EMPTY_ARRAY : getSettingsRequest.indices();
|
||||
String[] names = getSettingsRequest.names() == null ? Strings.EMPTY_ARRAY : getSettingsRequest.names();
|
||||
|
||||
String endpoint = endpoint(indices, "_settings", names);
|
||||
Request request = new Request(HttpGet.METHOD_NAME, endpoint);
|
||||
|
||||
Params params = new Params(request);
|
||||
params.withIndicesOptions(getSettingsRequest.indicesOptions());
|
||||
params.withLocal(getSettingsRequest.local());
|
||||
params.withIncludeDefaults(getSettingsRequest.includeDefaults());
|
||||
params.withMasterTimeout(getSettingsRequest.masterNodeTimeout());
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
static Request indicesExist(GetIndexRequest getIndexRequest) {
|
||||
// this can be called with no indices as argument by transport client, not via REST though
|
||||
if (getIndexRequest.indices() == null || getIndexRequest.indices().length == 0) {
|
||||
|
@ -51,6 +51,8 @@ import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
|
||||
import org.elasticsearch.action.admin.indices.rollover.RolloverResponse;
|
||||
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
|
||||
import org.elasticsearch.action.admin.indices.shrink.ResizeResponse;
|
||||
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
|
||||
@ -189,6 +191,108 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetSettings() throws IOException {
|
||||
String indexName = "get_settings_index";
|
||||
Settings basicSettings = Settings.builder()
|
||||
.put("number_of_shards", 1)
|
||||
.put("number_of_replicas", 0)
|
||||
.build();
|
||||
createIndex(indexName, basicSettings);
|
||||
|
||||
GetSettingsRequest getSettingsRequest = new GetSettingsRequest().indices(indexName);
|
||||
GetSettingsResponse getSettingsResponse = execute(getSettingsRequest, highLevelClient().indices()::getSettings,
|
||||
highLevelClient().indices()::getSettingsAsync);
|
||||
|
||||
assertNull(getSettingsResponse.getSetting(indexName, "index.refresh_interval"));
|
||||
assertEquals("1", getSettingsResponse.getSetting(indexName, "index.number_of_shards"));
|
||||
|
||||
updateIndexSettings(indexName, Settings.builder().put("refresh_interval", "30s"));
|
||||
|
||||
GetSettingsResponse updatedResponse = execute(getSettingsRequest, highLevelClient().indices()::getSettings,
|
||||
highLevelClient().indices()::getSettingsAsync);
|
||||
assertEquals("30s", updatedResponse.getSetting(indexName, "index.refresh_interval"));
|
||||
}
|
||||
|
||||
public void testGetSettingsNonExistentIndex() throws IOException {
|
||||
String nonExistentIndex = "index_that_doesnt_exist";
|
||||
assertFalse(indexExists(nonExistentIndex));
|
||||
|
||||
GetSettingsRequest getSettingsRequest = new GetSettingsRequest().indices(nonExistentIndex);
|
||||
ElasticsearchException exception = expectThrows(ElasticsearchException.class,
|
||||
() -> execute(getSettingsRequest, highLevelClient().indices()::getSettings, highLevelClient().indices()::getSettingsAsync));
|
||||
assertEquals(RestStatus.NOT_FOUND, exception.status());
|
||||
}
|
||||
|
||||
public void testGetSettingsFromMultipleIndices() throws IOException {
|
||||
String indexName1 = "get_multiple_settings_one";
|
||||
createIndex(indexName1, Settings.builder().put("number_of_shards", 2).build());
|
||||
|
||||
String indexName2 = "get_multiple_settings_two";
|
||||
createIndex(indexName2, Settings.builder().put("number_of_shards", 3).build());
|
||||
|
||||
GetSettingsRequest getSettingsRequest = new GetSettingsRequest().indices("get_multiple_settings*");
|
||||
GetSettingsResponse getSettingsResponse = execute(getSettingsRequest, highLevelClient().indices()::getSettings,
|
||||
highLevelClient().indices()::getSettingsAsync);
|
||||
|
||||
assertEquals("2", getSettingsResponse.getSetting(indexName1, "index.number_of_shards"));
|
||||
assertEquals("3", getSettingsResponse.getSetting(indexName2, "index.number_of_shards"));
|
||||
}
|
||||
|
||||
public void testGetSettingsFiltered() throws IOException {
|
||||
String indexName = "get_settings_index";
|
||||
Settings basicSettings = Settings.builder()
|
||||
.put("number_of_shards", 1)
|
||||
.put("number_of_replicas", 0)
|
||||
.build();
|
||||
createIndex(indexName, basicSettings);
|
||||
|
||||
GetSettingsRequest getSettingsRequest = new GetSettingsRequest().indices(indexName).names("index.number_of_shards");
|
||||
GetSettingsResponse getSettingsResponse = execute(getSettingsRequest, highLevelClient().indices()::getSettings,
|
||||
highLevelClient().indices()::getSettingsAsync);
|
||||
|
||||
assertNull(getSettingsResponse.getSetting(indexName, "index.number_of_replicas"));
|
||||
assertEquals("1", getSettingsResponse.getSetting(indexName, "index.number_of_shards"));
|
||||
assertEquals(1, getSettingsResponse.getIndexToSettings().get("get_settings_index").size());
|
||||
}
|
||||
|
||||
public void testGetSettingsWithDefaults() throws IOException {
|
||||
String indexName = "get_settings_index";
|
||||
Settings basicSettings = Settings.builder()
|
||||
.put("number_of_shards", 1)
|
||||
.put("number_of_replicas", 0)
|
||||
.build();
|
||||
createIndex(indexName, basicSettings);
|
||||
|
||||
GetSettingsRequest getSettingsRequest = new GetSettingsRequest().indices(indexName).includeDefaults(true);
|
||||
GetSettingsResponse getSettingsResponse = execute(getSettingsRequest, highLevelClient().indices()::getSettings,
|
||||
highLevelClient().indices()::getSettingsAsync);
|
||||
|
||||
assertNotNull(getSettingsResponse.getSetting(indexName, "index.refresh_interval"));
|
||||
assertEquals(IndexSettings.DEFAULT_REFRESH_INTERVAL,
|
||||
getSettingsResponse.getIndexToDefaultSettings().get("get_settings_index").getAsTime("index.refresh_interval", null));
|
||||
assertEquals("1", getSettingsResponse.getSetting(indexName, "index.number_of_shards"));
|
||||
}
|
||||
|
||||
public void testGetSettingsWithDefaultsFiltered() throws IOException {
|
||||
String indexName = "get_settings_index";
|
||||
Settings basicSettings = Settings.builder()
|
||||
.put("number_of_shards", 1)
|
||||
.put("number_of_replicas", 0)
|
||||
.build();
|
||||
createIndex(indexName, basicSettings);
|
||||
|
||||
GetSettingsRequest getSettingsRequest = new GetSettingsRequest()
|
||||
.indices(indexName)
|
||||
.names("index.refresh_interval")
|
||||
.includeDefaults(true);
|
||||
GetSettingsResponse getSettingsResponse = execute(getSettingsRequest, highLevelClient().indices()::getSettings,
|
||||
highLevelClient().indices()::getSettingsAsync);
|
||||
|
||||
assertNull(getSettingsResponse.getSetting(indexName, "index.number_of_replicas"));
|
||||
assertNull(getSettingsResponse.getSetting(indexName, "index.number_of_shards"));
|
||||
assertEquals(0, getSettingsResponse.getIndexToSettings().get("get_settings_index").size());
|
||||
assertEquals(1, getSettingsResponse.getIndexToDefaultSettings().get("get_settings_index").size());
|
||||
}
|
||||
public void testPutMapping() throws IOException {
|
||||
{
|
||||
// Add mappings to index
|
||||
|
@ -47,6 +47,7 @@ import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
|
||||
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
|
||||
import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
|
||||
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
|
||||
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
|
||||
import org.elasticsearch.action.bulk.BulkRequest;
|
||||
@ -76,6 +77,7 @@ import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.io.Streams;
|
||||
import org.elasticsearch.common.lucene.uid.Versions;
|
||||
import org.elasticsearch.common.settings.IndexScopedSettings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
@ -405,6 +407,52 @@ public class RequestConvertersTests extends ESTestCase {
|
||||
assertNull(request.getEntity());
|
||||
}
|
||||
|
||||
public void testGetSettings() throws IOException {
|
||||
String[] indicesUnderTest = randomBoolean() ? null : randomIndicesNames(0, 5);
|
||||
|
||||
GetSettingsRequest getSettingsRequest = new GetSettingsRequest().indices(indicesUnderTest);
|
||||
|
||||
Map<String, String> expectedParams = new HashMap<>();
|
||||
setRandomMasterTimeout(getSettingsRequest, expectedParams);
|
||||
setRandomIndicesOptions(getSettingsRequest::indicesOptions, getSettingsRequest::indicesOptions, expectedParams);
|
||||
|
||||
setRandomLocal(getSettingsRequest, expectedParams);
|
||||
|
||||
if (randomBoolean()) {
|
||||
//the request object will not have include_defaults present unless it is set to true
|
||||
getSettingsRequest.includeDefaults(randomBoolean());
|
||||
if (getSettingsRequest.includeDefaults()) {
|
||||
expectedParams.put("include_defaults", Boolean.toString(true));
|
||||
}
|
||||
}
|
||||
|
||||
StringJoiner endpoint = new StringJoiner("/", "/", "");
|
||||
if (indicesUnderTest != null && indicesUnderTest.length > 0) {
|
||||
endpoint.add(String.join(",", indicesUnderTest));
|
||||
}
|
||||
endpoint.add("_settings");
|
||||
|
||||
if (randomBoolean()) {
|
||||
String[] names = randomBoolean() ? null : new String[randomIntBetween(0, 3)];
|
||||
if (names != null) {
|
||||
for (int x = 0; x < names.length; x++) {
|
||||
names[x] = randomAlphaOfLengthBetween(3, 10);
|
||||
}
|
||||
}
|
||||
getSettingsRequest.names(names);
|
||||
if (names != null && names.length > 0) {
|
||||
endpoint.add(String.join(",", names));
|
||||
}
|
||||
}
|
||||
|
||||
Request request = RequestConverters.getSettings(getSettingsRequest);
|
||||
|
||||
assertThat(endpoint.toString(), equalTo(request.getEndpoint()));
|
||||
assertThat(request.getParameters(), equalTo(expectedParams));
|
||||
assertThat(request.getMethod(), equalTo(HttpGet.METHOD_NAME));
|
||||
assertThat(request.getEntity(), nullValue());
|
||||
}
|
||||
|
||||
public void testDeleteIndexEmptyIndices() {
|
||||
String[] indices = randomBoolean() ? null : Strings.EMPTY_ARRAY;
|
||||
ActionRequestValidationException validationException = new DeleteIndexRequest(indices).validate();
|
||||
|
@ -50,6 +50,8 @@ import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
|
||||
import org.elasticsearch.action.admin.indices.rollover.RolloverResponse;
|
||||
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
|
||||
import org.elasticsearch.action.admin.indices.shrink.ResizeResponse;
|
||||
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
|
||||
@ -775,6 +777,119 @@ public class IndicesClientDocumentationIT extends ESRestHighLevelClientTestCase
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetSettings() throws Exception {
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
|
||||
{
|
||||
Settings settings = Settings.builder().put("number_of_shards", 3).build();
|
||||
CreateIndexResponse createIndexResponse = client.indices().create(new CreateIndexRequest("index", settings));
|
||||
assertTrue(createIndexResponse.isAcknowledged());
|
||||
}
|
||||
|
||||
// tag::get-settings-request
|
||||
GetSettingsRequest request = new GetSettingsRequest().indices("index");
|
||||
// end::get-settings-request
|
||||
|
||||
// tag::get-settings-request-names
|
||||
request.names("index.number_of_shards"); // <1>
|
||||
// end::get-settings-request-names
|
||||
|
||||
// tag::get-settings-request-indicesOptions
|
||||
request.indicesOptions(IndicesOptions.lenientExpandOpen()); // <1>
|
||||
// end::get-settings-request-indicesOptions
|
||||
|
||||
// tag::get-settings-execute
|
||||
GetSettingsResponse getSettingsResponse = client.indices().getSettings(request);
|
||||
// end::get-settings-execute
|
||||
|
||||
// tag::get-settings-response
|
||||
String numberOfShardsString = getSettingsResponse.getSetting("index", "index.number_of_shards"); // <1>
|
||||
Settings indexSettings = getSettingsResponse.getIndexToSettings().get("index"); // <2>
|
||||
Integer numberOfShards = indexSettings.getAsInt("index.number_of_shards", null); // <3>
|
||||
// end::get-settings-response
|
||||
|
||||
assertEquals("3", numberOfShardsString);
|
||||
assertEquals(Integer.valueOf(3), numberOfShards);
|
||||
|
||||
assertNull("refresh_interval returned but was never set!",
|
||||
getSettingsResponse.getSetting("index", "index.refresh_interval"));
|
||||
|
||||
// tag::get-settings-execute-listener
|
||||
ActionListener<GetSettingsResponse> listener =
|
||||
new ActionListener<GetSettingsResponse>() {
|
||||
@Override
|
||||
public void onResponse(GetSettingsResponse GetSettingsResponse) {
|
||||
// <1>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
// <2>
|
||||
}
|
||||
};
|
||||
// end::get-settings-execute-listener
|
||||
|
||||
// Replace the empty listener by a blocking listener in test
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
listener = new LatchedActionListener<>(listener, latch);
|
||||
|
||||
// tag::get-settings-execute-async
|
||||
client.indices().getSettingsAsync(request, listener); // <1>
|
||||
// end::get-settings-execute-async
|
||||
|
||||
assertTrue(latch.await(30L, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
public void testGetSettingsWithDefaults() throws Exception {
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
|
||||
{
|
||||
Settings settings = Settings.builder().put("number_of_shards", 3).build();
|
||||
CreateIndexResponse createIndexResponse = client.indices().create(new CreateIndexRequest("index", settings));
|
||||
assertTrue(createIndexResponse.isAcknowledged());
|
||||
}
|
||||
|
||||
GetSettingsRequest request = new GetSettingsRequest().indices("index");
|
||||
request.indicesOptions(IndicesOptions.lenientExpandOpen());
|
||||
|
||||
// tag::get-settings-request-include-defaults
|
||||
request.includeDefaults(true); // <1>
|
||||
// end::get-settings-request-include-defaults
|
||||
|
||||
GetSettingsResponse getSettingsResponse = client.indices().getSettings(request);
|
||||
String numberOfShardsString = getSettingsResponse.getSetting("index", "index.number_of_shards");
|
||||
Settings indexSettings = getSettingsResponse.getIndexToSettings().get("index");
|
||||
Integer numberOfShards = indexSettings.getAsInt("index.number_of_shards", null);
|
||||
|
||||
// tag::get-settings-defaults-response
|
||||
String refreshInterval = getSettingsResponse.getSetting("index", "index.refresh_interval"); // <1>
|
||||
Settings indexDefaultSettings = getSettingsResponse.getIndexToDefaultSettings().get("index"); // <2>
|
||||
// end::get-settings-defaults-response
|
||||
|
||||
assertEquals("3", numberOfShardsString);
|
||||
assertEquals(Integer.valueOf(3), numberOfShards);
|
||||
assertNotNull("with defaults enabled we should get a value for refresh_interval!", refreshInterval);
|
||||
|
||||
assertEquals(refreshInterval, indexDefaultSettings.get("index.refresh_interval"));
|
||||
ActionListener<GetSettingsResponse> listener =
|
||||
new ActionListener<GetSettingsResponse>() {
|
||||
@Override
|
||||
public void onResponse(GetSettingsResponse GetSettingsResponse) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
}
|
||||
};
|
||||
|
||||
// Replace the empty listener by a blocking listener in test
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
listener = new LatchedActionListener<>(listener, latch);
|
||||
|
||||
client.indices().getSettingsAsync(request, listener);
|
||||
assertTrue(latch.await(30L, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
public void testForceMergeIndex() throws Exception {
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
|
||||
|
96
docs/java-rest/high-level/indices/get_settings.asciidoc
Normal file
96
docs/java-rest/high-level/indices/get_settings.asciidoc
Normal file
@ -0,0 +1,96 @@
|
||||
[[java-rest-high-get-settings]]
|
||||
=== Get Settings API
|
||||
|
||||
[[java-rest-high-get-settings-request]]
|
||||
==== Get Settings Request
|
||||
|
||||
A `GetSettingsRequest` requires one or more `index` arguments:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-settings-request]
|
||||
--------------------------------------------------
|
||||
<1> The index whose settings we should retrieve
|
||||
|
||||
==== Optional arguments
|
||||
The following arguments can optionally be provided:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-settings-request-names]
|
||||
--------------------------------------------------
|
||||
<1> One or more settings that be the only settings retrieved. If unset, all settings will be retrieved
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-settings-request-include-defaults]
|
||||
--------------------------------------------------
|
||||
<1> If true, defaults will be returned for settings not explicitly set on the index
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-settings-request-indicesOptions]
|
||||
--------------------------------------------------
|
||||
<1> Setting `IndicesOptions` controls how unavailable indices are resolved and
|
||||
how wildcard expressions are expanded
|
||||
|
||||
[[java-rest-high-get-settings-sync]]
|
||||
==== Synchronous Execution
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-settings-execute]
|
||||
--------------------------------------------------
|
||||
|
||||
[[java-rest-high-get-settings-async]]
|
||||
==== Asynchronous Execution
|
||||
|
||||
The asynchronous execution of a Get Settings request requires both the `GetSettingsRequest`
|
||||
instance and an `ActionListener` instance to be passed to the asynchronous
|
||||
method:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-settings-execute-async]
|
||||
--------------------------------------------------
|
||||
<1> The `GetSettingsRequest` to execute and the `ActionListener` to use when
|
||||
the execution completes
|
||||
|
||||
The asynchronous method does not block and returns immediately. Once it is
|
||||
completed the `ActionListener` is called back using the `onResponse` method
|
||||
if the execution successfully completed or using the `onFailure` method if
|
||||
it failed.
|
||||
|
||||
A typical listener for `GetSettingsResponse` looks like:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-settings-execute-listener]
|
||||
--------------------------------------------------
|
||||
<1> Called when the execution is successfully completed. The response is
|
||||
provided as an argument
|
||||
<2> Called in case of failure. The raised exception is provided as an argument
|
||||
|
||||
[[java-rest-high-get-settings-response]]
|
||||
==== Get Settings Response
|
||||
|
||||
The returned `GetSettingsResponse` allows to retrieve information about the
|
||||
executed operation as follows:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-settings-response]
|
||||
--------------------------------------------------
|
||||
<1> We can retrieve the setting value for a particular index directly from the response as a string
|
||||
<2> We can also retrieve the Settings object for a particular index for further examination
|
||||
<3> The returned Settings object provides convenience methods for non String types
|
||||
|
||||
If the `includeDefaults` flag was set to true in the `GetSettingsRequest`, the
|
||||
behavior of `GetSettingsResponse` will differ somewhat.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-settings-defaults-response]
|
||||
--------------------------------------------------
|
||||
<1> Individual default setting values may be retrieved directly from the `GetSettingsResponse`
|
||||
<2> We may retrieve a Settings object for an index that contains those settings with default values
|
@ -69,6 +69,7 @@ Index Management::
|
||||
* <<java-rest-high-force-merge>>
|
||||
* <<java-rest-high-rollover-index>>
|
||||
* <<java-rest-high-indices-put-settings>>
|
||||
* <<java-rest-high-get-settings>>
|
||||
|
||||
Mapping Management::
|
||||
* <<java-rest-high-put-mapping>>
|
||||
@ -93,6 +94,7 @@ include::indices/put_mapping.asciidoc[]
|
||||
include::indices/update_aliases.asciidoc[]
|
||||
include::indices/exists_alias.asciidoc[]
|
||||
include::indices/put_settings.asciidoc[]
|
||||
include::indices/get_settings.asciidoc[]
|
||||
|
||||
== Cluster APIs
|
||||
|
||||
|
@ -16,6 +16,10 @@
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"master_timeout": {
|
||||
"type": "time",
|
||||
"description": "Specify timeout for connection to master"
|
||||
},
|
||||
"ignore_unavailable": {
|
||||
"type" : "boolean",
|
||||
"description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
|
||||
|
@ -576,7 +576,7 @@ public class ActionModule extends AbstractModule {
|
||||
registerHandler.accept(new RestOpenIndexAction(settings, restController));
|
||||
|
||||
registerHandler.accept(new RestUpdateSettingsAction(settings, restController));
|
||||
registerHandler.accept(new RestGetSettingsAction(settings, restController, indexScopedSettings, settingsFilter));
|
||||
registerHandler.accept(new RestGetSettingsAction(settings, restController));
|
||||
|
||||
registerHandler.accept(new RestAnalyzeAction(settings, restController));
|
||||
registerHandler.accept(new RestGetIndexTemplateAction(settings, restController));
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package org.elasticsearch.action.admin.indices.settings.get;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
import org.elasticsearch.action.IndicesRequest;
|
||||
import org.elasticsearch.action.ValidateActions;
|
||||
@ -29,6 +30,8 @@ import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
public class GetSettingsRequest extends MasterNodeReadRequest<GetSettingsRequest> implements IndicesRequest.Replaceable {
|
||||
|
||||
@ -36,6 +39,7 @@ public class GetSettingsRequest extends MasterNodeReadRequest<GetSettingsRequest
|
||||
private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, true, true, true);
|
||||
private String[] names = Strings.EMPTY_ARRAY;
|
||||
private boolean humanReadable = false;
|
||||
private boolean includeDefaults = false;
|
||||
|
||||
@Override
|
||||
public GetSettingsRequest indices(String... indices) {
|
||||
@ -48,6 +52,16 @@ public class GetSettingsRequest extends MasterNodeReadRequest<GetSettingsRequest
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* When include_defaults is set, return default values which are normally suppressed.
|
||||
* This flag is specific to the rest client.
|
||||
*/
|
||||
public GetSettingsRequest includeDefaults(boolean includeDefaults) {
|
||||
this.includeDefaults = includeDefaults;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public GetSettingsRequest() {
|
||||
}
|
||||
|
||||
@ -57,6 +71,9 @@ public class GetSettingsRequest extends MasterNodeReadRequest<GetSettingsRequest
|
||||
indicesOptions = IndicesOptions.readIndicesOptions(in);
|
||||
names = in.readStringArray();
|
||||
humanReadable = in.readBoolean();
|
||||
if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
|
||||
includeDefaults = in.readBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -66,6 +83,9 @@ public class GetSettingsRequest extends MasterNodeReadRequest<GetSettingsRequest
|
||||
indicesOptions.writeIndicesOptions(out);
|
||||
out.writeStringArray(names);
|
||||
out.writeBoolean(humanReadable);
|
||||
if (out.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
|
||||
out.writeBoolean(includeDefaults);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -96,6 +116,10 @@ public class GetSettingsRequest extends MasterNodeReadRequest<GetSettingsRequest
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean includeDefaults() {
|
||||
return includeDefaults;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionRequestValidationException validate() {
|
||||
ActionRequestValidationException validationException = null;
|
||||
@ -109,4 +133,24 @@ public class GetSettingsRequest extends MasterNodeReadRequest<GetSettingsRequest
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
GetSettingsRequest that = (GetSettingsRequest) o;
|
||||
return humanReadable == that.humanReadable &&
|
||||
includeDefaults == that.includeDefaults &&
|
||||
Arrays.equals(indices, that.indices) &&
|
||||
Objects.equals(indicesOptions, that.indicesOptions) &&
|
||||
Arrays.equals(names, that.names);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = Objects.hash(indicesOptions, humanReadable, includeDefaults);
|
||||
result = 31 * result + Arrays.hashCode(indices);
|
||||
result = 31 * result + Arrays.hashCode(names);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -21,32 +21,83 @@ package org.elasticsearch.action.admin.indices.settings.get;
|
||||
|
||||
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentParserUtils;
|
||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.CharBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class GetSettingsResponse extends ActionResponse {
|
||||
public class GetSettingsResponse extends ActionResponse implements ToXContentObject {
|
||||
|
||||
private ImmutableOpenMap<String, Settings> indexToSettings = ImmutableOpenMap.of();
|
||||
private ImmutableOpenMap<String, Settings> indexToDefaultSettings = ImmutableOpenMap.of();
|
||||
|
||||
public GetSettingsResponse(ImmutableOpenMap<String, Settings> indexToSettings) {
|
||||
public GetSettingsResponse(ImmutableOpenMap<String, Settings> indexToSettings,
|
||||
ImmutableOpenMap<String, Settings> indexToDefaultSettings) {
|
||||
this.indexToSettings = indexToSettings;
|
||||
this.indexToDefaultSettings = indexToDefaultSettings;
|
||||
}
|
||||
|
||||
GetSettingsResponse() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of index name to {@link Settings} object. The returned {@link Settings}
|
||||
* objects contain only those settings explicitly set on a given index. Any settings
|
||||
* taking effect as defaults must be accessed via {@link #getIndexToDefaultSettings()}.
|
||||
*/
|
||||
public ImmutableOpenMap<String, Settings> getIndexToSettings() {
|
||||
return indexToSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the originating {@link GetSettingsRequest} object was configured to include
|
||||
* defaults, this will contain a mapping of index name to {@link Settings} objects.
|
||||
* The returned {@link Settings} objects will contain only those settings taking
|
||||
* effect as defaults. Any settings explicitly set on the index will be available
|
||||
* via {@link #getIndexToSettings()}.
|
||||
* See also {@link GetSettingsRequest#includeDefaults(boolean)}
|
||||
*/
|
||||
public ImmutableOpenMap<String, Settings> getIndexToDefaultSettings() {
|
||||
return indexToDefaultSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string value for the specified index and setting. If the includeDefaults
|
||||
* flag was not set or set to false on the GetSettingsRequest, this method will only
|
||||
* return a value where the setting was explicitly set on the index. If the includeDefaults
|
||||
* flag was set to true on the GetSettingsRequest, this method will fall back to return the default
|
||||
* value if the setting was not explicitly set.
|
||||
*/
|
||||
public String getSetting(String index, String setting) {
|
||||
Settings settings = indexToSettings.get(index);
|
||||
if (setting != null) {
|
||||
return settings.get(setting);
|
||||
if (settings != null && settings.hasValue(setting)) {
|
||||
return settings.get(setting);
|
||||
} else {
|
||||
Settings defaultSettings = indexToDefaultSettings.get(index);
|
||||
if (defaultSettings != null) {
|
||||
return defaultSettings.get(setting);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@ -55,12 +106,22 @@ public class GetSettingsResponse extends ActionResponse {
|
||||
@Override
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
super.readFrom(in);
|
||||
int size = in.readVInt();
|
||||
ImmutableOpenMap.Builder<String, Settings> builder = ImmutableOpenMap.builder();
|
||||
for (int i = 0; i < size; i++) {
|
||||
builder.put(in.readString(), Settings.readSettingsFromStream(in));
|
||||
|
||||
int settingsSize = in.readVInt();
|
||||
ImmutableOpenMap.Builder<String, Settings> settingsBuilder = ImmutableOpenMap.builder();
|
||||
for (int i = 0; i < settingsSize; i++) {
|
||||
settingsBuilder.put(in.readString(), Settings.readSettingsFromStream(in));
|
||||
}
|
||||
indexToSettings = builder.build();
|
||||
ImmutableOpenMap.Builder<String, Settings> defaultSettingsBuilder = ImmutableOpenMap.builder();
|
||||
|
||||
if (in.getVersion().onOrAfter(org.elasticsearch.Version.V_7_0_0_alpha1)) {
|
||||
int defaultSettingsSize = in.readVInt();
|
||||
for (int i = 0; i < defaultSettingsSize ; i++) {
|
||||
defaultSettingsBuilder.put(in.readString(), Settings.readSettingsFromStream(in));
|
||||
}
|
||||
}
|
||||
indexToSettings = settingsBuilder.build();
|
||||
indexToDefaultSettings = defaultSettingsBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,5 +132,121 @@ public class GetSettingsResponse extends ActionResponse {
|
||||
out.writeString(cursor.key);
|
||||
Settings.writeSettingsToStream(cursor.value, out);
|
||||
}
|
||||
if (out.getVersion().onOrAfter(org.elasticsearch.Version.V_7_0_0_alpha1)) {
|
||||
out.writeVInt(indexToDefaultSettings.size());
|
||||
for (ObjectObjectCursor<String, Settings> cursor : indexToDefaultSettings) {
|
||||
out.writeString(cursor.key);
|
||||
Settings.writeSettingsToStream(cursor.value, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseSettingsField(XContentParser parser, String currentIndexName, Map<String, Settings> indexToSettings,
|
||||
Map<String, Settings> indexToDefaultSettings) throws IOException {
|
||||
|
||||
if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
||||
switch (parser.currentName()) {
|
||||
case "settings":
|
||||
indexToSettings.put(currentIndexName, Settings.fromXContent(parser));
|
||||
break;
|
||||
case "defaults":
|
||||
indexToDefaultSettings.put(currentIndexName, Settings.fromXContent(parser));
|
||||
break;
|
||||
default:
|
||||
parser.skipChildren();
|
||||
}
|
||||
} else if (parser.currentToken() == XContentParser.Token.START_ARRAY) {
|
||||
parser.skipChildren();
|
||||
}
|
||||
parser.nextToken();
|
||||
}
|
||||
|
||||
private static void parseIndexEntry(XContentParser parser, Map<String, Settings> indexToSettings,
|
||||
Map<String, Settings> indexToDefaultSettings) throws IOException {
|
||||
String indexName = parser.currentName();
|
||||
parser.nextToken();
|
||||
while (!parser.isClosed() && parser.currentToken() != XContentParser.Token.END_OBJECT) {
|
||||
parseSettingsField(parser, indexName, indexToSettings, indexToDefaultSettings);
|
||||
}
|
||||
}
|
||||
public static GetSettingsResponse fromXContent(XContentParser parser) throws IOException {
|
||||
HashMap<String, Settings> indexToSettings = new HashMap<>();
|
||||
HashMap<String, Settings> indexToDefaultSettings = new HashMap<>();
|
||||
|
||||
if (parser.currentToken() == null) {
|
||||
parser.nextToken();
|
||||
}
|
||||
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.currentToken(), parser::getTokenLocation);
|
||||
parser.nextToken();
|
||||
|
||||
while (!parser.isClosed()) {
|
||||
if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
||||
//we must assume this is an index entry
|
||||
parseIndexEntry(parser, indexToSettings, indexToDefaultSettings);
|
||||
} else if (parser.currentToken() == XContentParser.Token.START_ARRAY) {
|
||||
parser.skipChildren();
|
||||
} else {
|
||||
parser.nextToken();
|
||||
}
|
||||
}
|
||||
|
||||
ImmutableOpenMap<String, Settings> settingsMap = ImmutableOpenMap.<String, Settings>builder().putAll(indexToSettings).build();
|
||||
ImmutableOpenMap<String, Settings> defaultSettingsMap =
|
||||
ImmutableOpenMap.<String, Settings>builder().putAll(indexToDefaultSettings).build();
|
||||
|
||||
return new GetSettingsResponse(settingsMap, defaultSettingsMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
XContentBuilder builder = new XContentBuilder(JsonXContent.jsonXContent, baos);
|
||||
toXContent(builder, ToXContent.EMPTY_PARAMS, false);
|
||||
return Strings.toString(builder);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e); //should not be possible here
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
return toXContent(builder, params, indexToDefaultSettings.isEmpty());
|
||||
}
|
||||
|
||||
private XContentBuilder toXContent(XContentBuilder builder, Params params, boolean omitEmptySettings) throws IOException {
|
||||
builder.startObject();
|
||||
for (ObjectObjectCursor<String, Settings> cursor : getIndexToSettings()) {
|
||||
// no settings, jump over it to shorten the response data
|
||||
if (omitEmptySettings && cursor.value.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
builder.startObject(cursor.key);
|
||||
builder.startObject("settings");
|
||||
cursor.value.toXContent(builder, params);
|
||||
builder.endObject();
|
||||
if (indexToDefaultSettings.isEmpty() == false) {
|
||||
builder.startObject("defaults");
|
||||
indexToDefaultSettings.get(cursor.key).toXContent(builder, params);
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
GetSettingsResponse that = (GetSettingsResponse) o;
|
||||
return Objects.equals(indexToSettings, that.indexToSettings) &&
|
||||
Objects.equals(indexToDefaultSettings, that.indexToDefaultSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(indexToSettings, indexToDefaultSettings);
|
||||
}
|
||||
}
|
||||
|
@ -37,19 +37,23 @@ import org.elasticsearch.common.util.CollectionUtils;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
import org.elasticsearch.common.settings.IndexScopedSettings;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class TransportGetSettingsAction extends TransportMasterNodeReadAction<GetSettingsRequest, GetSettingsResponse> {
|
||||
|
||||
private final SettingsFilter settingsFilter;
|
||||
private final IndexScopedSettings indexScopedSettings;
|
||||
|
||||
|
||||
@Inject
|
||||
public TransportGetSettingsAction(Settings settings, TransportService transportService, ClusterService clusterService,
|
||||
ThreadPool threadPool, SettingsFilter settingsFilter, ActionFilters actionFilters,
|
||||
IndexNameExpressionResolver indexNameExpressionResolver) {
|
||||
IndexNameExpressionResolver indexNameExpressionResolver, IndexScopedSettings indexedScopedSettings) {
|
||||
super(settings, GetSettingsAction.NAME, transportService, clusterService, threadPool, actionFilters, GetSettingsRequest::new, indexNameExpressionResolver);
|
||||
this.settingsFilter = settingsFilter;
|
||||
this.indexScopedSettings = indexedScopedSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -69,25 +73,39 @@ public class TransportGetSettingsAction extends TransportMasterNodeReadAction<Ge
|
||||
return new GetSettingsResponse();
|
||||
}
|
||||
|
||||
private static boolean isFilteredRequest(GetSettingsRequest request) {
|
||||
return CollectionUtils.isEmpty(request.names()) == false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void masterOperation(GetSettingsRequest request, ClusterState state, ActionListener<GetSettingsResponse> listener) {
|
||||
Index[] concreteIndices = indexNameExpressionResolver.concreteIndices(state, request);
|
||||
ImmutableOpenMap.Builder<String, Settings> indexToSettingsBuilder = ImmutableOpenMap.builder();
|
||||
ImmutableOpenMap.Builder<String, Settings> indexToDefaultSettingsBuilder = ImmutableOpenMap.builder();
|
||||
for (Index concreteIndex : concreteIndices) {
|
||||
IndexMetaData indexMetaData = state.getMetaData().index(concreteIndex);
|
||||
if (indexMetaData == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Settings settings = settingsFilter.filter(indexMetaData.getSettings());
|
||||
Settings indexSettings = settingsFilter.filter(indexMetaData.getSettings());
|
||||
if (request.humanReadable()) {
|
||||
settings = IndexMetaData.addHumanReadableSettings(settings);
|
||||
indexSettings = IndexMetaData.addHumanReadableSettings(indexSettings);
|
||||
}
|
||||
if (CollectionUtils.isEmpty(request.names()) == false) {
|
||||
settings = settings.filter(k -> Regex.simpleMatch(request.names(), k));
|
||||
|
||||
if (isFilteredRequest(request)) {
|
||||
indexSettings = indexSettings.filter(k -> Regex.simpleMatch(request.names(), k));
|
||||
}
|
||||
|
||||
indexToSettingsBuilder.put(concreteIndex.getName(), indexSettings);
|
||||
if (request.includeDefaults()) {
|
||||
Settings defaultSettings = settingsFilter.filter(indexScopedSettings.diff(indexSettings, Settings.EMPTY));
|
||||
if (isFilteredRequest(request)) {
|
||||
defaultSettings = defaultSettings.filter(k -> Regex.simpleMatch(request.names(), k));
|
||||
}
|
||||
indexToDefaultSettingsBuilder.put(concreteIndex.getName(), defaultSettings);
|
||||
}
|
||||
indexToSettingsBuilder.put(concreteIndex.getName(), settings);
|
||||
}
|
||||
listener.onResponse(new GetSettingsResponse(indexToSettingsBuilder.build()));
|
||||
listener.onResponse(new GetSettingsResponse(indexToSettingsBuilder.build(), indexToDefaultSettingsBuilder.build()));
|
||||
}
|
||||
}
|
||||
|
@ -44,18 +44,12 @@ import static org.elasticsearch.rest.RestStatus.OK;
|
||||
|
||||
public class RestGetSettingsAction extends BaseRestHandler {
|
||||
|
||||
private final IndexScopedSettings indexScopedSettings;
|
||||
private final SettingsFilter settingsFilter;
|
||||
|
||||
public RestGetSettingsAction(Settings settings, RestController controller, IndexScopedSettings indexScopedSettings,
|
||||
final SettingsFilter settingsFilter) {
|
||||
public RestGetSettingsAction(Settings settings, RestController controller) {
|
||||
super(settings);
|
||||
this.indexScopedSettings = indexScopedSettings;
|
||||
controller.registerHandler(GET, "/_settings/{name}", this);
|
||||
controller.registerHandler(GET, "/{index}/_settings", this);
|
||||
controller.registerHandler(GET, "/{index}/_settings/{name}", this);
|
||||
controller.registerHandler(GET, "/{index}/_setting/{name}", this);
|
||||
this.settingsFilter = settingsFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -73,31 +67,16 @@ public class RestGetSettingsAction extends BaseRestHandler {
|
||||
.indices(Strings.splitStringByCommaToArray(request.param("index")))
|
||||
.indicesOptions(IndicesOptions.fromRequest(request, IndicesOptions.strictExpandOpen()))
|
||||
.humanReadable(request.hasParam("human"))
|
||||
.includeDefaults(renderDefaults)
|
||||
.names(names);
|
||||
getSettingsRequest.local(request.paramAsBoolean("local", getSettingsRequest.local()));
|
||||
getSettingsRequest.masterNodeTimeout(request.paramAsTime("master_timeout", getSettingsRequest.masterNodeTimeout()));
|
||||
|
||||
return channel -> client.admin().indices().getSettings(getSettingsRequest, new RestBuilderListener<GetSettingsResponse>(channel) {
|
||||
|
||||
@Override
|
||||
public RestResponse buildResponse(GetSettingsResponse getSettingsResponse, XContentBuilder builder) throws Exception {
|
||||
builder.startObject();
|
||||
for (ObjectObjectCursor<String, Settings> cursor : getSettingsResponse.getIndexToSettings()) {
|
||||
// no settings, jump over it to shorten the response data
|
||||
if (cursor.value.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
builder.startObject(cursor.key);
|
||||
builder.startObject("settings");
|
||||
cursor.value.toXContent(builder, request);
|
||||
builder.endObject();
|
||||
if (renderDefaults) {
|
||||
builder.startObject("defaults");
|
||||
settingsFilter.filter(indexScopedSettings.diff(cursor.value, settings)).toXContent(builder, request);
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
getSettingsResponse.toXContent(builder, request);
|
||||
return new BytesRestResponse(OK, builder);
|
||||
}
|
||||
});
|
||||
|
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.action.admin.indices.settings.get;
|
||||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.IndicesRequest;
|
||||
import org.elasticsearch.action.support.ActionFilters;
|
||||
import org.elasticsearch.action.support.replication.ClusterStateCreationUtils;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.settings.IndexScopedSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsFilter;
|
||||
import org.elasticsearch.common.settings.SettingsModule;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.transport.CapturingTransport;
|
||||
import org.elasticsearch.threadpool.TestThreadPool;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.elasticsearch.test.ClusterServiceUtils.createClusterService;
|
||||
|
||||
public class GetSettingsActionTests extends ESTestCase {
|
||||
|
||||
private TransportService transportService;
|
||||
private ClusterService clusterService;
|
||||
private ThreadPool threadPool;
|
||||
private SettingsFilter settingsFilter;
|
||||
private final String indexName = "test_index";
|
||||
|
||||
private TestTransportGetSettingsAction getSettingsAction;
|
||||
|
||||
class TestTransportGetSettingsAction extends TransportGetSettingsAction {
|
||||
TestTransportGetSettingsAction() {
|
||||
super(Settings.EMPTY, GetSettingsActionTests.this.transportService, GetSettingsActionTests.this.clusterService,
|
||||
GetSettingsActionTests.this.threadPool, settingsFilter, new ActionFilters(Collections.emptySet()),
|
||||
new Resolver(Settings.EMPTY), IndexScopedSettings.DEFAULT_SCOPED_SETTINGS);
|
||||
}
|
||||
@Override
|
||||
protected void masterOperation(GetSettingsRequest request, ClusterState state, ActionListener<GetSettingsResponse> listener) {
|
||||
ClusterState stateWithIndex = ClusterStateCreationUtils.state(indexName, 1, 1);
|
||||
super.masterOperation(request, stateWithIndex, listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
settingsFilter = new SettingsModule(Settings.EMPTY, Collections.emptyList(), Collections.emptyList()).getSettingsFilter();
|
||||
threadPool = new TestThreadPool("GetSettingsActionTests");
|
||||
clusterService = createClusterService(threadPool);
|
||||
CapturingTransport capturingTransport = new CapturingTransport();
|
||||
transportService = new TransportService(clusterService.getSettings(), capturingTransport, threadPool,
|
||||
TransportService.NOOP_TRANSPORT_INTERCEPTOR,
|
||||
boundAddress -> clusterService.localNode(), null, Collections.emptySet());
|
||||
transportService.start();
|
||||
transportService.acceptIncomingRequests();
|
||||
getSettingsAction = new GetSettingsActionTests.TestTransportGetSettingsAction();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
ThreadPool.terminate(threadPool, 30, TimeUnit.SECONDS);
|
||||
threadPool = null;
|
||||
clusterService.close();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testIncludeDefaults() {
|
||||
GetSettingsRequest noDefaultsRequest = new GetSettingsRequest().indices(indexName);
|
||||
getSettingsAction.execute(null, noDefaultsRequest, ActionListener.wrap(noDefaultsResponse -> {
|
||||
assertNull("index.refresh_interval should be null as it was never set", noDefaultsResponse.getSetting(indexName,
|
||||
"index.refresh_interval"));
|
||||
}, exception -> {
|
||||
throw new AssertionError(exception);
|
||||
}));
|
||||
|
||||
GetSettingsRequest defaultsRequest = new GetSettingsRequest().indices(indexName).includeDefaults(true);
|
||||
|
||||
getSettingsAction.execute(null, defaultsRequest, ActionListener.wrap(defaultsResponse -> {
|
||||
assertNotNull("index.refresh_interval should be set as we are including defaults", defaultsResponse.getSetting(indexName,
|
||||
"index.refresh_interval"));
|
||||
}, exception -> {
|
||||
throw new AssertionError(exception);
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
public void testIncludeDefaultsWithFiltering() {
|
||||
GetSettingsRequest defaultsRequest = new GetSettingsRequest().indices(indexName).includeDefaults(true)
|
||||
.names("index.refresh_interval");
|
||||
getSettingsAction.execute(null, defaultsRequest, ActionListener.wrap(defaultsResponse -> {
|
||||
assertNotNull("index.refresh_interval should be set as we are including defaults", defaultsResponse.getSetting(indexName,
|
||||
"index.refresh_interval"));
|
||||
assertNull("index.number_of_shards should be null as this query is filtered",
|
||||
defaultsResponse.getSetting(indexName, "index.number_of_shards"));
|
||||
assertNull("index.warmer.enabled should be null as this query is filtered",
|
||||
defaultsResponse.getSetting(indexName, "index.warmer.enabled"));
|
||||
}, exception -> {
|
||||
throw new AssertionError(exception);
|
||||
}));
|
||||
}
|
||||
|
||||
static class Resolver extends IndexNameExpressionResolver {
|
||||
Resolver(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] concreteIndexNames(ClusterState state, IndicesRequest request) {
|
||||
return request.indices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Index[] concreteIndices(ClusterState state, IndicesRequest request) {
|
||||
Index[] out = new Index[request.indices().length];
|
||||
for (int x = 0; x < out.length; x++) {
|
||||
out[x] = new Index(request.indices()[x], "_na_");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.action.admin.indices.settings.get;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
|
||||
public class GetSettingsRequestTests extends ESTestCase {
|
||||
private static final String TEST_622_REQUEST_BYTES = "ADwDAAEKdGVzdF9pbmRleA4BEHRlc3Rfc2V0dGluZ19rZXkB";
|
||||
private static final GetSettingsRequest TEST_622_REQUEST = new GetSettingsRequest()
|
||||
.indices("test_index")
|
||||
.names("test_setting_key")
|
||||
.humanReadable(true);
|
||||
private static final GetSettingsRequest TEST_700_REQUEST = new GetSettingsRequest()
|
||||
.includeDefaults(true)
|
||||
.humanReadable(true)
|
||||
.indices("test_index")
|
||||
.names("test_setting_key");
|
||||
|
||||
public void testSerdeRoundTrip() throws IOException {
|
||||
BytesStreamOutput bso = new BytesStreamOutput();
|
||||
TEST_700_REQUEST.writeTo(bso);
|
||||
|
||||
byte[] responseBytes = BytesReference.toBytes(bso.bytes());
|
||||
StreamInput si = StreamInput.wrap(responseBytes);
|
||||
GetSettingsRequest deserialized = new GetSettingsRequest(si);
|
||||
assertEquals(TEST_700_REQUEST, deserialized);
|
||||
}
|
||||
|
||||
public void testSerializeBackwardsCompatibility() throws IOException {
|
||||
BytesStreamOutput bso = new BytesStreamOutput();
|
||||
bso.setVersion(Version.V_6_2_2);
|
||||
TEST_700_REQUEST.writeTo(bso);
|
||||
|
||||
byte[] responseBytes = BytesReference.toBytes(bso.bytes());
|
||||
assertEquals(TEST_622_REQUEST_BYTES, Base64.getEncoder().encodeToString(responseBytes));
|
||||
}
|
||||
|
||||
public void testDeserializeBackwardsCompatibility() throws IOException {
|
||||
StreamInput si = StreamInput.wrap(Base64.getDecoder().decode(TEST_622_REQUEST_BYTES));
|
||||
si.setVersion(Version.V_6_2_2);
|
||||
GetSettingsRequest deserialized = new GetSettingsRequest(si);
|
||||
assertEquals(TEST_622_REQUEST, deserialized);
|
||||
}
|
||||
}
|
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.action.admin.indices.settings.get;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.settings.IndexScopedSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.RandomCreateIndexGenerator;
|
||||
import org.elasticsearch.test.AbstractStreamableXContentTestCase;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_REPLICAS;
|
||||
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS;
|
||||
import static org.elasticsearch.index.IndexSettings.INDEX_REFRESH_INTERVAL_SETTING;
|
||||
|
||||
public class GetSettingsResponseTests extends AbstractStreamableXContentTestCase<GetSettingsResponse> {
|
||||
|
||||
/*
|
||||
index.number_of_shards=2,index.number_of_replicas=1. The below base64'd bytes were generated by
|
||||
code from the 6.2.2 tag.
|
||||
*/
|
||||
private static final String TEST_6_2_2_RESPONSE_BYTES =
|
||||
"AQppbmRleF9uYW1lAhhpbmRleC5udW1iZXJfb2ZfcmVwbGljYXMAATEWaW5kZXgubnVtYmVyX29mX3NoYXJkcwABMg==";
|
||||
|
||||
/* This response object was generated using similar code to the code used to create the above bytes */
|
||||
private static final GetSettingsResponse TEST_6_2_2_RESPONSE_INSTANCE = getExpectedTest622Response();
|
||||
|
||||
@Override
|
||||
protected GetSettingsResponse createBlankInstance() {
|
||||
return new GetSettingsResponse();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GetSettingsResponse createTestInstance() {
|
||||
HashMap<String, Settings> indexToSettings = new HashMap<>();
|
||||
HashMap<String, Settings> indexToDefaultSettings = new HashMap<>();
|
||||
|
||||
IndexScopedSettings indexScopedSettings = IndexScopedSettings.DEFAULT_SCOPED_SETTINGS;
|
||||
|
||||
Set<String> indexNames = new HashSet<String>();
|
||||
int numIndices = randomIntBetween(1, 5);
|
||||
for (int x=0;x<numIndices;x++) {
|
||||
String indexName = randomAlphaOfLength(5);
|
||||
indexNames.add(indexName);
|
||||
}
|
||||
|
||||
for (String indexName : indexNames) {
|
||||
Settings.Builder builder = Settings.builder();
|
||||
builder.put(RandomCreateIndexGenerator.randomIndexSettings());
|
||||
/*
|
||||
We must ensure that *something* is in the settings response as we optimize away empty settings
|
||||
blocks in x content responses
|
||||
*/
|
||||
builder.put("index.refresh_interval", "1s");
|
||||
indexToSettings.put(indexName, builder.build());
|
||||
}
|
||||
ImmutableOpenMap<String, Settings> immutableIndexToSettings =
|
||||
ImmutableOpenMap.<String, Settings>builder().putAll(indexToSettings).build();
|
||||
|
||||
|
||||
if (randomBoolean()) {
|
||||
for (String indexName : indexToSettings.keySet()) {
|
||||
Settings defaultSettings = indexScopedSettings.diff(indexToSettings.get(indexName), Settings.EMPTY);
|
||||
indexToDefaultSettings.put(indexName, defaultSettings);
|
||||
}
|
||||
}
|
||||
|
||||
ImmutableOpenMap<String, Settings> immutableIndexToDefaultSettings =
|
||||
ImmutableOpenMap.<String, Settings>builder().putAll(indexToDefaultSettings).build();
|
||||
|
||||
return new GetSettingsResponse(immutableIndexToSettings, immutableIndexToDefaultSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GetSettingsResponse doParseInstance(XContentParser parser) throws IOException {
|
||||
return GetSettingsResponse.fromXContent(parser);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Predicate<String> getRandomFieldsExcludeFilter() {
|
||||
//we do not want to add new fields at the root (index-level), or inside settings blocks
|
||||
return f -> f.equals("") || f.contains(".settings") || f.contains(".defaults");
|
||||
}
|
||||
|
||||
private static GetSettingsResponse getExpectedTest622Response() {
|
||||
/* This is a fairly direct copy of the code used to generate the base64'd response above -- with the caveat that the constructor
|
||||
has been modified so that the code compiles on this version of elasticsearch
|
||||
*/
|
||||
HashMap<String, Settings> indexToSettings = new HashMap<>();
|
||||
Settings.Builder builder = Settings.builder();
|
||||
|
||||
builder.put(SETTING_NUMBER_OF_SHARDS, 2);
|
||||
builder.put(SETTING_NUMBER_OF_REPLICAS, 1);
|
||||
indexToSettings.put("index_name", builder.build());
|
||||
GetSettingsResponse response = new GetSettingsResponse(ImmutableOpenMap.<String, Settings>builder().putAll(indexToSettings).build
|
||||
(), ImmutableOpenMap.of());
|
||||
return response;
|
||||
}
|
||||
|
||||
private static GetSettingsResponse getResponseWithNewFields() {
|
||||
HashMap<String, Settings> indexToDefaultSettings = new HashMap<>();
|
||||
Settings.Builder builder = Settings.builder();
|
||||
|
||||
builder.put(INDEX_REFRESH_INTERVAL_SETTING.getKey(), "1s");
|
||||
indexToDefaultSettings.put("index_name", builder.build());
|
||||
ImmutableOpenMap<String, Settings> defaultsMap = ImmutableOpenMap.<String, Settings>builder().putAll(indexToDefaultSettings)
|
||||
.build();
|
||||
return new GetSettingsResponse(getExpectedTest622Response().getIndexToSettings(), defaultsMap);
|
||||
}
|
||||
|
||||
public void testCanDecode622Response() throws IOException {
|
||||
StreamInput si = StreamInput.wrap(Base64.getDecoder().decode(TEST_6_2_2_RESPONSE_BYTES));
|
||||
si.setVersion(Version.V_6_2_2);
|
||||
GetSettingsResponse response = new GetSettingsResponse();
|
||||
response.readFrom(si);
|
||||
|
||||
Assert.assertEquals(TEST_6_2_2_RESPONSE_INSTANCE, response);
|
||||
}
|
||||
|
||||
public void testCanOutput622Response() throws IOException {
|
||||
GetSettingsResponse responseWithExtraFields = getResponseWithNewFields();
|
||||
BytesStreamOutput bso = new BytesStreamOutput();
|
||||
bso.setVersion(Version.V_6_2_2);
|
||||
responseWithExtraFields.writeTo(bso);
|
||||
|
||||
String base64OfResponse = Base64.getEncoder().encodeToString(BytesReference.toBytes(bso.bytes()));
|
||||
|
||||
Assert.assertEquals(TEST_6_2_2_RESPONSE_BYTES, base64OfResponse);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user