[7.x] HLRC support for Index Templates V2 (#54838) (#54932)

* HLRC support for Index Templates V2 (#54838)

* HLRC support for Index Templates V2

This change adds High Level Rest Client support for Index Templates V2.

Relates to #53101

* fixed compilation error

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Przemko Robakowski 2020-04-09 07:43:13 +02:00 committed by GitHub
parent dd73a14d11
commit afa3467957
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 757 additions and 28 deletions

View File

@ -49,6 +49,7 @@ 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.FreezeIndexRequest;
import org.elasticsearch.client.indices.GetFieldMappingsRequest;
import org.elasticsearch.client.indices.GetFieldMappingsResponse;
@ -56,10 +57,14 @@ import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.client.indices.GetIndexTemplatesRequest;
import org.elasticsearch.client.indices.GetIndexTemplatesResponse;
import org.elasticsearch.client.indices.GetIndexTemplateV2Request;
import org.elasticsearch.client.indices.GetIndexTemplatesV2Response;
import org.elasticsearch.client.indices.GetMappingsRequest;
import org.elasticsearch.client.indices.GetMappingsResponse;
import org.elasticsearch.client.indices.IndexTemplateV2ExistRequest;
import org.elasticsearch.client.indices.IndexTemplatesExistRequest;
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;
@ -1289,6 +1294,36 @@ public final class IndicesClient {
AcknowledgedResponse::fromXContent, listener, emptySet());
}
/**
* Puts an index template 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 putIndexTemplateRequest 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 AcknowledgedResponse putIndexTemplate(PutIndexTemplateV2Request putIndexTemplateRequest, RequestOptions options)
throws IOException {
return restHighLevelClient.performRequestAndParseEntity(putIndexTemplateRequest, IndicesRequestConverters::putIndexTemplate,
options, AcknowledgedResponse::fromXContent, emptySet());
}
/**
* Asynchronously puts an index template 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 putIndexTemplateRequest 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
* @return cancellable that may be used to cancel the request
*/
public Cancellable putIndexTemplateAsync(PutIndexTemplateV2Request putIndexTemplateRequest,
RequestOptions options, ActionListener<AcknowledgedResponse> listener) {
return restHighLevelClient.performRequestAsyncAndParseEntity(putIndexTemplateRequest, IndicesRequestConverters::putIndexTemplate,
options, AcknowledgedResponse::fromXContent, listener, emptySet());
}
/**
* Validate a potentially expensive query without executing it.
* <p>
@ -1344,6 +1379,36 @@ public final class IndicesClient {
org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesResponse::fromXContent, 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 options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @param getIndexTemplatesRequest the request
* @return the response
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public GetIndexTemplatesV2Response getIndexTemplate(GetIndexTemplateV2Request getIndexTemplatesRequest,
RequestOptions options) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(getIndexTemplatesRequest, IndicesRequestConverters::getIndexTemplates,
options, GetIndexTemplatesV2Response::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
* @return cancellable that may be used to cancel the request
*/
public Cancellable getIndexTemplateAsync(GetIndexTemplateV2Request getIndexTemplatesRequest, RequestOptions options,
ActionListener<GetIndexTemplatesV2Response> listener) {
return restHighLevelClient.performRequestAsyncAndParseEntity(getIndexTemplatesRequest,
IndicesRequestConverters::getIndexTemplates, options, GetIndexTemplatesV2Response::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
@ -1354,7 +1419,7 @@ public final class IndicesClient {
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public GetIndexTemplatesResponse getIndexTemplate(GetIndexTemplatesRequest getIndexTemplatesRequest,
RequestOptions options) throws IOException {
RequestOptions options) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(getIndexTemplatesRequest,
IndicesRequestConverters::getTemplates,
options, GetIndexTemplatesResponse::fromXContent, emptySet());
@ -1429,6 +1494,37 @@ public final class IndicesClient {
RestHighLevelClient::convertExistsResponse, listener, emptySet());
}
/**
* Uses the Index Templates API to determine if index templates exist
*
* @param indexTemplatesRequest the request
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @return true if any index templates in the request exist, false otherwise
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public boolean existsIndexTemplate(IndexTemplateV2ExistRequest indexTemplatesRequest,
RequestOptions options) throws IOException {
return restHighLevelClient.performRequest(indexTemplatesRequest,
IndicesRequestConverters::templatesExist, options,
RestHighLevelClient::convertExistsResponse, emptySet());
}
/**
* Uses the Index Templates API to determine if index templates exist
* @param indexTemplatesExistRequest 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. The listener will be called with the value {@code true}
* @return cancellable that may be used to cancel the request
*/
public Cancellable existsIndexTemplateAsync(IndexTemplateV2ExistRequest indexTemplatesExistRequest,
RequestOptions options,
ActionListener<Boolean> listener) {
return restHighLevelClient.performRequestAsync(indexTemplatesExistRequest,
IndicesRequestConverters::templatesExist, options,
RestHighLevelClient::convertExistsResponse, listener, emptySet());
}
/**
* Calls the analyze API
*
@ -1535,6 +1631,35 @@ public final class IndicesClient {
options, AcknowledgedResponse::fromXContent, listener, emptySet());
}
/**
* Delete an index template 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 request the request
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public AcknowledgedResponse deleteIndexTemplate(DeleteIndexTemplateV2Request request, RequestOptions options) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(request, IndicesRequestConverters::deleteIndexTemplate,
options, AcknowledgedResponse::fromXContent, emptySet());
}
/**
* Asynchronously delete an index template 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 request 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
* @return cancellable that may be used to cancel the request
*/
public Cancellable deleteIndexTemplateAsync(DeleteIndexTemplateV2Request request, RequestOptions options,
ActionListener<AcknowledgedResponse> listener) {
return restHighLevelClient.performRequestAsyncAndParseEntity(request, IndicesRequestConverters::deleteIndexTemplate,
options, AcknowledgedResponse::fromXContent, listener, emptySet());
}
/**
* Synchronously calls the _reload_search_analyzers API
*

View File

@ -42,13 +42,17 @@ import org.elasticsearch.client.indices.AnalyzeRequest;
import org.elasticsearch.client.indices.CloseIndexRequest;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.DeleteAliasRequest;
import org.elasticsearch.client.indices.DeleteIndexTemplateV2Request;
import org.elasticsearch.client.indices.FreezeIndexRequest;
import org.elasticsearch.client.indices.GetFieldMappingsRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexTemplatesRequest;
import org.elasticsearch.client.indices.GetIndexTemplateV2Request;
import org.elasticsearch.client.indices.GetMappingsRequest;
import org.elasticsearch.client.indices.IndexTemplateV2ExistRequest;
import org.elasticsearch.client.indices.IndexTemplatesExistRequest;
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.ResizeRequest;
@ -580,6 +584,23 @@ final class IndicesRequestConverters {
return request;
}
static Request putIndexTemplate(PutIndexTemplateV2Request putIndexTemplateRequest) throws IOException {
String endpoint = new RequestConverters.EndpointBuilder().addPathPartAsIs("_index_template")
.addPathPart(putIndexTemplateRequest.name()).build();
Request request = new Request(HttpPut.METHOD_NAME, endpoint);
RequestConverters.Params params = new RequestConverters.Params();
params.withMasterTimeout(putIndexTemplateRequest.masterNodeTimeout());
if (putIndexTemplateRequest.create()) {
params.putParam("create", Boolean.TRUE.toString());
}
if (Strings.hasText(putIndexTemplateRequest.cause())) {
params.putParam("cause", putIndexTemplateRequest.cause());
}
request.addParameters(params.asMap());
request.setEntity(RequestConverters.createEntity(putIndexTemplateRequest, RequestConverters.REQUEST_BODY_CONTENT_TYPE));
return request;
}
static Request validateQuery(ValidateQueryRequest validateQueryRequest) throws IOException {
String[] indices = validateQueryRequest.indices() == null ? Strings.EMPTY_ARRAY : validateQueryRequest.indices();
String[] types = validateQueryRequest.types() == null || indices.length <= 0 ? Strings.EMPTY_ARRAY : validateQueryRequest.types();
@ -632,6 +653,19 @@ final class IndicesRequestConverters {
return request;
}
static Request getIndexTemplates(GetIndexTemplateV2Request getIndexTemplatesRequest) {
final String endpoint = new RequestConverters.EndpointBuilder()
.addPathPartAsIs("_index_template")
.addPathPart(getIndexTemplatesRequest.name())
.build();
final Request request = new Request(HttpGet.METHOD_NAME, endpoint);
final RequestConverters.Params params = new RequestConverters.Params();
params.withLocal(getIndexTemplatesRequest.isLocal());
params.withMasterTimeout(getIndexTemplatesRequest.getMasterNodeTimeout());
request.addParameters(params.asMap());
return request;
}
static Request templatesExist(IndexTemplatesExistRequest indexTemplatesExistRequest) {
final String endpoint = new RequestConverters.EndpointBuilder()
.addPathPartAsIs("_template")
@ -645,6 +679,19 @@ final class IndicesRequestConverters {
return request;
}
static Request templatesExist(IndexTemplateV2ExistRequest indexTemplatesExistRequest) {
final String endpoint = new RequestConverters.EndpointBuilder()
.addPathPartAsIs("_index_template")
.addPathPart(indexTemplatesExistRequest.name())
.build();
final Request request = new Request(HttpHead.METHOD_NAME, endpoint);
final RequestConverters.Params params = new RequestConverters.Params();
params.withLocal(indexTemplatesExistRequest.isLocal());
params.withMasterTimeout(indexTemplatesExistRequest.getMasterNodeTimeout());
request.addParameters(params.asMap());
return request;
}
static Request analyze(AnalyzeRequest request) throws IOException {
RequestConverters.EndpointBuilder builder = new RequestConverters.EndpointBuilder();
String index = request.index();
@ -691,6 +738,16 @@ final class IndicesRequestConverters {
return request;
}
static Request deleteIndexTemplate(DeleteIndexTemplateV2Request deleteIndexTemplateRequest) {
String name = deleteIndexTemplateRequest.getName();
String endpoint = new RequestConverters.EndpointBuilder().addPathPartAsIs("_index_template").addPathPart(name).build();
Request request = new Request(HttpDelete.METHOD_NAME, endpoint);
RequestConverters.Params params = new RequestConverters.Params();
params.withMasterTimeout(deleteIndexTemplateRequest.masterNodeTimeout());
request.addParameters(params.asMap());
return request;
}
static Request reloadAnalyzers(ReloadAnalyzersRequest reloadAnalyzersRequest) {
String endpoint = RequestConverters.endpoint(reloadAnalyzersRequest.getIndices(), "_reload_search_analyzers");
Request request = new Request(HttpPost.METHOD_NAME, endpoint);

View File

@ -0,0 +1,35 @@
/*
* 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.client.indices;
import org.elasticsearch.client.TimedRequest;
public class DeleteIndexTemplateV2Request extends TimedRequest {
private final String name;
public DeleteIndexTemplateV2Request(String name) {
this.name = name;
}
public String getName() {
return name;
}
}

View File

@ -0,0 +1,80 @@
/*
* 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.client.indices;
import org.elasticsearch.client.TimedRequest;
import org.elasticsearch.client.Validatable;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.unit.TimeValue;
/**
* A request to read the content of index templates
*/
public class GetIndexTemplateV2Request implements Validatable {
private final String name;
private TimeValue masterNodeTimeout = TimedRequest.DEFAULT_MASTER_NODE_TIMEOUT;
private boolean local = false;
/**
* Create a request to read the content of index template. If no template name is provided, all templates will
* be read
*
* @param name the name of template to read
*/
public GetIndexTemplateV2Request(String name) {
this.name = name;
}
/**
* @return the name of index template this request is requesting
*/
public String name() {
return name;
}
/**
* @return the timeout for waiting for the master node to respond
*/
public TimeValue getMasterNodeTimeout() {
return masterNodeTimeout;
}
public void setMasterNodeTimeout(@Nullable TimeValue masterNodeTimeout) {
this.masterNodeTimeout = masterNodeTimeout;
}
public void setMasterNodeTimeout(String masterNodeTimeout) {
final TimeValue timeValue = TimeValue.parseTimeValue(masterNodeTimeout, getClass().getSimpleName() + ".masterNodeTimeout");
setMasterNodeTimeout(timeValue);
}
/**
* @return true if this request is to read from the local cluster state, rather than the master node - false otherwise
*/
public boolean isLocal() {
return local;
}
public void setLocal(boolean local) {
this.local = local;
}
}

View File

@ -0,0 +1,108 @@
/*
* 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.client.indices;
import org.elasticsearch.cluster.metadata.IndexTemplateV2;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
public class GetIndexTemplatesV2Response {
public static final ParseField NAME = new ParseField("name");
public static final ParseField INDEX_TEMPLATES = new ParseField("index_templates");
public static final ParseField INDEX_TEMPLATE = new ParseField("index_template");
@SuppressWarnings("unchecked")
private static final ConstructingObjectParser<Map<String, IndexTemplateV2>, Void> PARSER =
new ConstructingObjectParser<>("index_templates", false,
a -> ((List<NamedIndexTemplate>) a[0]).stream().collect(Collectors.toMap(n -> n.name, n -> n.indexTemplate,
(n1, n2) -> n1, LinkedHashMap::new)));
private static final ConstructingObjectParser<NamedIndexTemplate, Void> INNER_PARSER =
new ConstructingObjectParser<>("named_index_template", false,
a -> new NamedIndexTemplate((String) a[0], (IndexTemplateV2) a[1]));
static {
INNER_PARSER.declareString(ConstructingObjectParser.constructorArg(), NAME);
INNER_PARSER.declareObject(ConstructingObjectParser.constructorArg(), IndexTemplateV2.PARSER, INDEX_TEMPLATE);
PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), INNER_PARSER, INDEX_TEMPLATES);
}
private static class NamedIndexTemplate {
String name;
IndexTemplateV2 indexTemplate;
private NamedIndexTemplate(String name, IndexTemplateV2 indexTemplate) {
this.name = name;
this.indexTemplate = indexTemplate;
}
}
@Override
public String toString() {
return "GetIndexTemplatesResponse [indexTemplates=" + indexTemplates + "]";
}
private final Map<String, IndexTemplateV2> indexTemplates;
GetIndexTemplatesV2Response(Map<String, IndexTemplateV2> indexTemplates) {
this.indexTemplates = Collections.unmodifiableMap(new LinkedHashMap<>(indexTemplates));
}
public Map<String, IndexTemplateV2> getIndexTemplates() {
return indexTemplates;
}
public static GetIndexTemplatesV2Response fromXContent(XContentParser parser) throws IOException {
return new GetIndexTemplatesV2Response(PARSER.apply(parser, null));
}
@Override
public int hashCode() {
return Objects.hash(indexTemplates);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
GetIndexTemplatesV2Response other = (GetIndexTemplatesV2Response) obj;
return Objects.equals(indexTemplates, other.indexTemplates);
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.client.indices;
import org.elasticsearch.common.Strings;
/**
* A request to check for the existence of index templates
*/
public class IndexTemplateV2ExistRequest extends GetComponentTemplatesRequest {
/**
* Create a request to check for the existence of index template. Name must be provided
*
* @param name the name of template to check for the existence of
*/
public IndexTemplateV2ExistRequest(String name) {
super(name);
if (Strings.isNullOrEmpty(name)) {
throw new IllegalArgumentException("must provide index template name");
}
}
}

View File

@ -0,0 +1,100 @@
/*
* 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.client.indices;
import org.elasticsearch.client.TimedRequest;
import org.elasticsearch.cluster.metadata.IndexTemplateV2;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
/**
* A request to create an index template.
*/
public class PutIndexTemplateV2Request extends TimedRequest implements ToXContentObject {
private String name;
private String cause = "";
private boolean create;
private IndexTemplateV2 indexTemplate;
/**
* Sets the name of the index template.
*/
public PutIndexTemplateV2Request name(String name) {
if (Strings.isNullOrEmpty(name)) {
throw new IllegalArgumentException("name cannot be null or empty");
}
this.name = name;
return this;
}
/**
* The name of the index template.
*/
public String name() {
return this.name;
}
/**
* Set to {@code true} to force only creation, not an update of an index template. If it already
* exists, it will fail with an {@link IllegalArgumentException}.
*/
public PutIndexTemplateV2Request create(boolean create) {
this.create = create;
return this;
}
public boolean create() {
return create;
}
/**
* The index template to create.
*/
public PutIndexTemplateV2Request indexTemplate(IndexTemplateV2 indexTemplate) {
this.indexTemplate = indexTemplate;
return this;
}
/**
* The cause for this index template creation.
*/
public PutIndexTemplateV2Request cause(String cause) {
this.cause = cause;
return this;
}
public String cause() {
return this.cause;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
if (indexTemplate != null) {
indexTemplate.toXContent(builder, params);
}
return builder;
}
}

View File

@ -62,6 +62,7 @@ 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.FreezeIndexRequest;
import org.elasticsearch.client.indices.GetFieldMappingsRequest;
import org.elasticsearch.client.indices.GetFieldMappingsResponse;
@ -69,11 +70,15 @@ import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.client.indices.GetIndexTemplatesRequest;
import org.elasticsearch.client.indices.GetIndexTemplatesResponse;
import org.elasticsearch.client.indices.GetIndexTemplateV2Request;
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.IndexTemplateV2ExistRequest;
import org.elasticsearch.client.indices.IndexTemplatesExistRequest;
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;
@ -82,10 +87,13 @@ 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.IndexMetadata;
import org.elasticsearch.cluster.metadata.IndexTemplateV2;
import org.elasticsearch.cluster.metadata.MappingMetadata;
import org.elasticsearch.cluster.metadata.Template;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.ValidationException;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.ByteSizeUnit;
@ -2021,4 +2029,50 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
assertThat(aliasExists(index, alias), equalTo(false));
assertThat(aliasExists(index, alias2), equalTo(true));
}
public void testIndexTemplates() throws Exception {
String templateName = "my-template";
Settings settings = Settings.builder().put("index.number_of_shards", 1).build();
CompressedXContent mappings = new CompressedXContent("{\"properties\":{\"host_name\":{\"type\":\"keyword\"}}}");
AliasMetadata alias = AliasMetadata.builder("alias").writeIndex(true).build();
Template template = new Template(settings, mappings, Collections.singletonMap("alias", alias));
List<String> pattern = Collections.singletonList("pattern");
IndexTemplateV2 indexTemplate = new IndexTemplateV2(pattern, template, Collections.emptyList(), 1L, 1L, new HashMap<>());
PutIndexTemplateV2Request putIndexTemplateV2Request =
new PutIndexTemplateV2Request().name(templateName).create(true).indexTemplate(indexTemplate);
AcknowledgedResponse response = execute(putIndexTemplateV2Request,
highLevelClient().indices()::putIndexTemplate, highLevelClient().indices()::putIndexTemplateAsync);
assertThat(response.isAcknowledged(), equalTo(true));
IndexTemplateV2ExistRequest indexTemplateV2ExistRequest = new IndexTemplateV2ExistRequest(templateName);
boolean exist = execute(indexTemplateV2ExistRequest,
highLevelClient().indices()::existsIndexTemplate, highLevelClient().indices()::existsIndexTemplateAsync);
assertTrue(exist);
GetIndexTemplateV2Request getIndexTemplateV2Request = new GetIndexTemplateV2Request(templateName);
GetIndexTemplatesV2Response getResponse = execute(getIndexTemplateV2Request,
highLevelClient().indices()::getIndexTemplate, highLevelClient().indices()::getIndexTemplateAsync);
assertThat(getResponse.getIndexTemplates().size(), equalTo(1));
assertThat(getResponse.getIndexTemplates().containsKey(templateName), equalTo(true));
assertThat(getResponse.getIndexTemplates().get(templateName), equalTo(indexTemplate));
DeleteIndexTemplateV2Request deleteIndexTemplateV2Request = new DeleteIndexTemplateV2Request(templateName);
response = execute(deleteIndexTemplateV2Request, highLevelClient().indices()::deleteIndexTemplate,
highLevelClient().indices()::deleteIndexTemplateAsync);
assertThat(response.isAcknowledged(), equalTo(true));
ElasticsearchStatusException statusException = expectThrows(ElasticsearchStatusException.class,
() -> execute(getIndexTemplateV2Request,
highLevelClient().indices()::getIndexTemplate, highLevelClient().indices()::getIndexTemplateAsync));
assertThat(statusException.status(), equalTo(RestStatus.NOT_FOUND));
exist = execute(indexTemplateV2ExistRequest,
highLevelClient().indices()::existsIndexTemplate, highLevelClient().indices()::existsIndexTemplateAsync);
assertFalse(exist);
}
}

View File

@ -861,8 +861,6 @@ public class RestHighLevelClientTests extends ESTestCase {
"indices.create_data_stream",
"indices.get_data_streams",
"indices.delete_data_stream",
"indices.put_index_template",
"indices.delete_index_template"
};
//These API are not required for high-level client feature completeness
String[] notRequiredApi = new String[] {

View File

@ -47,12 +47,37 @@ public class GetComponentTemplatesResponseTests extends ESTestCase {
.test();
}
public static Template randomTemplate() {
Settings settings = null;
CompressedXContent mappings = null;
Map<String, AliasMetadata> aliases = null;
if (randomBoolean()) {
settings = randomSettings();
}
if (randomBoolean()) {
mappings = randomMappings();
}
if (randomBoolean()) {
aliases = randomAliases();
}
return new Template(settings, mappings, aliases);
}
public static Map<String, Object> randomMeta() {
if (randomBoolean()) {
return Collections.singletonMap(randomAlphaOfLength(4), randomAlphaOfLength(4));
} else {
return Collections.singletonMap(randomAlphaOfLength(5),
Collections.singletonMap(randomAlphaOfLength(4), randomAlphaOfLength(4)));
}
}
private static GetComponentTemplatesResponse createTestInstance() {
Map<String, ComponentTemplate> templates = new HashMap<>();
if (randomBoolean()) {
int count = randomInt(10);
for (int i = 0; i < count; i++) {
templates.put(randomAlphaOfLength(10), randomTemplate());
templates.put(randomAlphaOfLength(10), randomComponentTemplate());
}
}
return new GetComponentTemplatesResponse(templates);
@ -72,20 +97,8 @@ public class GetComponentTemplatesResponseTests extends ESTestCase {
builder.endObject();
}
private static ComponentTemplate randomTemplate() {
Settings settings = null;
CompressedXContent mappings = null;
Map<String, AliasMetadata> aliases = null;
if (randomBoolean()) {
settings = randomSettings();
}
if (randomBoolean()) {
mappings = randomMappings();
}
if (randomBoolean()) {
aliases = randomAliases();
}
Template template = new Template(settings, mappings, aliases);
private static ComponentTemplate randomComponentTemplate() {
Template template = randomTemplate();
Map<String, Object> meta = null;
if (randomBoolean()) {
@ -119,13 +132,4 @@ public class GetComponentTemplatesResponseTests extends ESTestCase {
.put(randomAlphaOfLength(4), randomAlphaOfLength(10))
.build();
}
private static Map<String, Object> randomMeta() {
if (randomBoolean()) {
return Collections.singletonMap(randomAlphaOfLength(4), randomAlphaOfLength(4));
} else {
return Collections.singletonMap(randomAlphaOfLength(5),
Collections.singletonMap(randomAlphaOfLength(4), randomAlphaOfLength(4)));
}
}
}

View File

@ -0,0 +1,89 @@
/*
* 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.client.indices;
import org.elasticsearch.cluster.metadata.IndexTemplateV2;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.client.indices.GetComponentTemplatesResponseTests.randomMeta;
import static org.elasticsearch.client.indices.GetComponentTemplatesResponseTests.randomTemplate;
import static org.elasticsearch.test.AbstractXContentTestCase.xContentTester;
public class GetIndexTemplatesV2ResponseTests extends ESTestCase {
public void testFromXContent() throws Exception {
xContentTester(
this::createParser,
GetIndexTemplatesV2ResponseTests::createTestInstance,
GetIndexTemplatesV2ResponseTests::toXContent,
GetIndexTemplatesV2Response::fromXContent)
.supportsUnknownFields(true)
.randomFieldsExcludeFilter(a -> true)
.test();
}
private static GetIndexTemplatesV2Response createTestInstance() {
Map<String, IndexTemplateV2> templates = new HashMap<>();
if (randomBoolean()) {
int count = randomInt(10);
for (int i = 0; i < count; i++) {
templates.put(randomAlphaOfLength(10), randomIndexTemplate());
}
}
return new GetIndexTemplatesV2Response(templates);
}
private static void toXContent(GetIndexTemplatesV2Response response, XContentBuilder builder) throws IOException {
builder.startObject();
builder.startArray("index_templates");
for (Map.Entry<String, IndexTemplateV2> e : response.getIndexTemplates().entrySet()) {
builder.startObject();
builder.field("name", e.getKey());
builder.field("index_template");
e.getValue().toXContent(builder, null);
builder.endObject();
}
builder.endArray();
builder.endObject();
}
private static IndexTemplateV2 randomIndexTemplate() {
List<String> patterns = Arrays.asList(generateRandomStringArray(10, 10, false, false));
List<String> composedOf = null;
Map<String, Object> meta = null;
if (randomBoolean()) {
composedOf = Arrays.asList(generateRandomStringArray(10, 10, false, false));
}
if (randomBoolean()) {
meta = randomMeta();
}
Long priority = randomBoolean() ? null : randomNonNegativeLong();
Long version = randomBoolean() ? null : randomNonNegativeLong();
return new IndexTemplateV2(patterns, randomTemplate(), composedOf, priority, version, meta);
}
}

View File

@ -0,0 +1,39 @@
{
"indices.exists_index_template":{
"documentation":{
"url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-templates.html",
"description":"Returns information about whether a particular index template exists."
},
"stability":"stable",
"url":{
"paths":[
{
"path":"/_index_template/{name}",
"methods":[
"HEAD"
],
"parts":{
"name":{
"type":"string",
"description":"The name of the template"
}
}
}
]
},
"params":{
"flat_settings":{
"type":"boolean",
"description":"Return settings in flat format (default: false)"
},
"master_timeout":{
"type":"time",
"description":"Explicit operation timeout for connection to master node"
},
"local":{
"type":"boolean",
"description":"Return local information, do not retrieve the state from master node (default: false)"
}
}
}
}

View File

@ -51,7 +51,7 @@ public class IndexTemplateV2 extends AbstractDiffable<IndexTemplateV2> implement
private static final ParseField METADATA = new ParseField("_meta");
@SuppressWarnings("unchecked")
private static final ConstructingObjectParser<IndexTemplateV2, Void> PARSER = new ConstructingObjectParser<>("index_template", false,
public static final ConstructingObjectParser<IndexTemplateV2, Void> PARSER = new ConstructingObjectParser<>("index_template", false,
a -> new IndexTemplateV2((List<String>) a[0],
(Template) a[1],
(List<String>) a[2],