From b2e11f7f85c82b4a2e7d0fc17b63b47e67f467ef Mon Sep 17 00:00:00 2001 From: Nhat Nguyen Date: Mon, 28 May 2018 12:13:43 -0400 Subject: [PATCH 1/6] HLRest: Add get index templates API --- .../elasticsearch/client/IndicesClient.java | 26 ++++++ .../client/RequestConverters.java | 11 +++ .../elasticsearch/client/IndicesClientIT.java | 52 +++++++++++ .../client/RequestConvertersTests.java | 20 ++++ .../IndicesClientDocumentationIT.java | 72 ++++++++++++++ .../high-level/indices/get_templates.asciidoc | 73 +++++++++++++++ .../get/GetIndexTemplatesResponse.java | 15 +++ .../get/GetIndexTemplatesResponseTests.java | 93 +++++++++++++++++++ 8 files changed, 362 insertions(+) create mode 100644 docs/java-rest/high-level/indices/get_templates.asciidoc create mode 100644 server/src/test/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponseTests.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java index fa7eb9ab9ec8a..aef04c61ae0c1 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java @@ -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; @@ -1059,4 +1061,28 @@ 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 Index Templates API + * on elastic.co + */ + public GetIndexTemplatesResponse getTemplates(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 Index Templates API + * on elastic.co + */ + public void getTemplatesAsync(GetIndexTemplatesRequest getIndexTemplatesRequest, RequestOptions options, + ActionListener listener) { + restHighLevelClient.performRequestAsyncAndParseEntity(getIndexTemplatesRequest, RequestConverters::getTemplates, + options, GetIndexTemplatesResponse::fromXContent, listener, emptySet()); + } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java index b061289888c0c..a9af2408653d3 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java @@ -54,6 +54,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; @@ -818,6 +819,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)); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java index 986c3380ff3c8..3a0661747c7a5 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java @@ -59,6 +59,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.index.IndexRequest; @@ -66,6 +68,7 @@ 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; @@ -1002,4 +1005,53 @@ 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()::getTemplates, client.indices()::getTemplatesAsync); + 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()::getTemplates, client.indices()::getTemplatesAsync); + 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()::getTemplates, client.indices()::getTemplatesAsync); + assertThat(getBoth.getIndexTemplates(), hasSize(2)); + assertThat(getBoth.getIndexTemplates().get(0).name(), equalTo("template-1")); + assertThat(getBoth.getIndexTemplates().get(0).patterns(), contains("pattern-1", "name-1")); + assertThat(getBoth.getIndexTemplates().get(1).name(), equalTo("template-2")); + assertThat(getBoth.getIndexTemplates().get(1).patterns(), contains("pattern-2", "name-2")); + + ElasticsearchException notFound = expectThrows(ElasticsearchException.class, () -> execute( + new GetIndexTemplatesRequest().names("the-template-*"), client.indices()::getTemplates, client.indices()::getTemplatesAsync)); + assertThat(notFound.status(), equalTo(RestStatus.NOT_FOUND)); + } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java index ee372e255e70a..2bbaea9f4dae2 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java @@ -56,6 +56,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; @@ -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; @@ -1762,6 +1764,24 @@ public void testPutTemplateRequest() throws Exception { assertToXContentBody(putTemplateRequest, request.getEntity()); } + public void testGetTemplateRequest() throws Exception { + Map 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 names = randomSubsetOf(1, encodes.keySet()); + GetIndexTemplatesRequest getTemplatesRequest = new GetIndexTemplatesRequest().names(names.toArray(new String[0])); + Map 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()); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java index 2b81e4a4adce9..0d72b89c3301a 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java @@ -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; @@ -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; @@ -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. @@ -1983,4 +1988,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().getTemplates(request, RequestOptions.DEFAULT); + // end::get-templates-execute + + // tag::get-templates-response + List 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 listener = + new ActionListener() { + @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().getTemplatesAsync(request, RequestOptions.DEFAULT, listener); // <1> + // end::get-templates-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + } } diff --git a/docs/java-rest/high-level/indices/get_templates.asciidoc b/docs/java-rest/high-level/indices/get_templates.asciidoc new file mode 100644 index 0000000000000..979752803f008 --- /dev/null +++ b/docs/java-rest/high-level/indices/get_templates.asciidoc @@ -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 getting index templates. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[get-templates-request] +-------------------------------------------------- +<1> A single index template name +<2> Multiple index templates' names +<3> An index template's 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 + diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponse.java b/server/src/main/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponse.java index 3c5fb36d6c6aa..2976f24724234 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponse.java @@ -25,9 +25,11 @@ 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 java.io.IOException; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import static java.util.Collections.singletonMap; @@ -37,6 +39,7 @@ public class GetIndexTemplatesResponse extends ActionResponse implements ToXCont private List indexTemplates; GetIndexTemplatesResponse() { + indexTemplates = new ArrayList<>(); } GetIndexTemplatesResponse(List indexTemplates) { @@ -76,4 +79,16 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.endObject(); return builder; } + + public static GetIndexTemplatesResponse fromXContent(XContentParser parser) throws IOException { + final List templates = new ArrayList<>(); + for (XContentParser.Token token = parser.nextToken(); token != XContentParser.Token.END_OBJECT; token = parser.nextToken()) { + if (token == XContentParser.Token.FIELD_NAME) { + final IndexTemplateMetaData templateMetaData = IndexTemplateMetaData.Builder.fromXContent(parser, parser.currentName()); + templates.add(templateMetaData); + } + } + templates.sort(Comparator.comparing(IndexTemplateMetaData::name)); + return new GetIndexTemplatesResponse(templates); + } } diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponseTests.java new file mode 100644 index 0000000000000..c466cf3292128 --- /dev/null +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponseTests.java @@ -0,0 +1,93 @@ +/* + * 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.template.get; + +import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.cluster.metadata.IndexTemplateMetaData; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.test.AbstractXContentTestCase; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static org.hamcrest.Matchers.equalTo; + +public class GetIndexTemplatesResponseTests extends AbstractXContentTestCase { + @Override + protected GetIndexTemplatesResponse doParseInstance(XContentParser parser) throws IOException { + return GetIndexTemplatesResponse.fromXContent(parser); + } + + @Override + protected GetIndexTemplatesResponse createTestInstance() { + List templates = new ArrayList<>(); + int numTemplates = between(1, 10); + for (int t = 0; t < numTemplates; t++) { + IndexTemplateMetaData.Builder templateBuilder = IndexTemplateMetaData.builder("template-" + t); + templateBuilder.patterns(IntStream.range(0, between(1, 5)).mapToObj(i -> "pattern-" + i).collect(Collectors.toList())); + int numAlias = between(0, 5); + for (int i = 0; i < numAlias; i++) { + AliasMetaData.Builder alias = AliasMetaData.builder(randomAlphaOfLengthBetween(1, 10)); + if (randomBoolean()) { + alias.indexRouting(randomRealisticUnicodeOfLengthBetween(1, 10)); + } + if (randomBoolean()) { + alias.searchRouting(randomRealisticUnicodeOfLengthBetween(1, 10)); + } + templateBuilder.putAlias(alias); + } + if (randomBoolean()) { + templateBuilder.settings(Settings.builder().put("index.setting-1", randomLong())); + } + if (randomBoolean()) { + templateBuilder.order(randomInt()); + } + if (randomBoolean()) { + templateBuilder.version(between(0, 100)); + } + if (randomBoolean()) { + try { + templateBuilder.putMapping("doc", "{\"doc\":{\"properties\":{\"type\":\"text\"}}}"); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } + templates.add(templateBuilder.build()); + } + return new GetIndexTemplatesResponse(templates); + } + + @Override + protected boolean supportsUnknownFields() { + return false; + } + + @Override + protected void assertEqualInstances(GetIndexTemplatesResponse expectedInstance, GetIndexTemplatesResponse newInstance) { + assertNotSame(newInstance, expectedInstance); + assertThat(new HashSet<>(newInstance.getIndexTemplates()), equalTo(new HashSet<>(expectedInstance.getIndexTemplates()))); + } +} From 95875965fb4baba9323c69f53af9c89f094fabd2 Mon Sep 17 00:00:00 2001 From: Nhat Nguyen Date: Wed, 6 Jun 2018 21:44:19 -0400 Subject: [PATCH 2/6] add to supported api list --- docs/java-rest/high-level/supported-apis.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index 34149bee52880..5e78dfef660cd 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -101,6 +101,7 @@ include::indices/exists_alias.asciidoc[] include::indices/put_settings.asciidoc[] include::indices/get_settings.asciidoc[] include::indices/put_template.asciidoc[] +include::indices/get_templates.asciidoc[] == Cluster APIs From a6119c3da5d67ad1e57d284aedc435245fd37453 Mon Sep 17 00:00:00 2001 From: Nhat Nguyen Date: Thu, 7 Jun 2018 15:17:17 -0400 Subject: [PATCH 3/6] @cbuescher comments --- .../high-level/indices/get_templates.asciidoc | 6 +++--- .../template/get/GetIndexTemplatesResponse.java | 6 ++---- .../template/get/GetIndexTemplatesResponseTests.java | 11 ++--------- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/docs/java-rest/high-level/indices/get_templates.asciidoc b/docs/java-rest/high-level/indices/get_templates.asciidoc index 979752803f008..4a882bb53aa7d 100644 --- a/docs/java-rest/high-level/indices/get_templates.asciidoc +++ b/docs/java-rest/high-level/indices/get_templates.asciidoc @@ -6,15 +6,15 @@ 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 getting index templates. +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 templates' names -<3> An index template's name using wildcard +<2> Multiple index template names +<3> An index template name using wildcard ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponse.java b/server/src/main/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponse.java index 2976f24724234..2bdc966c74e59 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponse.java @@ -29,14 +29,13 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; import static java.util.Collections.singletonMap; public class GetIndexTemplatesResponse extends ActionResponse implements ToXContentObject { - private List indexTemplates; + private final List indexTemplates; GetIndexTemplatesResponse() { indexTemplates = new ArrayList<>(); @@ -54,7 +53,7 @@ public List getIndexTemplates() { public void readFrom(StreamInput in) throws IOException { super.readFrom(in); int size = in.readVInt(); - indexTemplates = new ArrayList<>(size); + indexTemplates.clear(); for (int i = 0 ; i < size ; i++) { indexTemplates.add(0, IndexTemplateMetaData.readFrom(in)); } @@ -88,7 +87,6 @@ public static GetIndexTemplatesResponse fromXContent(XContentParser parser) thro templates.add(templateMetaData); } } - templates.sort(Comparator.comparing(IndexTemplateMetaData::name)); return new GetIndexTemplatesResponse(templates); } } diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponseTests.java index c466cf3292128..0f6a91790e138 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponseTests.java @@ -44,20 +44,13 @@ protected GetIndexTemplatesResponse doParseInstance(XContentParser parser) throw @Override protected GetIndexTemplatesResponse createTestInstance() { List templates = new ArrayList<>(); - int numTemplates = between(1, 10); + int numTemplates = between(0, 10); for (int t = 0; t < numTemplates; t++) { IndexTemplateMetaData.Builder templateBuilder = IndexTemplateMetaData.builder("template-" + t); templateBuilder.patterns(IntStream.range(0, between(1, 5)).mapToObj(i -> "pattern-" + i).collect(Collectors.toList())); int numAlias = between(0, 5); for (int i = 0; i < numAlias; i++) { - AliasMetaData.Builder alias = AliasMetaData.builder(randomAlphaOfLengthBetween(1, 10)); - if (randomBoolean()) { - alias.indexRouting(randomRealisticUnicodeOfLengthBetween(1, 10)); - } - if (randomBoolean()) { - alias.searchRouting(randomRealisticUnicodeOfLengthBetween(1, 10)); - } - templateBuilder.putAlias(alias); + templateBuilder.putAlias(AliasMetaData.builder(randomAlphaOfLengthBetween(1, 10))); } if (randomBoolean()) { templateBuilder.settings(Settings.builder().put("index.setting-1", randomLong())); From caea8456cd345523dccfc248aa840bdb371c03d2 Mon Sep 17 00:00:00 2001 From: Nhat Nguyen Date: Thu, 7 Jun 2018 22:46:58 -0400 Subject: [PATCH 4/6] fix test when get both templates --- .../java/org/elasticsearch/client/IndicesClientIT.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java index 3a0661747c7a5..cb3f50d09d505 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java @@ -91,6 +91,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; @@ -1045,10 +1046,8 @@ public void testGetIndexTemplate() throws Exception { } GetIndexTemplatesResponse getBoth = execute(getBothRequest, client.indices()::getTemplates, client.indices()::getTemplatesAsync); assertThat(getBoth.getIndexTemplates(), hasSize(2)); - assertThat(getBoth.getIndexTemplates().get(0).name(), equalTo("template-1")); - assertThat(getBoth.getIndexTemplates().get(0).patterns(), contains("pattern-1", "name-1")); - assertThat(getBoth.getIndexTemplates().get(1).name(), equalTo("template-2")); - assertThat(getBoth.getIndexTemplates().get(1).patterns(), contains("pattern-2", "name-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()::getTemplates, client.indices()::getTemplatesAsync)); From 7117a3d90eb97f70c6ee7f64be430ec7d5d005ac Mon Sep 17 00:00:00 2001 From: Nhat Nguyen Date: Sun, 10 Jun 2018 16:02:02 -0400 Subject: [PATCH 5/6] getTemplates -> getTemplate --- .../org/elasticsearch/client/IndicesClient.java | 17 +++++++++++------ .../elasticsearch/client/IndicesClientIT.java | 8 ++++---- .../IndicesClientDocumentationIT.java | 4 ++-- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java index aef04c61ae0c1..59d2cf1392d30 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndicesClient.java @@ -1064,24 +1064,29 @@ public void putTemplateAsync(PutIndexTemplateRequest putIndexTemplateRequest, Re /** * Gets index templates using the Index Templates API - *

