Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Get Settings API support to java high-level rest client #29229

Merged
merged 15 commits into from
May 4, 2018
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
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;
Expand Down Expand Up @@ -265,6 +267,28 @@ public void flushAsync(FlushRequest flushRequest, ActionListener<FlushResponse>
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, Request::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, Request::getSettings, GetSettingsResponse::fromXContent,
listener, emptySet(), headers);
}

/**
* Force merge one or more indices using the Force Merge API
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
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;
Expand Down Expand Up @@ -593,6 +594,20 @@ static Request rollover(RolloverRequest rolloverRequest) throws IOException {
return new Request(HttpPost.METHOD_NAME, endpoint, params.getParams(), entity);
}

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();

Params params = Params.builder();
params.withIndicesOptions(getSettingsRequest.indicesOptions());
params.withLocal(getSettingsRequest.local());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are a few other params that we need to provide. Unfortunately it's all params that the transport client doesn't support but only the ES REST layer knows about. What we've been doing in these situations is add those params to the request object, and document that only the high-level REST client uses them. We've already encountered flat_settings for instance , and this one also has include_defaults.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I definitely understand adding include_defaults -- but is there a reason to include flat_settings -- won't the behavior of the java API be identical whether that flag is set or not ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right! I thought that somehow we would parse settings differently with or without the flag, but I have just tested it and nothing changes. So, ideally we would support this flag as it is part of our SPEC, but practically it does not do anything given how we parse settings back given that we use the Settings class. It would only make sense to expose this flag if we changed the way settings were returned. Thanks for pointing this out. I will also have the remove support for this flag from a couple of other API where we added it :(

params.withIncludeDefaults(getSettingsRequest.includeDefaults());
params.withMasterTimeout(getSettingsRequest.masterNodeTimeout());

String endpoint = endpoint(indices, "_settings", names);
return new Request(HttpGet.METHOD_NAME, endpoint, params.getParams(), null);
}

static Request indicesExist(GetIndexRequest request) {
// this can be called with no indices as argument by transport client, not via REST though
if (request.indices() == null || request.indices().length == 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
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;
Expand Down Expand Up @@ -189,6 +191,108 @@ public void testCreateIndex() throws IOException {
}
}

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());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for adding all these different tests, these are great to have!

public void testPutMapping() throws IOException {
{
// Add mappings to index
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
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;
Expand Down Expand Up @@ -75,6 +76,7 @@
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;
Expand Down Expand Up @@ -428,6 +430,52 @@ public void testDeleteIndex() {
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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we also test includeDefaults and names here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check


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));
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could you also randomly set it to the request when false, just to make sure? Maybe something like:

if (randomBoolean()) {
    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 = Request.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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
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;
Expand All @@ -58,7 +60,6 @@
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue;
Expand Down Expand Up @@ -777,6 +778,119 @@ public void onFailure(Exception e) {
}
}

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");
// tag::get-settings-request
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be an end tag ;)


// 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();

Expand Down
Loading