Преглед изворни кода

HLRC: document index template v2 and component template APIs (#56136)

This documents the index template v2 and component template APIs in the
high level rest client.
Andrei Dan пре 5 година
родитељ
комит
9bcf89b1e2

+ 232 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/ClusterClientDocumentationIT.java

@@ -28,6 +28,7 @@ import org.elasticsearch.action.admin.cluster.settings.ClusterGetSettingsRespons
 import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
 import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsResponse;
 import org.elasticsearch.action.support.ActiveShardCount;
+import org.elasticsearch.action.support.master.AcknowledgedResponse;
 import org.elasticsearch.client.ESRestHighLevelClientTestCase;
 import org.elasticsearch.client.RequestOptions;
 import org.elasticsearch.client.RestHighLevelClient;
@@ -35,11 +36,19 @@ import org.elasticsearch.client.cluster.RemoteConnectionInfo;
 import org.elasticsearch.client.cluster.RemoteInfoRequest;
 import org.elasticsearch.client.cluster.RemoteInfoResponse;
 import org.elasticsearch.client.indices.CreateIndexRequest;
+import org.elasticsearch.client.indices.DeleteComponentTemplateRequest;
+import org.elasticsearch.client.indices.GetComponentTemplatesRequest;
+import org.elasticsearch.client.indices.GetComponentTemplatesResponse;
+import org.elasticsearch.client.indices.PutComponentTemplateRequest;
 import org.elasticsearch.cluster.health.ClusterHealthStatus;
 import org.elasticsearch.cluster.health.ClusterIndexHealth;
 import org.elasticsearch.cluster.health.ClusterShardHealth;
+import org.elasticsearch.cluster.metadata.AliasMetadata;
+import org.elasticsearch.cluster.metadata.ComponentTemplate;
+import org.elasticsearch.cluster.metadata.Template;
 import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider;
 import org.elasticsearch.common.Priority;
+import org.elasticsearch.common.compress.CompressedXContent;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.unit.ByteSizeUnit;
 import org.elasticsearch.common.unit.TimeValue;
@@ -56,6 +65,7 @@ import java.util.concurrent.TimeUnit;
 
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.notNullValue;
 
 /**
@@ -475,4 +485,226 @@ public class ClusterClientDocumentationIT extends ESRestHighLevelClientTestCase
 
         assertTrue(latch.await(30L, TimeUnit.SECONDS));
     }
+
+    public void testGetComponentTemplates() throws Exception {
+        RestHighLevelClient client = highLevelClient();
+        {
+            Template template = new Template(Settings.builder().put("index.number_of_replicas", 3).build(), null, null);
+            ComponentTemplate componentTemplate = new ComponentTemplate(template, null, null);
+            PutComponentTemplateRequest putComponentTemplateRequest =
+                new PutComponentTemplateRequest().name("ct1").componentTemplate(componentTemplate);
+            client.cluster().putComponentTemplate(putComponentTemplateRequest, RequestOptions.DEFAULT);
+
+            assertTrue(client.cluster().putComponentTemplate(putComponentTemplateRequest, RequestOptions.DEFAULT).isAcknowledged());
+        }
+
+        // tag::get-component-templates-request
+        GetComponentTemplatesRequest request = new GetComponentTemplatesRequest("ct1"); // <1>
+        // end::get-component-templates-request
+
+        // tag::get-component-templates-request-masterTimeout
+        request.setMasterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
+        request.setMasterNodeTimeout("1m"); // <2>
+        // end::get-component-templates-request-masterTimeout
+
+        // tag::get-component-templates-execute
+        GetComponentTemplatesResponse getTemplatesResponse = client.cluster().getComponentTemplate(request, RequestOptions.DEFAULT);
+        // end::get-component-templates-execute
+
+        // tag::get-component-templates-response
+        Map<String, ComponentTemplate> templates = getTemplatesResponse.getComponentTemplates(); // <1>
+        // end::get-component-templates-response
+
+        assertThat(templates.size(), is(1));
+        assertThat(templates.get("ct1"), is(notNullValue()));
+
+        // tag::get-component-templates-execute-listener
+        ActionListener<GetComponentTemplatesResponse> listener =
+            new ActionListener<GetComponentTemplatesResponse>() {
+                @Override
+                public void onResponse(GetComponentTemplatesResponse response) {
+                    // <1>
+                }
+
+                @Override
+                public void onFailure(Exception e) {
+                    // <2>
+                }
+            };
+        // end::get-component-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-component-templates-execute-async
+        client.cluster().getComponentTemplateAsync(request, RequestOptions.DEFAULT, listener); // <1>
+        // end::get-component-templates-execute-async
+
+        assertTrue(latch.await(30L, TimeUnit.SECONDS));
+    }
+
+    public void testPutComponentTemplate() throws Exception {
+        RestHighLevelClient client = highLevelClient();
+
+        {
+            // tag::put-component-template-request
+            PutComponentTemplateRequest request = new PutComponentTemplateRequest()
+                .name("ct1"); // <1>
+
+            Settings settings = Settings.builder()
+                .put("index.number_of_shards", 3)
+                .put("index.number_of_replicas", 1)
+                .build();
+            String mappingJson = "{\n" +
+                "  \"properties\": {\n" +
+                "    \"message\": {\n" +
+                "      \"type\": \"text\"\n" +
+                "    }\n" +
+                "  }\n" +
+                "}";
+            AliasMetadata twitterAlias = AliasMetadata.builder("twitter_alias").build();
+            Template template = new Template(settings, new CompressedXContent(mappingJson), Map.of("twitter_alias", twitterAlias)); // <2>
+
+            request.componentTemplate(new ComponentTemplate(template, null, null));
+            assertTrue(client.cluster().putComponentTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
+            // end::put-component-template-request
+        }
+
+        {
+            // tag::put-component-template-request-version
+            PutComponentTemplateRequest request = new PutComponentTemplateRequest()
+                .name("ct1");
+            Settings settings = Settings.builder()
+                .put("index.number_of_replicas", 3)
+                .build();
+            Template template = new Template(settings, null, null);
+
+            request.componentTemplate(new ComponentTemplate(template, 3L, null)); // <1>
+            assertTrue(client.cluster().putComponentTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
+            // end::put-component-template-request-version
+
+            // tag::put-component-template-request-create
+            request.create(true);  // <1>
+            // end::put-component-template-request-create
+
+            // tag::put-component-template-request-masterTimeout
+            request.setMasterTimeout(TimeValue.timeValueMinutes(1)); // <1>
+            // end::put-component-template-request-masterTimeout
+
+            request.create(false); // make test happy
+
+            // tag::put-component-template-request-execute
+            AcknowledgedResponse putComponentTemplateResponse = client.cluster().putComponentTemplate(request, RequestOptions.DEFAULT);
+            // end::put-component-template-request-execute
+
+            // tag::put-component-template-response
+            boolean acknowledged = putComponentTemplateResponse.isAcknowledged(); // <1>
+            // end::put-component-template-response
+            assertTrue(acknowledged);
+
+            // tag::put-component-template-execute-listener
+            ActionListener<AcknowledgedResponse> listener =
+                new ActionListener<AcknowledgedResponse>() {
+                    @Override
+                    public void onResponse(AcknowledgedResponse putComponentTemplateResponse) {
+                        // <1>
+                    }
+
+                    @Override
+                    public void onFailure(Exception e) {
+                        // <2>
+                    }
+                };
+            // end::put-component-template-execute-listener
+
+            final CountDownLatch latch = new CountDownLatch(1);
+            listener = new LatchedActionListener<>(listener, latch);
+
+            // tag::put-component-template-execute-async
+            client.cluster().putComponentTemplateAsync(request, RequestOptions.DEFAULT, listener); // <1>
+            // end::put-component-template-execute-async
+
+            assertTrue(latch.await(30L, TimeUnit.SECONDS));
+        }
+    }
+
+    public void testDeleteComponentTemplate() throws Exception {
+        RestHighLevelClient client = highLevelClient();
+        {
+            PutComponentTemplateRequest request = new PutComponentTemplateRequest()
+                .name("ct1");
+
+            Settings settings = Settings.builder()
+                .put("index.number_of_shards", 3)
+                .put("index.number_of_replicas", 1)
+                .build();
+            String mappingJson = "{\n" +
+                "  \"properties\": {\n" +
+                "    \"message\": {\n" +
+                "      \"type\": \"text\"\n" +
+                "    }\n" +
+                "  }\n" +
+                "}";
+            AliasMetadata twitterAlias = AliasMetadata.builder("twitter_alias").build();
+            Template template = new Template(settings, new CompressedXContent(mappingJson), Map.of("twitter_alias", twitterAlias));
+
+            request.componentTemplate(new ComponentTemplate(template, null, null));
+            assertTrue(client.cluster().putComponentTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
+        }
+
+        // tag::delete-component-template-request
+        DeleteComponentTemplateRequest deleteRequest = new DeleteComponentTemplateRequest("ct1"); // <1>
+        // end::delete-component-template-request
+
+        // tag::delete-component-template-request-masterTimeout
+        deleteRequest.setMasterTimeout(TimeValue.timeValueMinutes(1)); // <1>
+        // end::delete-component-template-request-masterTimeout
+
+        // tag::delete-component-template-execute
+        AcknowledgedResponse deleteTemplateAcknowledge = client.cluster().deleteComponentTemplate(deleteRequest, RequestOptions.DEFAULT);
+        // end::delete-component-template-execute
+
+        // tag::delete-component-template-response
+        boolean acknowledged = deleteTemplateAcknowledge.isAcknowledged(); // <1>
+        // end::delete-component-template-response
+        assertThat(acknowledged, equalTo(true));
+
+        {
+            PutComponentTemplateRequest request = new PutComponentTemplateRequest()
+                .name("ct1");
+
+            Settings settings = Settings.builder()
+                .put("index.number_of_shards", 3)
+                .put("index.number_of_replicas", 1)
+                .build();
+            Template template = new Template(settings, null, null);
+            request.componentTemplate(new ComponentTemplate(template, null, null));
+            assertTrue(client.cluster().putComponentTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
+        }
+
+        // tag::delete-component-template-execute-listener
+        ActionListener<AcknowledgedResponse> listener =
+            new ActionListener<AcknowledgedResponse>() {
+                @Override
+                public void onResponse(AcknowledgedResponse response) {
+                    // <1>
+                }
+
+                @Override
+                public void onFailure(Exception e) {
+                    // <2>
+                }
+            };
+        // end::delete-component-template-execute-listener
+
+        final CountDownLatch latch = new CountDownLatch(1);
+        listener = new LatchedActionListener<>(listener, latch);
+
+        // tag::delete-component-template-execute-async
+        client.cluster().deleteComponentTemplateAsync(deleteRequest, RequestOptions.DEFAULT, listener); // <1>
+        // end::delete-component-template-execute-async
+
+        assertTrue(latch.await(30L, TimeUnit.SECONDS));
+    }
 }

+ 337 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java

@@ -64,28 +64,39 @@ import org.elasticsearch.client.indices.CloseIndexResponse;
 import org.elasticsearch.client.indices.CreateIndexRequest;
 import org.elasticsearch.client.indices.CreateIndexResponse;
 import org.elasticsearch.client.indices.DeleteAliasRequest;
+import org.elasticsearch.client.indices.DeleteIndexTemplateV2Request;
 import org.elasticsearch.client.indices.DetailAnalyzeResponse;
 import org.elasticsearch.client.indices.FreezeIndexRequest;
 import org.elasticsearch.client.indices.GetFieldMappingsRequest;
 import org.elasticsearch.client.indices.GetFieldMappingsResponse;
 import org.elasticsearch.client.indices.GetIndexRequest;
 import org.elasticsearch.client.indices.GetIndexResponse;
+import org.elasticsearch.client.indices.GetIndexTemplateV2Request;
 import org.elasticsearch.client.indices.GetIndexTemplatesRequest;
 import org.elasticsearch.client.indices.GetIndexTemplatesResponse;
+import org.elasticsearch.client.indices.GetIndexTemplatesV2Response;
 import org.elasticsearch.client.indices.GetMappingsRequest;
 import org.elasticsearch.client.indices.GetMappingsResponse;
 import org.elasticsearch.client.indices.IndexTemplateMetadata;
 import org.elasticsearch.client.indices.IndexTemplatesExistRequest;
+import org.elasticsearch.client.indices.PutComponentTemplateRequest;
 import org.elasticsearch.client.indices.PutIndexTemplateRequest;
+import org.elasticsearch.client.indices.PutIndexTemplateV2Request;
 import org.elasticsearch.client.indices.PutMappingRequest;
 import org.elasticsearch.client.indices.ReloadAnalyzersRequest;
 import org.elasticsearch.client.indices.ReloadAnalyzersResponse;
 import org.elasticsearch.client.indices.ReloadAnalyzersResponse.ReloadDetails;
+import org.elasticsearch.client.indices.SimulateIndexTemplateRequest;
+import org.elasticsearch.client.indices.SimulateIndexTemplateResponse;
 import org.elasticsearch.client.indices.UnfreezeIndexRequest;
 import org.elasticsearch.client.indices.rollover.RolloverRequest;
 import org.elasticsearch.client.indices.rollover.RolloverResponse;
 import org.elasticsearch.cluster.metadata.AliasMetadata;
+import org.elasticsearch.cluster.metadata.ComponentTemplate;
+import org.elasticsearch.cluster.metadata.IndexTemplateV2;
 import org.elasticsearch.cluster.metadata.MappingMetadata;
+import org.elasticsearch.cluster.metadata.Template;
+import org.elasticsearch.common.compress.CompressedXContent;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.unit.ByteSizeUnit;
 import org.elasticsearch.common.unit.ByteSizeValue;
@@ -107,8 +118,11 @@ import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+import static org.hamcrest.Matchers.containsInAnyOrder;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
 import static org.hamcrest.Matchers.nullValue;
 
 /**
@@ -2258,6 +2272,329 @@ public class IndicesClientDocumentationIT extends ESRestHighLevelClientTestCase
         assertTrue(latch.await(30L, TimeUnit.SECONDS));
     }
 
+    public void testGetIndexTemplatesV2() throws Exception {
+        RestHighLevelClient client = highLevelClient();
+        {
+            Template template = new Template(Settings.builder().put("index.number_of_shards", 3).put("index.number_of_replicas", 1).build(),
+                new CompressedXContent("{ \"properties\": { \"message\": { \"type\": \"text\" } } }"),
+                null);
+            PutIndexTemplateV2Request putRequest = new PutIndexTemplateV2Request()
+                .name("my-template")
+                .indexTemplate(
+                    new IndexTemplateV2(List.of("pattern-1", "log-*"), template, null, null, null, null)
+                );
+            assertTrue(client.indices().putIndexTemplate(putRequest, RequestOptions.DEFAULT).isAcknowledged());
+        }
+
+        // tag::get-index-templates-v2-request
+        GetIndexTemplateV2Request request = new GetIndexTemplateV2Request("my-template"); // <1>
+        request = new GetIndexTemplateV2Request("my-*"); // <2>
+        // end::get-index-templates-v2-request
+
+        // tag::get-index-templates-v2-request-masterTimeout
+        request.setMasterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
+        request.setMasterNodeTimeout("1m"); // <2>
+        // end::get-index-templates-v2-request-masterTimeout
+
+        // tag::get-index-templates-v2-execute
+        GetIndexTemplatesV2Response getTemplatesResponse = client.indices().getIndexTemplate(request, RequestOptions.DEFAULT);
+        // end::get-index-templates-v2-execute
+
+        // tag::get-index-templates-v2-response
+        Map<String, IndexTemplateV2> templates = getTemplatesResponse.getIndexTemplates(); // <1>
+        // end::get-index-templates-v2-response
+
+        assertThat(templates.size(), is(1));
+        assertThat(templates.get("my-template"), is(notNullValue()));
+
+        // tag::get-index-templates-v2-execute-listener
+        ActionListener<GetIndexTemplatesV2Response> listener =
+            new ActionListener<GetIndexTemplatesV2Response>() {
+                @Override
+                public void onResponse(GetIndexTemplatesV2Response response) {
+                    // <1>
+                }
+
+                @Override
+                public void onFailure(Exception e) {
+                    // <2>
+                }
+            };
+        // end::get-index-templates-v2-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-index-templates-v2-execute-async
+        client.indices().getIndexTemplateAsync(request, RequestOptions.DEFAULT, listener); // <1>
+        // end::get-index-templates-v2-execute-async
+
+        assertTrue(latch.await(30L, TimeUnit.SECONDS));
+    }
+
+    public void testPutIndexTemplateV2() throws Exception {
+        RestHighLevelClient client = highLevelClient();
+
+        {
+            // tag::put-index-template-v2-request
+            PutIndexTemplateV2Request request = new PutIndexTemplateV2Request()
+                .name("my-template"); // <1>
+            IndexTemplateV2 indexTemplateV2 = new IndexTemplateV2(List.of("pattern-1", "log-*"), null, null, null, null, null); // <2>
+            request.indexTemplate(indexTemplateV2);
+            assertTrue(client.indices().putIndexTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
+            // end::put-index-template-v2-request
+        }
+
+        {
+            // tag::put-index-template-v2-request-settings
+            PutIndexTemplateV2Request request = new PutIndexTemplateV2Request()
+                .name("my-template");
+            Settings settings = Settings.builder() // <1>
+                .put("index.number_of_shards", 3)
+                .put("index.number_of_replicas", 1)
+                .build();
+            Template template = new Template(settings, null, null); // <2>
+            IndexTemplateV2 indexTemplateV2 = new IndexTemplateV2(List.of("pattern-1", "log-*"), template, null, null, null, null); // <3>
+            request.indexTemplate(indexTemplateV2);
+
+            assertTrue(client.indices().putIndexTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
+            // end::put-index-template-v2-request-settings
+        }
+
+        {
+            // tag::put-index-template-v2-request-mappings-json
+            String mappingJson = "{\n" +
+                "  \"properties\": {\n" +
+                "    \"message\": {\n" +
+                "      \"type\": \"text\"\n" +
+                "    }\n" +
+                "  }\n" +
+                "}"; // <1>
+            PutIndexTemplateV2Request request = new PutIndexTemplateV2Request()
+                .name("my-template");
+            Template template = new Template(null, new CompressedXContent(mappingJson), null); // <2>
+            IndexTemplateV2 indexTemplateV2 = new IndexTemplateV2(List.of("pattern-1", "log-*"), template, null, null, null, null); // <3>
+            request.indexTemplate(indexTemplateV2);
+
+            assertTrue(client.indices().putIndexTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
+            // end::put-index-template-v2-request-mappings-json
+        }
+
+        {
+            // tag::put-index-template-v2-request-aliases
+            PutIndexTemplateV2Request request = new PutIndexTemplateV2Request()
+                .name("my-template");
+            AliasMetadata twitterAlias = AliasMetadata.builder("twitter_alias").build(); // <1>
+            AliasMetadata placeholderAlias = AliasMetadata.builder("{index}_alias").searchRouting("xyz").build(); // <2>
+            Template template = new Template(null, null, Map.of("twitter_alias", twitterAlias, "{index}_alias", placeholderAlias)); // <3>
+            IndexTemplateV2 indexTemplateV2 = new IndexTemplateV2(List.of("pattern-1", "log-*"), template, null, null, null, null); // <3>
+            request.indexTemplate(indexTemplateV2);
+
+            assertTrue(client.indices().putIndexTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
+            // end::put-index-template-v2-request-aliases
+        }
+
+        {
+            Template template = new Template(Settings.builder().put("index.number_of_replicas", 3).build(), null, null);
+            ComponentTemplate componentTemplate = new ComponentTemplate(template, null, null);
+            client.cluster().putComponentTemplate(new PutComponentTemplateRequest().name("ct1").componentTemplate(componentTemplate),
+                RequestOptions.DEFAULT);
+
+            // tag::put-index-template-v2-request-component-template
+            PutIndexTemplateV2Request request = new PutIndexTemplateV2Request()
+                .name("my-template");
+            IndexTemplateV2 indexTemplateV2 =
+                new IndexTemplateV2(List.of("pattern-1", "log-*"), null, List.of("ct1"), null, null, null); // <1>
+            request.indexTemplate(indexTemplateV2);
+
+            assertTrue(client.indices().putIndexTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
+            // end::put-index-template-v2-request-component-template
+        }
+
+        {
+            // tag::put-index-template-v2-request-priority
+            PutIndexTemplateV2Request request = new PutIndexTemplateV2Request()
+                .name("my-template");
+            IndexTemplateV2 indexTemplateV2 = new IndexTemplateV2(List.of("pattern-1", "log-*"), null, null, 20L, null, null); // <1>
+            request.indexTemplate(indexTemplateV2);
+
+            assertTrue(client.indices().putIndexTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
+            // end::put-index-template-v2-request-priority
+        }
+
+        {
+            // tag::put-index-template-v2-request-version
+            PutIndexTemplateV2Request request = new PutIndexTemplateV2Request()
+                .name("my-template");
+            IndexTemplateV2 indexTemplateV2 = new IndexTemplateV2(List.of("pattern-1", "log-*"), null, null, null, 3L, null); // <1>
+            request.indexTemplate(indexTemplateV2);
+
+            assertTrue(client.indices().putIndexTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
+            // end::put-index-template-v2-request-version
+
+            // tag::put-index-template-v2-request-create
+            request.create(true);  // <1>
+            // end::put-index-template-v2-request-create
+
+            // tag::put-index-template-v2-request-masterTimeout
+            request.setMasterTimeout(TimeValue.timeValueMinutes(1)); // <1>
+            // end::put-index-template-v2-request-masterTimeout
+
+            request.create(false); // make test happy
+
+            // tag::put-index-template-v2-execute
+            AcknowledgedResponse putTemplateResponse = client.indices().putIndexTemplate(request, RequestOptions.DEFAULT);
+            // end::put-index-template-v2-execute
+
+            // tag::put-index-template-v2-response
+            boolean acknowledged = putTemplateResponse.isAcknowledged(); // <1>
+            // end::put-index-template-v2-response
+            assertTrue(acknowledged);
+
+            // tag::put-index-template-v2-execute-listener
+            ActionListener<AcknowledgedResponse> listener =
+                new ActionListener<AcknowledgedResponse>() {
+                    @Override
+                    public void onResponse(AcknowledgedResponse putIndexTemplateResponse) {
+                        // <1>
+                    }
+
+                    @Override
+                    public void onFailure(Exception e) {
+                        // <2>
+                    }
+                };
+            // end::put-index-template-v2-execute-listener
+
+            final CountDownLatch latch = new CountDownLatch(1);
+            listener = new LatchedActionListener<>(listener, latch);
+
+            // tag::put-index-template-v2-execute-async
+            client.indices().putIndexTemplateAsync(request, RequestOptions.DEFAULT, listener); // <1>
+            // end::put-index-template-v2-execute-async
+
+            assertTrue(latch.await(30L, TimeUnit.SECONDS));
+        }
+    }
+
+    public void testDeleteIndexTemplateV2() throws Exception {
+        RestHighLevelClient client = highLevelClient();
+        {
+            PutIndexTemplateV2Request request = new PutIndexTemplateV2Request()
+                .name("my-template");
+            IndexTemplateV2 indexTemplateV2 = new IndexTemplateV2(List.of("pattern-1", "log-*"), null, null, null, null, null); // <2>
+            request.indexTemplate(indexTemplateV2);
+            assertTrue(client.indices().putIndexTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
+        }
+
+        // tag::delete-index-template-v2-request
+        DeleteIndexTemplateV2Request deleteRequest = new DeleteIndexTemplateV2Request("my-template"); // <1>
+        // end::delete-index-template-v2-request
+
+        // tag::delete-index-template-v2-request-masterTimeout
+        deleteRequest.setMasterTimeout(TimeValue.timeValueMinutes(1)); // <1>
+        // end::delete-index-template-v2-request-masterTimeout
+
+        // tag::delete-index-template-v2-execute
+        AcknowledgedResponse deleteTemplateAcknowledge = client.indices().deleteIndexTemplate(deleteRequest, RequestOptions.DEFAULT);
+        // end::delete-index-template-v2-execute
+
+        // tag::delete-index-template-v2-response
+        boolean acknowledged = deleteTemplateAcknowledge.isAcknowledged(); // <1>
+        // end::delete-index-template-v2-response
+        assertThat(acknowledged, equalTo(true));
+
+        {
+            PutIndexTemplateV2Request request = new PutIndexTemplateV2Request()
+                .name("my-template");
+            IndexTemplateV2 indexTemplateV2 = new IndexTemplateV2(List.of("pattern-1", "log-*"), null, null, null, null, null); // <2>
+            request.indexTemplate(indexTemplateV2);
+            assertTrue(client.indices().putIndexTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
+        }
+
+        // tag::delete-index-template-v2-execute-listener
+        ActionListener<AcknowledgedResponse> listener =
+            new ActionListener<AcknowledgedResponse>() {
+                @Override
+                public void onResponse(AcknowledgedResponse response) {
+                    // <1>
+                }
+
+                @Override
+                public void onFailure(Exception e) {
+                    // <2>
+                }
+            };
+        // end::delete-index-template-v2-execute-listener
+
+        final CountDownLatch latch = new CountDownLatch(1);
+        listener = new LatchedActionListener<>(listener, latch);
+
+        // tag::delete-index-template-v2-execute-async
+        client.indices().deleteIndexTemplateAsync(deleteRequest, RequestOptions.DEFAULT, listener); // <1>
+        // end::delete-index-template-v2-execute-async
+
+        assertTrue(latch.await(30L, TimeUnit.SECONDS));
+    }
+
+    public void testSimulateIndexTemplate() throws Exception {
+        RestHighLevelClient client = highLevelClient();
+
+        {
+            PutIndexTemplateV2Request request = new PutIndexTemplateV2Request()
+                .name("my-template"); // <1>
+            Template template = new Template(Settings.builder().put("index.number_of_replicas", 3).build(), null, null);
+            IndexTemplateV2 indexTemplateV2 = new IndexTemplateV2(List.of("pattern-1", "log-*"), template, null, null, null, null);
+            request.indexTemplate(indexTemplateV2);
+            assertTrue(client.indices().putIndexTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
+        }
+
+        // tag::simulate-index-template-request
+        SimulateIndexTemplateRequest simulateRequest = new SimulateIndexTemplateRequest("log-000001"); // <1>
+        PutIndexTemplateV2Request newIndexTemplateRequest = new PutIndexTemplateV2Request()
+            .name("used-for-simulation");
+        Settings settings = Settings.builder().put("index.number_of_shards", 6).build();
+        Template template = new Template(settings, null, null); // <2>
+        IndexTemplateV2 indexTemplateV2 = new IndexTemplateV2(List.of("log-*"), template, null, 90L, null, null);
+        newIndexTemplateRequest.indexTemplate(indexTemplateV2);
+
+        simulateRequest.indexTemplateV2Request(newIndexTemplateRequest); // <2>
+        // end::simulate-index-template-request
+
+        // tag::simulate-index-template-response
+        SimulateIndexTemplateResponse simulateIndexTemplateResponse = client.indices().simulateIndexTemplate(simulateRequest,
+            RequestOptions.DEFAULT);
+        assertThat(simulateIndexTemplateResponse.resolvedTemplate().settings().get("index.number_of_shards"), is("6")); // <1>
+        assertThat(simulateIndexTemplateResponse.overlappingTemplates().get("my-template"),
+            containsInAnyOrder("pattern-1", "log-*")); // <2>
+        // end::simulate-index-template-response
+
+        // tag::simulate-index-template-execute-listener
+        ActionListener<SimulateIndexTemplateResponse> listener =
+            new ActionListener<SimulateIndexTemplateResponse>() {
+                @Override
+                public void onResponse(SimulateIndexTemplateResponse response) {
+                    // <1>
+                }
+
+                @Override
+                public void onFailure(Exception e) {
+                    // <2>
+                }
+            };
+        // end::simulate-index-template-execute-listener
+
+        final CountDownLatch latch = new CountDownLatch(1);
+        listener = new LatchedActionListener<>(listener, latch);
+
+        // tag::simulate-index-template-execute-async
+        client.indices().simulateIndexTemplateAsync(simulateRequest, RequestOptions.DEFAULT, listener); // <1>
+        // end::simulate-index-template-execute-async
+
+        assertTrue(latch.await(30L, TimeUnit.SECONDS));
+    }
+
     public void testTemplatesExist() throws Exception {
         final RestHighLevelClient client = highLevelClient();
         {

+ 41 - 0
docs/java-rest/high-level/cluster/delete_component_template.asciidoc

@@ -0,0 +1,41 @@
+--
+:api: delete-component-template
+:request: DeleteComponentTemplateRequest
+:response: AcknowledgedResponse
+--
+
+[id="{upid}-{api}"]
+=== Delete Component Template API
+
+[id="{upid}-{api}-request"]
+==== Request
+
+The Delete Component Template API allows you to delete a component template.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request]
+--------------------------------------------------
+<1> The name of the component template to delete.
+
+=== Optional arguments
+The following arguments can optionally be provided:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-masterTimeout]
+--------------------------------------------------
+<1> Timeout to connect to the master node as a `TimeValue`
+
+[id="{upid}-{api}-response"]
+==== Response
+
+The returned +{response}+ indicates if the delete component template request was received.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-response]
+--------------------------------------------------
+<1> Whether or not the delete component template request was acknowledged.
+
+include::../execution.asciidoc[]

+ 42 - 0
docs/java-rest/high-level/cluster/get_component_template.asciidoc

@@ -0,0 +1,42 @@
+--
+:api: get-component-templates
+:request: GetComponentTemplatesRequest
+:response: GetComponentTemplatesResponse
+--
+
+[id="{upid}-{api}"]
+=== Get Component Templates API
+
+The Get Component Templates API allows to retrieve information about one or more component templates.
+
+[id="{upid}-{api}-request"]
+==== Get Component Templates Request
+
+A +{request}+ specifies one component template name to retrieve.
+To return all component templates omit the name altogether.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request]
+--------------------------------------------------
+<1> A single component template name
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-masterTimeout]
+--------------------------------------------------
+<1> Timeout to connect to the master node as a `TimeValue`
+<2> Timeout to connect to the master node as a `String`
+
+include::../execution.asciidoc[]
+
+[id="{upid}-{api}-response"]
+==== Get Component Templates Response
+
+The returned +{response}+ consists a map of component template names and their corresponding definition.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-response]
+--------------------------------------------------
+<1> A map of matching component template names and the corresponding definitions

+ 64 - 0
docs/java-rest/high-level/cluster/put_component_template.asciidoc

@@ -0,0 +1,64 @@
+--
+:api: put-component-template
+:request: PutComponentTemplateRequest
+:response: AcknowledgedResponse
+--
+
+[id="{upid}-{api}"]
+=== Put Component Template API
+
+The Put Component Template API allows to create or change a component template.
+
+[id="{upid}-{api}-request"]
+==== Put Component Template Request
+
+A +{request}+ specifies the name of the component template and the template definition,
+which can consist of the settings, mappings or aliases, together with a version (which
+can be used to simply component template management by external systems) and a metadata
+map consisting of user specific information.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request]
+--------------------------------------------------
+<1> The name of the component template
+<2> Template configuration containing the settings, mappings and aliases for this component template
+
+===== Version
+A component template can optionally specify a version number which can be used to simplify template
+management by external systems.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-version]
+--------------------------------------------------
+<1> The version number of the template
+
+=== Optional arguments
+The following arguments can optionally be provided:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-create]
+--------------------------------------------------
+<1> To force to only create a new template; do not overwrite the existing template
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-masterTimeout]
+--------------------------------------------------
+<1> Timeout to connect to the master node as a `TimeValue`
+
+include::../execution.asciidoc[]
+
+[id="{upid}-{api}-response"]
+==== Put Component Templates Response
+
+The returned +{response}+ allows to retrieve information about the
+executed operation as follows:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-response]
+--------------------------------------------------
+<1> Indicates whether all of the nodes have acknowledged the request

+ 41 - 0
docs/java-rest/high-level/indices/delete_index_template.asciidoc

@@ -0,0 +1,41 @@
+--
+:api: delete-index-template-v2
+:request: DeleteIndexTemplateV2Request
+:response: AcknowledgedResponse
+--
+
+[id="{upid}-{api}"]
+=== Delete Index Template V2 API
+
+[id="{upid}-{api}-request"]
+==== Request
+
+The Delete Index Template V2 API allows you to delete an index template.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request]
+--------------------------------------------------
+<1> The name of an index template to delete.
+
+=== Optional arguments
+The following arguments can optionally be provided:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-masterTimeout]
+--------------------------------------------------
+<1> Timeout to connect to the master node as a `TimeValue`
+
+[id="{upid}-{api}-response"]
+==== Response
+
+The returned +{response}+ indicates if the delete template request was received.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-response]
+--------------------------------------------------
+<1> Whether or not the delete template request was acknowledged.
+
+include::../execution.asciidoc[]

+ 43 - 0
docs/java-rest/high-level/indices/get_index_template.asciidoc

@@ -0,0 +1,43 @@
+--
+:api: get-index-templates-v2
+:request: GetIndexTemplateV2Request
+:response: GetIndexTemplatesV2Response
+--
+
+[id="{upid}-{api}"]
+=== Get Index Templates V2 API
+
+The Get Index Templates API allows to retrieve information about one or more index templates.
+
+[id="{upid}-{api}-request"]
+==== Get Index Templates V2 Request
+
+A +{request}+ specifies one, or a wildcard expression of index template names
+to get. To return all index templates, omit the name altogether or use a value of `*`.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request]
+--------------------------------------------------
+<1> A single index template name
+<2> An index template name using wildcard
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-masterTimeout]
+--------------------------------------------------
+<1> Timeout to connect to the master node as a `TimeValue`
+<2> Timeout to connect to the master node as a `String`
+
+include::../execution.asciidoc[]
+
+[id="{upid}-{api}-response"]
+==== Get Templates Response
+
+The returned +{response}+ consists a map of index template names and their corresponding configurations.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-response]
+--------------------------------------------------
+<1> A map of matching index templates names and the corresponding configurations

+ 120 - 0
docs/java-rest/high-level/indices/put_index_template.asciidoc

@@ -0,0 +1,120 @@
+--
+:api: put-index-template-v2
+:request: PutIndexTemplateV2Request
+:response: AcknowledgedResponse
+--
+
+[id="{upid}-{api}"]
+=== Put Index Template V2 API
+
+[id="{upid}-{api}-request"]
+==== Put Index Template V2 Request
+
+A +{request}+ specifies the `name` of a template and the index template configuration
+which consists of the `patterns` that control whether the template should be applied
+to the new index, and the optional mappings, settings and aliases configuration.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request]
+--------------------------------------------------
+<1> The name of the template
+<2> The index template configuration that specifies the index name patterns this template will match
+
+==== Settings
+The settings of the template will be applied to the new index whose name matches the
+template's patterns.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-settings]
+--------------------------------------------------
+<1> Settings for this template
+<2> Configure the settings on the template building block
+<3> Create the IndexTemplateV2 object that configures the index template to apply the defined template to indices matching the patterns
+
+==== Mappings
+The mapping of the template will be applied to the new index whose name matches the
+template's patterns.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-mappings-json]
+--------------------------------------------------
+<1> The mapping, provided as a JSON string
+<2> Configure the mapping on the template building block
+
+==== Aliases
+The aliases of the template will define aliasing to the index whose name matches the
+template's patterns. A placeholder `{index}` can be used in an alias of a template.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-aliases]
+--------------------------------------------------
+<1> The alias to define
+<2> The alias to define with placeholder
+<3> Configure the aliases on the template building block
+
+==== Component templates
+Component templates can be used as building blocks for specifying mappings, settings or aliases
+configurations, but they don't apply to indices themselves. To be applied to an index, the
+component templates must be specified in the `componentTemplates` list of the `IndexTemplateV2`
+index template definition object. The order in which they are specified in the list is the order
+in which the component templates are applied.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-component-template]
+--------------------------------------------------
+<1> The component template used by this index template
+
+==== Priority
+In case multiple templates match an index, the priority of matching templates determines
+the index template which will be applied.
+Index templates with higher priority "win" over index templates with lower priority.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-priority]
+--------------------------------------------------
+<1> The priority of the template
+
+==== Version
+A template can optionally specify a version number which can be used to simplify template
+management by external systems.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-version]
+--------------------------------------------------
+<1> The version number of the template
+
+==== Optional arguments
+The following arguments can optionally be provided:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-create]
+--------------------------------------------------
+<1> To force to only create a new template; do not overwrite the existing template
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request-masterTimeout]
+--------------------------------------------------
+<1> Timeout to connect to the master node as a `TimeValue`
+
+include::../execution.asciidoc[]
+
+[id="{upid}-{api}-response"]
+==== Put Index Template V2 Response
+
+The returned +{response}+ allows to retrieve information about the
+executed operation as follows:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-response]
+--------------------------------------------------
+<1> Indicates whether all of the nodes have acknowledged the request

+ 39 - 0
docs/java-rest/high-level/indices/simulate_index_template.asciidoc

@@ -0,0 +1,39 @@
+--
+:api: simulate-index-template
+:request: SimulateIndexTemplateRequest
+:response: SimulateIndexTemplateResponse
+--
+
+[id="{upid}-{api}"]
+=== Simulate Index Template API
+
+[id="{upid}-{api}-request"]
+==== Simulate Index Template Request
+
+A +{request}+ specifies the `indexName` to simulate matching against the
+templates in the system.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-request]
+--------------------------------------------------
+<1> The name of the index
+<2> Optionally, defines a new template
+
+include::../execution.asciidoc[]
+
+[id="{upid}-{api}-response"]
+==== Simulate Index Template Response
+
+The returned +{response}+ includes a resolved `Template` object containing
+the resolved settings, mappings and aliases of the index template that matched
+and would be applied to the index with the provided name (if any). It will
+also return a `Map` of index templates (both V1 and V2) names and their
+corresponding index patterns:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests-file}[{api}-response]
+--------------------------------------------------
+<1> Resolved template configuration that would be applied when creating the index with the provided name
+<2> Overlapping index templates and their corresponding index patterns

+ 7 - 0
docs/java-rest/high-level/supported-apis.asciidoc

@@ -176,6 +176,10 @@ include::indices/freeze_index.asciidoc[]
 include::indices/unfreeze_index.asciidoc[]
 include::indices/delete_template.asciidoc[]
 include::indices/reload_analyzers.asciidoc[]
+include::indices/get_index_template.asciidoc[]
+include::indices/put_index_template.asciidoc[]
+include::indices/delete_index_template.asciidoc[]
+include::indices/simulate_index_template.asciidoc[]
 
 == Cluster APIs
 
@@ -192,6 +196,9 @@ include::cluster/put_settings.asciidoc[]
 include::cluster/get_settings.asciidoc[]
 include::cluster/health.asciidoc[]
 include::cluster/remote_info.asciidoc[]
+include::cluster/get_component_template.asciidoc[]
+include::cluster/put_component_template.asciidoc[]
+include::cluster/delete_component_template.asciidoc[]
 
 == Ingest APIs
 The Java High Level REST Client supports the following Ingest APIs: