Add support for indices exists to REST high level client (#27384)

Relates to #27205
This commit is contained in:
Haris Osmanagić 2018-02-02 11:25:36 +01:00 committed by Luca Cavanna
parent 031415a5f6
commit 897ef458f3
11 changed files with 357 additions and 9 deletions

View File

@ -30,6 +30,7 @@ import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
@ -38,6 +39,7 @@ import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeResponse;
import java.io.IOException;
import java.util.Collections;
import static java.util.Collections.emptySet;
@ -211,6 +213,39 @@ public final class IndicesClient {
listener, emptySet(), headers);
}
/**
* Checks if the index (indices) exists or not.
* <p>
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-exists.html">
* Indices Exists API on elastic.co</a>
*/
public boolean exists(GetIndexRequest request, Header... headers) throws IOException {
return restHighLevelClient.performRequest(
request,
Request::indicesExist,
RestHighLevelClient::convertExistsResponse,
Collections.emptySet(),
headers
);
}
/**
* Asynchronously checks if the index (indices) exists or not.
* <p>
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-exists.html">
* Indices Exists API on elastic.co</a>
*/
public void existsAsync(GetIndexRequest request, ActionListener<Boolean> listener, Header... headers) {
restHighLevelClient.performRequestAsync(
request,
Request::indicesExist,
RestHighLevelClient::convertExistsResponse,
listener,
Collections.emptySet(),
headers
);
}
/**
* Shrinks an index using the Shrink Index API
* <p>

View File

@ -34,6 +34,7 @@ import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
@ -582,6 +583,17 @@ public final class Request {
return ContentType.create(xContentType.mediaTypeWithoutParameters(), (Charset) null);
}
static Request indicesExist(GetIndexRequest request) {
String endpoint = endpoint(request.indices(), Strings.EMPTY_ARRAY, "");
Params params = Params.builder();
params.withLocal(request.local());
params.withHuman(request.humanReadable());
params.withIndicesOptions(request.indicesOptions());
params.withFlatSettings(request.flatSettings());
params.withIncludeDefaults(request.includeDefaults());
return new Request(HttpHead.METHOD_NAME, endpoint, params.getParams(), null);
}
/**
* Utility class to build request's parameters map and centralize all parameter names.
*/
@ -729,8 +741,31 @@ public final class Request {
return this;
}
Params withHuman(boolean human) {
if (human) {
putParam("human", Boolean.toString(human));
}
return this;
}
Params withLocal(boolean local) {
putParam("local", Boolean.toString(local));
if (local) {
putParam("local", Boolean.toString(local));
}
return this;
}
Params withFlatSettings(boolean flatSettings) {
if (flatSettings) {
return putParam("flat_settings", Boolean.TRUE.toString());
}
return this;
}
Params withIncludeDefaults(boolean includeDefaults) {
if (includeDefaults) {
return putParam("include_defaults", Boolean.TRUE.toString());
}
return this;
}

View File