* See Index Templates API * on elastic.co + * @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 getTemplates(GetIndexTemplatesRequest getIndexTemplatesRequest, - RequestOptions options) throws IOException { + 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 Index Templates API * on elastic.co + * @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 getTemplatesAsync(GetIndexTemplatesRequest getIndexTemplatesRequest, RequestOptions options, - ActionListener listener) { + public void getTemplateAsync(GetIndexTemplatesRequest getIndexTemplatesRequest, RequestOptions options, + ActionListener listener) { restHighLevelClient.performRequestAsyncAndParseEntity(getIndexTemplatesRequest, RequestConverters::getTemplates, options, GetIndexTemplatesResponse::fromXContent, listener, emptySet()); } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java index cb3f50d09d505..3945a39e8c77e 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndicesClientIT.java @@ -1021,7 +1021,7 @@ public void testGetIndexTemplate() throws Exception { equalTo(true)); GetIndexTemplatesResponse getTemplate1 = execute(new GetIndexTemplatesRequest().names("template-1"), - client.indices()::getTemplates, client.indices()::getTemplatesAsync); + client.indices()::getTemplate, client.indices()::getTemplateAsync); assertThat(getTemplate1.getIndexTemplates(), hasSize(1)); IndexTemplateMetaData template1 = getTemplate1.getIndexTemplates().get(0); assertThat(template1.name(), equalTo("template-1")); @@ -1029,7 +1029,7 @@ public void testGetIndexTemplate() throws Exception { assertTrue(template1.aliases().containsKey("alias-1")); GetIndexTemplatesResponse getTemplate2 = execute(new GetIndexTemplatesRequest().names("template-2"), - client.indices()::getTemplates, client.indices()::getTemplatesAsync); + client.indices()::getTemplate, client.indices()::getTemplateAsync); assertThat(getTemplate2.getIndexTemplates(), hasSize(1)); IndexTemplateMetaData template2 = getTemplate2.getIndexTemplates().get(0); assertThat(template2.name(), equalTo("template-2")); @@ -1044,13 +1044,13 @@ public void testGetIndexTemplate() throws Exception { } else { getBothRequest.names("template-*"); } - GetIndexTemplatesResponse getBoth = execute(getBothRequest, client.indices()::getTemplates, client.indices()::getTemplatesAsync); + 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()::getTemplates, client.indices()::getTemplatesAsync)); + new GetIndexTemplatesRequest().names("the-template-*"), client.indices()::getTemplate, client.indices()::getTemplateAsync)); assertThat(notFound.status(), equalTo(RestStatus.NOT_FOUND)); } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java index 0d72b89c3301a..bdaac91b374c6 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java @@ -2020,7 +2020,7 @@ public void testGetTemplates() throws Exception { // end::get-templates-request-masterTimeout // tag::get-templates-execute - GetIndexTemplatesResponse getTemplatesResponse = client.indices().getTemplates(request, RequestOptions.DEFAULT); + GetIndexTemplatesResponse getTemplatesResponse = client.indices().getTemplate(request, RequestOptions.DEFAULT); // end::get-templates-execute // tag::get-templates-response @@ -2050,7 +2050,7 @@ public void onFailure(Exception e) { listener = new LatchedActionListener<>(listener, latch); // tag::get-templates-execute-async - client.indices().getTemplatesAsync(request, RequestOptions.DEFAULT, listener); // <1> + client.indices().getTemplateAsync(request, RequestOptions.DEFAULT, listener); // <1> // end::get-templates-execute-async assertTrue(latch.await(30L, TimeUnit.SECONDS)); From c4a2bb9653a7c8486c06ca2c48381a887311debc Mon Sep 17 00:00:00 2001 From: Nhat Nguyen Date: Mon, 11 Jun 2018 08:18:12 -0400 Subject: [PATCH 6/6] add comment --- .../indices/template/get/GetIndexTemplatesResponseTests.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/src/test/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponseTests.java index 0f6a91790e138..6cb26967d07fa 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/indices/template/get/GetIndexTemplatesResponseTests.java @@ -75,6 +75,9 @@ protected GetIndexTemplatesResponse createTestInstance() { @Override protected boolean supportsUnknownFields() { + // We can not inject anything at the top level because a GetIndexTemplatesResponse is serialized as a map + // from template name to template content. IndexTemplateMetaDataTests already covers situations where we + // inject arbitrary things inside the IndexTemplateMetaData. return false; }