Skip to content

Commit

Permalink
HLRest: Add get index templates API (#31161)
Browse files Browse the repository at this point in the history
Relates #27205
  • Loading branch information
dnhatn committed Jun 13, 2018
1 parent 197aa9b commit abc6751
Show file tree
Hide file tree
Showing 9 changed files with 364 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse;
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeResponse;
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesRequest;
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesResponse;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateResponse;

Expand Down Expand Up @@ -1059,4 +1061,33 @@ public void putTemplateAsync(PutIndexTemplateRequest putIndexTemplateRequest, Re
restHighLevelClient.performRequestAsyncAndParseEntity(putIndexTemplateRequest, RequestConverters::putTemplate, options,
PutIndexTemplateResponse::fromXContent, listener, emptySet());
}

/**
* Gets index templates using the Index Templates API
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates.html"> Index Templates API
* on elastic.co</a>
* @param getIndexTemplatesRequest the request
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @return the response
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public GetIndexTemplatesResponse getTemplate(GetIndexTemplatesRequest getIndexTemplatesRequest,
RequestOptions options) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(getIndexTemplatesRequest, RequestConverters::getTemplates,
options, GetIndexTemplatesResponse::fromXContent, emptySet());
}

/**
* Asynchronously gets index templates using the Index Templates API
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates.html"> Index Templates API
* on elastic.co</a>
* @param getIndexTemplatesRequest the request
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @param listener the listener to be notified upon request completion
*/
public void getTemplateAsync(GetIndexTemplatesRequest getIndexTemplatesRequest, RequestOptions options,
ActionListener<GetIndexTemplatesResponse> listener) {
restHighLevelClient.performRequestAsyncAndParseEntity(getIndexTemplatesRequest, RequestConverters::getTemplates,
options, GetIndexTemplatesResponse::fromXContent, listener, emptySet());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesRequest;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
Expand Down Expand Up @@ -841,6 +842,16 @@ static Request putTemplate(PutIndexTemplateRequest putIndexTemplateRequest) thro
return request;
}

static Request getTemplates(GetIndexTemplatesRequest getIndexTemplatesRequest) throws IOException {
String[] names = getIndexTemplatesRequest.names();
String endpoint = new EndpointBuilder().addPathPartAsIs("_template").addCommaSeparatedPathParts(names).build();
Request request = new Request(HttpGet.METHOD_NAME, endpoint);
Params params = new Params(request);
params.withLocal(getIndexTemplatesRequest.local());
params.withMasterTimeout(getIndexTemplatesRequest.masterNodeTimeout());
return request;
}

private static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) throws IOException {
BytesRef source = XContentHelper.toXContent(toXContent, xContentType, false).toBytesRef();
return new ByteArrayEntity(source.bytes, source.offset, source.length, createContentType(xContentType));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,16 @@
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeResponse;
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesRequest;
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesResponse;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.support.broadcast.BroadcastResponse;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
import org.elasticsearch.common.ValidationException;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
Expand All @@ -89,6 +92,7 @@
import static org.elasticsearch.common.xcontent.support.XContentMapValues.extractRawValues;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.extractValue;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
Expand Down Expand Up @@ -999,4 +1003,51 @@ public void testPutTemplateBadRequests() throws Exception {
() -> execute(unknownSettingTemplate, client.indices()::putTemplate, client.indices()::putTemplateAsync));
assertThat(unknownSettingError.getDetailedMessage(), containsString("unknown setting [index.this-setting-does-not-exist]"));
}