@ -34,6 +34,7 @@ import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
@ -58,6 +59,58 @@ import static org.hamcrest.Matchers.not;
public class IndicesClientIT extends ESRestHighLevelClientTestCase {
public void testIndicesExists() throws IOException {
// Index present
{
String indexName = "test_index_exists_index_present";
createIndex(indexName, Settings.EMPTY);
GetIndexRequest request = new GetIndexRequest();
request.indices(indexName);
boolean response = execute(
request,
highLevelClient().indices()::exists,
highLevelClient().indices()::existsAsync
);
assertTrue(response);
}
// Index doesn't exist
{
String indexName = "non_existent_index";
GetIndexRequest request = new GetIndexRequest();
request.indices(indexName);
boolean response = execute(
request,
highLevelClient().indices()::exists,
highLevelClient().indices()::existsAsync
);
assertFalse(response);
}
// One index exists, one doesn't
{
String existingIndex = "apples";
createIndex(existingIndex, Settings.EMPTY);
String nonExistentIndex = "oranges";
GetIndexRequest request = new GetIndexRequest();
request.indices(existingIndex, nonExistentIndex);
boolean response = execute(
request,
highLevelClient().indices()::exists,
highLevelClient().indices()::existsAsync
);
assertFalse(response);
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
public void testCreateIndex() throws IOException {
{

View File

@ -36,6 +36,7 @@ import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
@ -55,6 +56,7 @@ import org.elasticsearch.action.support.ActiveShardCount;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.support.master.AcknowledgedRequest;
import org.elasticsearch.action.support.master.MasterNodeReadRequest;
import org.elasticsearch.action.support.master.MasterNodeRequest;
import org.elasticsearch.action.support.replication.ReplicationRequest;
import org.elasticsearch.action.update.UpdateRequest;
@ -262,6 +264,26 @@ public class RequestTests extends ESTestCase {
getAndExistsTest(Request::exists, HttpHead.METHOD_NAME);
}
public void testIndicesExist() {
String[] indices = randomIndicesNames(1, 10);
GetIndexRequest getIndexRequest = new GetIndexRequest().indices(indices);
Map<String, String> expectedParams = new HashMap<>();
setRandomIndicesOptions(getIndexRequest::indicesOptions, getIndexRequest::indicesOptions, expectedParams);
setRandomLocal(getIndexRequest, expectedParams);
setRandomFlatSettings(getIndexRequest, expectedParams);
setRandomHumanReadable(getIndexRequest, expectedParams);
setRandomIncludeDefaults(getIndexRequest, expectedParams);
final Request request = Request.indicesExist(getIndexRequest);
assertEquals(HttpHead.METHOD_NAME, request.getMethod());
assertEquals("/" + String.join(",", indices), request.getEndpoint());
assertThat(expectedParams, equalTo(request.getParameters()));
assertNull(request.getEntity());
}
private static void getAndExistsTest(Function<GetRequest, Request> requestConverter, String method) {
String index = randomAlphaOfLengthBetween(3, 10);
String type = randomAlphaOfLengthBetween(3, 10);
@ -1008,12 +1030,7 @@ public class RequestTests extends ESTestCase {
String[] aliases = randomIndicesNames(indices.length == 0 ? 1 : 0, 5);
getAliasesRequest.aliases(aliases);
Map<String, String> expectedParams = new HashMap<>();
if (randomBoolean()) {
boolean local = randomBoolean();
getAliasesRequest.local(local);
}
expectedParams.put("local", Boolean.toString(getAliasesRequest.local()));
setRandomLocal(getAliasesRequest, expectedParams);
setRandomIndicesOptions(getAliasesRequest::indicesOptions, getAliasesRequest::indicesOptions, expectedParams);
Request request = Request.existsAlias(getAliasesRequest);
@ -1252,6 +1269,46 @@ public class RequestTests extends ESTestCase {
}
}
private static void setRandomIncludeDefaults(GetIndexRequest request, Map<String, String> expectedParams) {
if (randomBoolean()) {
boolean includeDefaults = randomBoolean();
request.includeDefaults(includeDefaults);
if (includeDefaults) {
expectedParams.put("include_defaults", String.valueOf(includeDefaults));
}
}
}
private static void setRandomHumanReadable(GetIndexRequest request, Map<String, String> expectedParams) {
if (randomBoolean()) {
boolean humanReadable = randomBoolean();
request.humanReadable(humanReadable);
if (humanReadable) {
expectedParams.put("human", String.valueOf(humanReadable));
}
}
}
private static void setRandomFlatSettings(GetIndexRequest request, Map<String, String> expectedParams) {
if (randomBoolean()) {
boolean flatSettings = randomBoolean();
request.flatSettings(flatSettings);
if (flatSettings) {
expectedParams.put("flat_settings", String.valueOf(flatSettings));
}
}
}
private static void setRandomLocal(MasterNodeReadRequest<?> request, Map<String, String> expectedParams) {
if (randomBoolean()) {
boolean local = randomBoolean();
request.local(local);
if (local) {
expectedParams.put("local", String.valueOf(local));
}
}
}
private static void setRandomTimeout(Consumer<String> setter, TimeValue defaultTimeout, Map<String, String> expectedParams) {
if (randomBoolean()) {
String timeout = randomTimeValue();

View File

@ -19,6 +19,7 @@
package org.elasticsearch.client.documentation;
import org.apache.http.Header;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.LatchedActionListener;
@ -33,6 +34,7 @@ import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
@ -74,6 +76,69 @@ import java.util.concurrent.TimeUnit;
*/
public class IndicesClientDocumentationIT extends ESRestHighLevelClientTestCase {
public void testIndicesExist() throws IOException {
RestHighLevelClient client = highLevelClient();
{
CreateIndexResponse createIndexResponse = client.indices().create(new CreateIndexRequest("twitter"));
assertTrue(createIndexResponse.isAcknowledged());
}
{
// tag::indices-exists-request
GetIndexRequest request = new GetIndexRequest();
request.indices("twitter"); // <1>
// end::indices-exists-request
IndicesOptions indicesOptions = IndicesOptions.strictExpand();
// tag::indices-exists-request-optionals
request.local(false); // <1>
request.humanReadable(true); // <2>
request.includeDefaults(false); // <3>
request.flatSettings(false); // <4>
request.indicesOptions(indicesOptions); // <5>
// end::indices-exists-request-optionals
Header[] headers = new Header[0];
// tag::indices-exists-response
boolean exists = client.indices().exists(request, headers);
// end::indices-exists-response
assertTrue(exists);
}
}
public void testIndicesExistAsync() throws IOException {
RestHighLevelClient client = highLevelClient();
{
CreateIndexResponse createIndexResponse = client.indices().create(new CreateIndexRequest("twitter"));
assertTrue(createIndexResponse.isAcknowledged());
}
{
GetIndexRequest request = new GetIndexRequest();
request.indices("twitter");
Header[] headers = new Header[0];
// tag::indices-exists-async
client.indices().existsAsync(
request,
new ActionListener<Boolean>() {
@Override
public void onResponse(Boolean exists) {
// <1>
}
@Override
public void onFailure(Exception e) {
// <2>
}
},
headers
);
// end::indices-exists-async
}
}
public void testDeleteIndex() throws IOException {
RestHighLevelClient client = highLevelClient();

View File

@ -1,5 +1,7 @@
include::create_index.asciidoc[]
include::indices_exists.asciidoc[]
include::delete_index.asciidoc[]
include::open_index.asciidoc[]

View File

@ -0,0 +1,57 @@
[[java-rest-high-indices-exists]]
=== Indices Exists API
[[java-rest-high-indices-exists-request]]
==== Indices Exists Request
The high-level REST client uses a `GetIndexRequest` for Indices Exists API. The index name (or indices' names) are required.
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[indices-exists-request]
--------------------------------------------------
<1> Index
[[java-rest-high-indices-exists-optional-args]]
==== Optional arguments
Indices Exists API also accepts following optional arguments, through a `GetIndexRequest`:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[indices-exists-request-optionals]
--------------------------------------------------
<1> Whether to return local information or retrieve the state from master node
<2> Return result in a format suitable for humans
<3> Whether to return all default setting for each of the indices
<4> Return settings in flat format
<5> Controls how unavailable indices are resolved and how wildcard expressions are expanded
[[java-rest-high-indices-sync]]
==== Synchronous Execution
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[indices-exists-response]
--------------------------------------------------
[[java-rest-high-indices-async]]
==== Asynchronous Execution
As is the case with many other APIs, the Indices Exists API has an asynchronous variant in the
Java High Level REST Client.
The asynchronous variant returns void and accept an extra `ActionListener` as an argument.
The provided listener will be notified upon request completion or failure.
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[indices-exists-async]
--------------------------------------------------
<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-indices-exists-response]]
==== Response
The response is a `boolean` value, indicating whether the index (or indices) exist:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[indices-exists-response]
--------------------------------------------------

View File

@ -6,6 +6,7 @@ The Java High Level REST Client supports the following APIs:
Indices APIs::
* <<java-rest-high-create-index>>
* <<java-rest-high-delete-index>>
* <<java-rest-high-indices-exists>>
* <<java-rest-high-open-index>>
* <<java-rest-high-close-index>>
* <<java-rest-high-put-mapping>>

View File

@ -51,4 +51,4 @@ public class IndicesExistsResponse extends ActionResponse {
super.writeTo(out);
out.writeBoolean(exists);
}
}
}

View File

@ -33,7 +33,6 @@ import java.util.List;
* A request to delete an index. Best created with {@link org.elasticsearch.client.Requests#deleteIndexRequest(String)}.
*/
public class GetIndexRequest extends ClusterInfoRequest<GetIndexRequest> {
public enum Feature {
ALIASES((byte) 0, "_aliases", "_alias"),
MAPPINGS((byte) 1, "_mappings", "_mapping"),
@ -99,6 +98,8 @@ public class GetIndexRequest extends ClusterInfoRequest<GetIndexRequest> {
private static final Feature[] DEFAULT_FEATURES = new Feature[] { Feature.ALIASES, Feature.MAPPINGS, Feature.SETTINGS };
private Feature[] features = DEFAULT_FEATURES;
private boolean humanReadable = false;
private transient boolean flatSettings = false;
private transient boolean includeDefaults = false;
public GetIndexRequest() {
@ -149,6 +150,43 @@ public class GetIndexRequest extends ClusterInfoRequest<GetIndexRequest> {
return humanReadable;
}
/**
* Sets the value of "flat_settings".
* @param flatSettings value of "flat_settings" flag to be set
* @return this request
*/
public GetIndexRequest flatSettings(boolean flatSettings) {
this.flatSettings = flatSettings;
return this;
}
/**
* Return settings in flat format.
* @return <code>true</code> if settings need to be returned in flat format; <code>false</code> otherwise.
*/
public boolean flatSettings() {
return flatSettings;
}
/**
* Sets the value of "include_defaults".
* @param includeDefaults value of "include_defaults" to be set.
* @return this request
*/
public GetIndexRequest includeDefaults(boolean includeDefaults) {
this.includeDefaults = includeDefaults;
return this;
}
/**
* Whether to return all default settings for each of the indices.
* @return <code>true</code> if defaults settings for each of the indices need to returned;
* <code>false</code> otherwise.
*/
public boolean includeDefaults() {
return includeDefaults;
}
@Override
public void readFrom(StreamInput in) throws IOException {
throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable");

View File

@ -51,6 +51,11 @@ public abstract class MasterNodeReadRequest<Request extends MasterNodeReadReques
return (Request) this;
}
/**
* Return local information, do not retrieve the state from master node (default: false).
* @return <code>true</code> if local information is to be returned;
* <code>false</code> if information is to be retrieved from master node (default).
*/
public final boolean local() {
return local;
}