public void testGetIndexTemplate() throws Exception {
RestHighLevelClient client = highLevelClient();

PutIndexTemplateRequest putTemplate1 = new PutIndexTemplateRequest().name("template-1")
.patterns(Arrays.asList("pattern-1", "name-1")).alias(new Alias("alias-1"));
assertThat(execute(putTemplate1, client.indices()::putTemplate, client.indices()::putTemplateAsync).isAcknowledged(),
equalTo(true));
PutIndexTemplateRequest putTemplate2 = new PutIndexTemplateRequest().name("template-2")
.patterns(Arrays.asList("pattern-2", "name-2"))
.settings(Settings.builder().put("number_of_shards", "2").put("number_of_replicas", "0"));
assertThat(execute(putTemplate2, client.indices()::putTemplate, client.indices()::putTemplateAsync).isAcknowledged(),
equalTo(true));

GetIndexTemplatesResponse getTemplate1 = execute(new GetIndexTemplatesRequest().names("template-1"),
client.indices()::getTemplate, client.indices()::getTemplateAsync);
assertThat(getTemplate1.getIndexTemplates(), hasSize(1));
IndexTemplateMetaData template1 = getTemplate1.getIndexTemplates().get(0);
assertThat(template1.name(), equalTo("template-1"));
assertThat(template1.patterns(), contains("pattern-1", "name-1"));
assertTrue(template1.aliases().containsKey("alias-1"));

GetIndexTemplatesResponse getTemplate2 = execute(new GetIndexTemplatesRequest().names("template-2"),
client.indices()::getTemplate, client.indices()::getTemplateAsync);
assertThat(getTemplate2.getIndexTemplates(), hasSize(1));
IndexTemplateMetaData template2 = getTemplate2.getIndexTemplates().get(0);
assertThat(template2.name(), equalTo("template-2"));
assertThat(template2.patterns(), contains("pattern-2", "name-2"));
assertTrue(template2.aliases().isEmpty());
assertThat(template2.settings().get("index.number_of_shards"), equalTo("2"));
assertThat(template2.settings().get("index.number_of_replicas"), equalTo("0"));

GetIndexTemplatesRequest getBothRequest = new GetIndexTemplatesRequest();
if (randomBoolean()) {
getBothRequest.names("*-1", "template-2");
} else {
getBothRequest.names("template-*");
}
GetIndexTemplatesResponse getBoth = execute(getBothRequest, client.indices()::getTemplate, client.indices()::getTemplateAsync);
assertThat(getBoth.getIndexTemplates(), hasSize(2));
assertThat(getBoth.getIndexTemplates().stream().map(IndexTemplateMetaData::getName).toArray(),
arrayContainingInAnyOrder("template-1", "template-2"));

ElasticsearchException notFound = expectThrows(ElasticsearchException.class, () -> execute(
new GetIndexTemplatesRequest().names("the-template-*"), client.indices()::getTemplate, client.indices()::getTemplateAsync));
assertThat(notFound.status(), equalTo(RestStatus.NOT_FOUND));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesRequest;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkShardRequest;
Expand Down Expand Up @@ -140,6 +141,7 @@
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import static java.util.Collections.singletonMap;
import static org.elasticsearch.client.RequestConverters.REQUEST_BODY_CONTENT_TYPE;
Expand Down Expand Up @@ -1812,6 +1814,24 @@ public void testPutTemplateRequest() throws Exception {
assertToXContentBody(putTemplateRequest, request.getEntity());
}

public void testGetTemplateRequest() throws Exception {
Map<String, String> encodes = new HashMap<>();
encodes.put("log", "log");
encodes.put("1", "1");
encodes.put("template#1", "template%231");
encodes.put("template-*", "template-*");
encodes.put("foo^bar", "foo%5Ebar");
List<String> names = randomSubsetOf(1, encodes.keySet());
GetIndexTemplatesRequest getTemplatesRequest = new GetIndexTemplatesRequest().names(names.toArray(new String[0]));
Map<String, String> expectedParams = new HashMap<>();
setRandomMasterTimeout(getTemplatesRequest, expectedParams);
setRandomLocal(getTemplatesRequest, expectedParams);
Request request = RequestConverters.getTemplates(getTemplatesRequest);
assertThat(request.getEndpoint(), equalTo("/_template/" + names.stream().map(encodes::get).collect(Collectors.joining(","))));
assertThat(request.getParameters(), equalTo(expectedParams));
assertThat(request.getEntity(), nullValue());
}

private static void assertToXContentBody(ToXContent expectedBody, HttpEntity actualEntity) throws IOException {
BytesReference expectedBytes = XContentHelper.toXContent(expectedBody, REQUEST_BODY_CONTENT_TYPE, false);
assertEquals(XContentType.JSON.mediaTypeWithoutParameters(), actualEntity.getContentType().getValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeResponse;
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesRequest;
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesResponse;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateResponse;
import org.elasticsearch.action.support.ActiveShardCount;
Expand All @@ -67,6 +69,7 @@
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.SyncedFlushResponse;
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.settings.Settings;
Expand All @@ -82,11 +85,13 @@
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;

/**
* This class is used to generate the Java Indices API documentation.
Expand Down Expand Up @@ -1982,4 +1987,71 @@ public void onFailure(Exception e) {

assertTrue(latch.await(30L, TimeUnit.SECONDS));
}

public void testGetTemplates() throws Exception {
RestHighLevelClient client = highLevelClient();
{
PutIndexTemplateRequest putRequest = new PutIndexTemplateRequest("my-template");
putRequest.patterns(Arrays.asList("pattern-1", "log-*"));
putRequest.settings(Settings.builder().put("index.number_of_shards", 3).put("index.number_of_replicas", 1));
putRequest.mapping("tweet",
"{\n" +
" \"tweet\": {\n" +
" \"properties\": {\n" +
" \"message\": {\n" +
" \"type\": \"text\"\n" +
" }\n" +
" }\n" +
" }\n" +
"}", XContentType.JSON);
assertTrue(client.indices().putTemplate(putRequest, RequestOptions.DEFAULT).isAcknowledged());
}

// tag::get-templates-request
GetIndexTemplatesRequest request = new GetIndexTemplatesRequest("my-template"); // <1>
request.names("template-1", "template-2"); // <2>
request.names("my-*"); // <3>
// end::get-templates-request

// tag::get-templates-request-masterTimeout
request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
request.masterNodeTimeout("1m"); // <2>
// end::get-templates-request-masterTimeout

// tag::get-templates-execute
GetIndexTemplatesResponse getTemplatesResponse = client.indices().getTemplate(request, RequestOptions.DEFAULT);
// end::get-templates-execute

// tag::get-templates-response
List<IndexTemplateMetaData> templates = getTemplatesResponse.getIndexTemplates(); // <1>
// end::get-templates-response

assertThat(templates, hasSize(1));
assertThat(templates.get(0).name(), equalTo("my-template"));

// tag::get-templates-execute-listener
ActionListener<GetIndexTemplatesResponse> listener =
new ActionListener<GetIndexTemplatesResponse>() {
@Override
public void onResponse(GetIndexTemplatesResponse response) {
// <1>
}

@Override
public void onFailure(Exception e) {
// <2>
}
};
// end::get-templates-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-templates-execute-async
client.indices().getTemplateAsync(request, RequestOptions.DEFAULT, listener); // <1>
// end::get-templates-execute-async

assertTrue(latch.await(30L, TimeUnit.SECONDS));
}
}
73 changes: 73 additions & 0 deletions docs/java-rest/high-level/indices/get_templates.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
[[java-rest-high-get-templates]]
=== Get Templates API

The Get Templates API allows to retrieve a list of index templates by name.

[[java-rest-high-get-templates-request]]
==== Get Index Templates Request

A `GetIndexTemplatesRequest` specifies one or several names of the index templates to get.

["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-templates-request]
--------------------------------------------------
<1> A single index template name
<2> Multiple index template names
<3> An index template name using wildcard

["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-templates-request-masterTimeout]
--------------------------------------------------
<1> Timeout to connect to the master node as a `TimeValue`
<2> Timeout to connect to the master node as a `String`

[[java-rest-high-get-templates-sync]]
==== Synchronous Execution

["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-templates-execute]
--------------------------------------------------

[[java-rest-high-get-templates-async]]
==== Asynchronous Execution

The asynchronous execution of a get index templates request requires a `GetTemplatesRequest`
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-templates-execute-async]
--------------------------------------------------
<1> The `GetTemplatesRequest` 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 `GetTemplatesResponse` looks like:

["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-templates-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-templates-response]]
==== Get Templates Response

The returned `GetTemplatesResponse` consists a list of matching index templates.

["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-templates-response]
--------------------------------------------------
<1> A list of matching index templates

3 changes: 2 additions & 1 deletion docs/java-rest/high-level/supported-apis.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ include::indices/get_mappings.asciidoc[]
include::indices/update_aliases.asciidoc[]
include::indices/exists_alias.asciidoc[]
include::indices/put_settings.asciidoc[]
include::indices/put_template.asciidoc[]
include::indices/get_settings.asciidoc[]
include::indices/put_template.asciidoc[]
include::indices/get_templates.asciidoc[]

== Cluster APIs

Expand Down
Loading

0 comments on commit abc6751

Please sign in to comment.