Component templates.

Original Pull Request #2534
Closes #1458
This commit is contained in:
Peter-Josef Meisch 2023-04-18 20:58:07 +02:00 committed by GitHub
parent df7a614638
commit bbd5e8119a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 2284 additions and 411 deletions

View File

@ -14,3 +14,13 @@ But besides the values defined by the enum, it is possible to have similarities
Therefore, the annotation property was changed from the type of the enum to a simple `String`.
The previous enum values like `Similarity.Default` do still exist as String constants, so existing code will compile unmodified.
Adaptions are necessary when this enum was used at other places than as a property of the `@Field` annotation.
[[elasticsearch-migration-guide-5.0-5.1.deprecations]]
== Deprecations
=== template functions
The functions in the `IndexOperations` and `ReactiverIndexOperations` to manage index templates that were introduced in Spring Data Elasticsearch 4.1
have been deprecated. They were using the old Elasticsearch API that was deprecated in Elasticsearch version 7.8.
Please use the new functions that are based on the compsable index template API instead.

View File

@ -115,16 +115,20 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate {
// region child templates
@Override
public IndexOperations indexOps(Class<?> clazz) {
return new IndicesTemplate(client.indices(), elasticsearchConverter, clazz);
return new IndicesTemplate(client.indices(), getClusterTemplate(), elasticsearchConverter, clazz);
}
@Override
public IndexOperations indexOps(IndexCoordinates index) {
return new IndicesTemplate(client.indices(), elasticsearchConverter, index);
return new IndicesTemplate(client.indices(), getClusterTemplate(), elasticsearchConverter, index);
}
@Override
public ClusterOperations cluster() {
return getClusterTemplate();
}
private ClusterTemplate getClusterTemplate() {
return new ClusterTemplate(client.cluster(), elasticsearchConverter);
}
// endregion

View File

@ -37,15 +37,15 @@ import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.ResourceUtil;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.index.AliasActions;
import org.springframework.data.elasticsearch.core.index.AliasData;
import org.springframework.data.elasticsearch.core.index.*;
import org.springframework.data.elasticsearch.core.index.DeleteIndexTemplateRequest;
import org.springframework.data.elasticsearch.core.index.DeleteTemplateRequest;
import org.springframework.data.elasticsearch.core.index.ExistsIndexTemplateRequest;
import org.springframework.data.elasticsearch.core.index.ExistsTemplateRequest;
import org.springframework.data.elasticsearch.core.index.GetIndexTemplateRequest;
import org.springframework.data.elasticsearch.core.index.GetTemplateRequest;
import org.springframework.data.elasticsearch.core.index.MappingBuilder;
import org.springframework.data.elasticsearch.core.index.PutIndexTemplateRequest;
import org.springframework.data.elasticsearch.core.index.PutTemplateRequest;
import org.springframework.data.elasticsearch.core.index.Settings;
import org.springframework.data.elasticsearch.core.index.TemplateData;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.lang.Nullable;
@ -62,30 +62,37 @@ public class IndicesTemplate extends ChildTemplate<ElasticsearchTransport, Elast
private static final Logger LOGGER = LoggerFactory.getLogger(IndicesTemplate.class);
// we need a cluster client as well because ES has put some methods from the indices API into the cluster client
// (component templates)
private final ClusterTemplate clusterTemplate;
protected final ElasticsearchConverter elasticsearchConverter;
@Nullable protected final Class<?> boundClass;
@Nullable protected final IndexCoordinates boundIndex;
public IndicesTemplate(ElasticsearchIndicesClient client, ElasticsearchConverter elasticsearchConverter,
Class<?> boundClass) {
public IndicesTemplate(ElasticsearchIndicesClient client, ClusterTemplate clusterTemplate,
ElasticsearchConverter elasticsearchConverter, Class<?> boundClass) {
super(client, elasticsearchConverter);
Assert.notNull(clusterTemplate, "cluster must not be null");
Assert.notNull(elasticsearchConverter, "elasticsearchConverter must not be null");
Assert.notNull(boundClass, "boundClass may not be null");
this.clusterTemplate = clusterTemplate;
this.elasticsearchConverter = elasticsearchConverter;
this.boundClass = boundClass;
this.boundIndex = null;
}
public IndicesTemplate(ElasticsearchIndicesClient client, ElasticsearchConverter elasticsearchConverter,
IndexCoordinates boundIndex) {
public IndicesTemplate(ElasticsearchIndicesClient client, ClusterTemplate clusterTemplate,
ElasticsearchConverter elasticsearchConverter, IndexCoordinates boundIndex) {
super(client, elasticsearchConverter);
Assert.notNull(clusterTemplate, "cluster must not be null");
Assert.notNull(elasticsearchConverter, "elasticsearchConverter must not be null");
Assert.notNull(boundIndex, "boundIndex must not be null");
this.clusterTemplate = clusterTemplate;
this.elasticsearchConverter = elasticsearchConverter;
this.boundClass = null;
this.boundIndex = boundIndex;
@ -338,6 +345,87 @@ public class IndicesTemplate extends ChildTemplate<ElasticsearchTransport, Elast
return execute(client -> client.deleteTemplate(deleteTemplateRequestES)).acknowledged();
}
@Override
public boolean putIndexTemplate(PutIndexTemplateRequest putIndexTemplateRequest) {
co.elastic.clients.elasticsearch.indices.PutIndexTemplateRequest putIndexTemplateRequestES = requestConverter
.indicesPutIndexTemplateRequest(putIndexTemplateRequest);
return execute(client -> client.putIndexTemplate(putIndexTemplateRequestES)).acknowledged();
}
@Override
public boolean existsIndexTemplate(ExistsIndexTemplateRequest existsIndexTemplateRequest) {
Assert.notNull(existsIndexTemplateRequest, "existsIndexTemplateRequest must not be null");
co.elastic.clients.elasticsearch.indices.ExistsIndexTemplateRequest existsTemplateRequestES = requestConverter
.indicesExistsIndexTemplateRequest(existsIndexTemplateRequest);
return execute(client -> client.existsIndexTemplate(existsTemplateRequestES)).value();
}
@Override
public List<TemplateResponse> getIndexTemplate(GetIndexTemplateRequest getIndexTemplateRequest) {
Assert.notNull(getIndexTemplateRequest, "getIndexTemplateRequest must not be null");
co.elastic.clients.elasticsearch.indices.GetIndexTemplateRequest getIndexTemplateRequestES = requestConverter
.indicesGetIndexTemplateRequest(getIndexTemplateRequest);
var getIndexTemplateResponse = execute(client -> client.getIndexTemplate(getIndexTemplateRequestES));
return responseConverter.getIndexTemplates(getIndexTemplateResponse);
}
@Override
public boolean deleteIndexTemplate(DeleteIndexTemplateRequest deleteIndexTemplateRequest) {
Assert.notNull(deleteIndexTemplateRequest, "deleteIndexTemplateRequest must not be null");
co.elastic.clients.elasticsearch.indices.DeleteIndexTemplateRequest deleteIndexTemplateRequestES = requestConverter
.indicesDeleteIndexTemplateRequest(deleteIndexTemplateRequest);
return execute(client -> client.deleteIndexTemplate(deleteIndexTemplateRequestES)).acknowledged();
}
@Override
public boolean putComponentTemplate(PutComponentTemplateRequest putComponentTemplateRequest) {
Assert.notNull(putComponentTemplateRequest, "putComponentTemplateRequest must not be null");
co.elastic.clients.elasticsearch.cluster.PutComponentTemplateRequest putComponentTemplateRequestES = requestConverter
.clusterPutComponentTemplateRequest(putComponentTemplateRequest);
// the new Elasticsearch client has this call in the cluster index
return clusterTemplate.execute(client -> client.putComponentTemplate(putComponentTemplateRequestES)).acknowledged();
}
@Override
public boolean existsComponentTemplate(ExistsComponentTemplateRequest existsComponentTemplateRequest) {
Assert.notNull(existsComponentTemplateRequest, "existsComponentTemplateRequest must not be null");
co.elastic.clients.elasticsearch.cluster.ExistsComponentTemplateRequest existsComponentTemplateRequestES = requestConverter
.clusterExistsComponentTemplateRequest(existsComponentTemplateRequest);
return clusterTemplate.execute(client -> client.existsComponentTemplate(existsComponentTemplateRequestES)).value();
}
@Override
public List<TemplateResponse> getComponentTemplate(GetComponentTemplateRequest getComponentTemplateRequest) {
co.elastic.clients.elasticsearch.cluster.GetComponentTemplateRequest getComponentTemplateRequestES = requestConverter
.clusterGetComponentTemplateRequest(getComponentTemplateRequest);
var response = clusterTemplate.execute(client -> client.getComponentTemplate(getComponentTemplateRequestES));
return responseConverter.clusterGetComponentTemplates(response);
}
@Override
public boolean deleteComponentTemplate(DeleteComponentTemplateRequest deleteComponentTemplateRequest) {
Assert.notNull(deleteComponentTemplateRequest, "deleteComponentTemplateRequest must not be null");
co.elastic.clients.elasticsearch.cluster.DeleteComponentTemplateRequest deleteComponentTemplateRequestES = requestConverter
.clusterDeleteComponentTemplateRequest(deleteComponentTemplateRequest);
return clusterTemplate.execute(client -> client.deleteComponentTemplate(deleteComponentTemplateRequestES))
.acknowledged();
}
@Override
public List<IndexInformation> getInformation(IndexCoordinates indexCoordinates) {

View File

@ -20,8 +20,8 @@ import co.elastic.clients.elasticsearch.cluster.HealthResponse;
import co.elastic.clients.transport.ElasticsearchTransport;
import reactor.core.publisher.Mono;
import org.springframework.data.elasticsearch.client.erhlc.ReactiveClusterOperations;
import org.springframework.data.elasticsearch.core.cluster.ClusterHealth;
import org.springframework.data.elasticsearch.core.cluster.ReactiveClusterOperations;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
/**

View File

@ -16,10 +16,10 @@
package org.springframework.data.elasticsearch.client.elc;
import co.elastic.clients.ApiClient;
import co.elastic.clients.elasticsearch.cluster.HealthRequest;
import co.elastic.clients.elasticsearch.cluster.HealthResponse;
import co.elastic.clients.elasticsearch.cluster.*;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.TransportOptions;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import co.elastic.clients.util.ObjectBuilder;
import reactor.core.publisher.Mono;
@ -53,4 +53,47 @@ public class ReactiveElasticsearchClusterClient
public Mono<HealthResponse> health(Function<HealthRequest.Builder, ObjectBuilder<HealthRequest>> fn) {
return health(fn.apply(new HealthRequest.Builder()).build());
}
public Mono<PutComponentTemplateResponse> putComponentTemplate(
PutComponentTemplateRequest putComponentTemplateRequest) {
return Mono.fromFuture(transport.performRequestAsync(putComponentTemplateRequest,
PutComponentTemplateRequest._ENDPOINT, transportOptions));
}
public Mono<PutComponentTemplateResponse> putComponentTemplate(
Function<PutComponentTemplateRequest.Builder, ObjectBuilder<PutComponentTemplateRequest>> fn) {
return putComponentTemplate(fn.apply(new PutComponentTemplateRequest.Builder()).build());
}
public Mono<GetComponentTemplateResponse> getComponentTemplate(
GetComponentTemplateRequest getComponentTemplateRequest) {
return Mono.fromFuture(transport.performRequestAsync(getComponentTemplateRequest,
GetComponentTemplateRequest._ENDPOINT, transportOptions));
}
public Mono<GetComponentTemplateResponse> getComponentTemplate(
Function<GetComponentTemplateRequest.Builder, ObjectBuilder<GetComponentTemplateRequest>> fn) {
return getComponentTemplate(fn.apply(new GetComponentTemplateRequest.Builder()).build());
}
public Mono<BooleanResponse> existsComponentTemplate(ExistsComponentTemplateRequest existsComponentTemplateRequest) {
return Mono.fromFuture(transport.performRequestAsync(existsComponentTemplateRequest,
ExistsComponentTemplateRequest._ENDPOINT, transportOptions));
}
public Mono<BooleanResponse> existsComponentTemplate(
Function<ExistsComponentTemplateRequest.Builder, ObjectBuilder<ExistsComponentTemplateRequest>> fn) {
return existsComponentTemplate(fn.apply(new ExistsComponentTemplateRequest.Builder()).build());
}
public Mono<DeleteComponentTemplateResponse> deleteComponentTemplate(
DeleteComponentTemplateRequest deleteComponentTemplateRequest) {
return Mono.fromFuture(transport.performRequestAsync(deleteComponentTemplateRequest,
DeleteComponentTemplateRequest._ENDPOINT, transportOptions));
}
public Mono<DeleteComponentTemplateResponse> deleteComponentTemplate(
Function<DeleteComponentTemplateRequest.Builder, ObjectBuilder<DeleteComponentTemplateRequest>> fn) {
return deleteComponentTemplate(fn.apply(new DeleteComponentTemplateRequest.Builder()).build());
}
}

View File

@ -15,8 +15,8 @@
*/
package org.springframework.data.elasticsearch.client.elc;
import static co.elastic.clients.util.ApiTypeHelper.*;
import static org.springframework.data.elasticsearch.client.elc.TypeUtils.*;
import static co.elastic.clients.util.ApiTypeHelper.DANGEROUS_disableRequiredPropertiesCheck;
import static org.springframework.data.elasticsearch.client.elc.TypeUtils.result;
import co.elastic.clients.elasticsearch._types.Result;
import co.elastic.clients.elasticsearch.core.*;
@ -46,24 +46,14 @@ import org.springframework.data.elasticsearch.BulkFailureException;
import org.springframework.data.elasticsearch.NoSuchIndexException;
import org.springframework.data.elasticsearch.UncategorizedElasticsearchException;
import org.springframework.data.elasticsearch.client.UnsupportedBackendOperation;
import org.springframework.data.elasticsearch.client.erhlc.ReactiveClusterOperations;
import org.springframework.data.elasticsearch.core.AbstractReactiveElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.AggregationContainer;
import org.springframework.data.elasticsearch.core.IndexedObjectInformation;
import org.springframework.data.elasticsearch.core.MultiGetItem;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ReactiveIndexOperations;
import org.springframework.data.elasticsearch.core.*;
import org.springframework.data.elasticsearch.core.cluster.ReactiveClusterOperations;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.document.SearchDocument;
import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.BaseQuery;
import org.springframework.data.elasticsearch.core.query.BulkOptions;
import org.springframework.data.elasticsearch.core.query.ByQueryResponse;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.SearchTemplateQuery;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.data.elasticsearch.core.query.UpdateResponse;
import org.springframework.data.elasticsearch.core.reindex.ReindexRequest;
import org.springframework.data.elasticsearch.core.reindex.ReindexResponse;
@ -616,16 +606,23 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
@Override
public ReactiveIndexOperations indexOps(IndexCoordinates index) {
return new ReactiveIndicesTemplate(client.indices(), converter, index);
return new ReactiveIndicesTemplate(client.indices(), getReactiveClusterTemplate(), converter, index);
}
@Override
public ReactiveIndexOperations indexOps(Class<?> clazz) {
return new ReactiveIndicesTemplate(client.indices(), converter, clazz);
return new ReactiveIndicesTemplate(client.indices(), getReactiveClusterTemplate(), converter, clazz);
}
@Override
public ReactiveClusterOperations cluster() {
return getReactiveClusterTemplate();
}
/**
* @since 5.1
*/
private ReactiveClusterTemplate getReactiveClusterTemplate() {
return new ReactiveClusterTemplate(client.cluster(), converter);
}

View File

@ -15,7 +15,7 @@
*/
package org.springframework.data.elasticsearch.client.elc;
import static org.springframework.util.StringUtils.*;
import static org.springframework.util.StringUtils.hasText;
import co.elastic.clients.elasticsearch._types.AcknowledgedResponseBase;
import co.elastic.clients.elasticsearch.indices.*;
@ -37,15 +37,15 @@ import org.springframework.data.elasticsearch.core.ReactiveIndexOperations;
import org.springframework.data.elasticsearch.core.ReactiveResourceUtil;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.index.AliasActions;
import org.springframework.data.elasticsearch.core.index.AliasData;
import org.springframework.data.elasticsearch.core.index.*;
import org.springframework.data.elasticsearch.core.index.DeleteIndexTemplateRequest;
import org.springframework.data.elasticsearch.core.index.DeleteTemplateRequest;
import org.springframework.data.elasticsearch.core.index.ExistsIndexTemplateRequest;
import org.springframework.data.elasticsearch.core.index.ExistsTemplateRequest;
import org.springframework.data.elasticsearch.core.index.GetIndexTemplateRequest;
import org.springframework.data.elasticsearch.core.index.GetTemplateRequest;
import org.springframework.data.elasticsearch.core.index.PutIndexTemplateRequest;
import org.springframework.data.elasticsearch.core.index.PutTemplateRequest;
import org.springframework.data.elasticsearch.core.index.ReactiveMappingBuilder;
import org.springframework.data.elasticsearch.core.index.Settings;
import org.springframework.data.elasticsearch.core.index.TemplateData;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.lang.Nullable;
@ -58,27 +58,35 @@ public class ReactiveIndicesTemplate
extends ReactiveChildTemplate<ElasticsearchTransport, ReactiveElasticsearchIndicesClient>
implements ReactiveIndexOperations {
// we need a cluster client as well because ES has put some methods from the indices API into the cluster client
// (component templates)
private final ReactiveClusterTemplate clusterTemplate;
@Nullable private final Class<?> boundClass;
private final IndexCoordinates boundIndexCoordinates;
public ReactiveIndicesTemplate(ReactiveElasticsearchIndicesClient client,
public ReactiveIndicesTemplate(ReactiveElasticsearchIndicesClient client, ReactiveClusterTemplate clusterTemplate,
ElasticsearchConverter elasticsearchConverter, IndexCoordinates index) {
super(client, elasticsearchConverter);
Assert.notNull(index, "index must not be null");
Assert.notNull(clusterTemplate, "clusterTemplate must not be null");
this.clusterTemplate = clusterTemplate;
this.boundClass = null;
this.boundIndexCoordinates = index;
}
public ReactiveIndicesTemplate(ReactiveElasticsearchIndicesClient client,
public ReactiveIndicesTemplate(ReactiveElasticsearchIndicesClient client, ReactiveClusterTemplate clusterTemplate,
ElasticsearchConverter elasticsearchConverter, Class<?> clazz) {
super(client, elasticsearchConverter);
Assert.notNull(clazz, "clazz must not be null");
Assert.notNull(clusterTemplate, "clusterTemplate must not be null");
this.clusterTemplate = clusterTemplate;
this.boundClass = clazz;
this.boundIndexCoordinates = getIndexCoordinatesFor(clazz);
}
@ -271,6 +279,99 @@ public class ReactiveIndicesTemplate
return putTemplateResponse.map(PutTemplateResponse::acknowledged);
}
@Override
public Mono<Boolean> putComponentTemplate(PutComponentTemplateRequest putComponentTemplateRequest) {
Assert.notNull(putComponentTemplateRequest, "putComponentTemplateRequest must not be null");
co.elastic.clients.elasticsearch.cluster.PutComponentTemplateRequest putComponentTemplateRequestES = requestConverter
.clusterPutComponentTemplateRequest(putComponentTemplateRequest);
// the new Elasticsearch client has this call in the cluster index
return Mono.from(clusterTemplate.execute(client -> client.putComponentTemplate(putComponentTemplateRequestES)))
.map(AcknowledgedResponseBase::acknowledged);
}
@Override
public Flux<TemplateResponse> getComponentTemplate(GetComponentTemplateRequest getComponentTemplateRequest) {
Assert.notNull(getComponentTemplateRequest, "getComponentTemplateRequest must not be null");
co.elastic.clients.elasticsearch.cluster.GetComponentTemplateRequest getComponentTemplateRequestES = requestConverter
.clusterGetComponentTemplateRequest(getComponentTemplateRequest);
return Flux.from(clusterTemplate.execute(client -> client.getComponentTemplate(getComponentTemplateRequestES)))
.flatMapIterable(responseConverter::clusterGetComponentTemplates);
}
@Override
public Mono<Boolean> existsComponentTemplate(ExistsComponentTemplateRequest existsComponentTemplateRequest) {
Assert.notNull(existsComponentTemplateRequest, "existsComponentTemplateRequest must not be null");
co.elastic.clients.elasticsearch.cluster.ExistsComponentTemplateRequest existsComponentTemplateRequestES = requestConverter
.clusterExistsComponentTemplateRequest(existsComponentTemplateRequest);
return Mono
.from(clusterTemplate.execute(client -> client.existsComponentTemplate(existsComponentTemplateRequestES)))
.map(BooleanResponse::value);
}
@Override
public Mono<Boolean> deleteComponentTemplate(DeleteComponentTemplateRequest deleteComponentTemplateRequest) {
Assert.notNull(deleteComponentTemplateRequest, "deleteComponentTemplateRequest must not be null");
co.elastic.clients.elasticsearch.cluster.DeleteComponentTemplateRequest deleteComponentTemplateRequestES = requestConverter
.clusterDeleteComponentTemplateRequest(deleteComponentTemplateRequest);
return Mono
.from(clusterTemplate.execute(client -> client.deleteComponentTemplate(deleteComponentTemplateRequestES)))
.map(AcknowledgedResponseBase::acknowledged);
}
@Override
public Mono<Boolean> putIndexTemplate(PutIndexTemplateRequest putIndexTemplateRequest) {
Assert.notNull(putIndexTemplateRequest, "putIndexTemplateRequest must not be null");
co.elastic.clients.elasticsearch.indices.PutIndexTemplateRequest putIndexTemplateRequestES = requestConverter
.indicesPutIndexTemplateRequest(putIndexTemplateRequest);
return Mono.from(execute(client -> client.putIndexTemplate(putIndexTemplateRequestES)))
.map(PutIndexTemplateResponse::acknowledged);
}
@Override
public Mono<Boolean> existsIndexTemplate(ExistsIndexTemplateRequest existsIndexTemplateRequest) {
Assert.notNull(existsIndexTemplateRequest, "existsIndexTemplateRequest must not be null");
co.elastic.clients.elasticsearch.indices.ExistsIndexTemplateRequest existsIndexTemplateRequestES = requestConverter
.indicesExistsIndexTemplateRequest(existsIndexTemplateRequest);
return Mono.from(execute(client -> client.existsIndexTemplate(existsIndexTemplateRequestES)))
.map(BooleanResponse::value);
}
@Override
public Flux<TemplateResponse> getIndexTemplate(GetIndexTemplateRequest getIndexTemplateRequest) {
Assert.notNull(getIndexTemplateRequest, "getIndexTemplateRequest must not be null");
co.elastic.clients.elasticsearch.indices.GetIndexTemplateRequest getIndexTemplateRequestES = requestConverter
.indicesGetIndexTemplateRequest(getIndexTemplateRequest);
return Mono.from(execute(client -> client.getIndexTemplate(getIndexTemplateRequestES)))
.flatMapIterable(responseConverter::getIndexTemplates);
}
@Override
public Mono<Boolean> deleteIndexTemplate(DeleteIndexTemplateRequest deleteIndexTemplateRequest) {
Assert.notNull(deleteIndexTemplateRequest, "deleteIndexTemplateRequest must not be null");
co.elastic.clients.elasticsearch.indices.DeleteIndexTemplateRequest deleteIndexTemplateRequestES = requestConverter
.indicesDeleteIndexTemplateRequest(deleteIndexTemplateRequest);
return Mono.from(execute(client -> client.deleteIndexTemplate(deleteIndexTemplateRequestES)))
.map(AcknowledgedResponseBase::acknowledged);
}
@Override
public Mono<TemplateData> getTemplate(GetTemplateRequest getTemplateRequest) {

View File

@ -19,10 +19,16 @@ import static org.springframework.data.elasticsearch.client.elc.TypeUtils.*;
import static org.springframework.util.CollectionUtils.isEmpty;
import co.elastic.clients.elasticsearch._types.*;
import co.elastic.clients.elasticsearch._types.mapping.*;
import co.elastic.clients.elasticsearch._types.mapping.FieldType;
import co.elastic.clients.elasticsearch._types.mapping.RuntimeField;
import co.elastic.clients.elasticsearch._types.mapping.RuntimeFieldType;
import co.elastic.clients.elasticsearch._types.query_dsl.FieldAndFormat;
import co.elastic.clients.elasticsearch._types.query_dsl.Like;
import co.elastic.clients.elasticsearch.cluster.HealthRequest;
import co.elastic.clients.elasticsearch.cluster.*;
import co.elastic.clients.elasticsearch.cluster.DeleteComponentTemplateRequest;
import co.elastic.clients.elasticsearch.cluster.ExistsComponentTemplateRequest;
import co.elastic.clients.elasticsearch.cluster.GetComponentTemplateRequest;
import co.elastic.clients.elasticsearch.cluster.PutComponentTemplateRequest;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import co.elastic.clients.elasticsearch.core.bulk.CreateOperation;
@ -34,16 +40,15 @@ import co.elastic.clients.elasticsearch.core.search.Highlight;
import co.elastic.clients.elasticsearch.core.search.Rescore;
import co.elastic.clients.elasticsearch.core.search.SourceConfig;
import co.elastic.clients.elasticsearch.indices.*;
import co.elastic.clients.elasticsearch.indices.ExistsIndexTemplateRequest;
import co.elastic.clients.elasticsearch.indices.ExistsRequest;
import co.elastic.clients.elasticsearch.indices.update_aliases.Action;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.json.JsonpDeserializer;
import co.elastic.clients.json.JsonpMapper;
import jakarta.json.stream.JsonGenerator;
import jakarta.json.stream.JsonParser;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
@ -58,9 +63,12 @@ import org.springframework.data.elasticsearch.core.ScriptType;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.index.*;
import org.springframework.data.elasticsearch.core.index.DeleteIndexTemplateRequest;
import org.springframework.data.elasticsearch.core.index.DeleteTemplateRequest;
import org.springframework.data.elasticsearch.core.index.ExistsTemplateRequest;
import org.springframework.data.elasticsearch.core.index.GetIndexTemplateRequest;
import org.springframework.data.elasticsearch.core.index.GetTemplateRequest;
import org.springframework.data.elasticsearch.core.index.PutIndexTemplateRequest;
import org.springframework.data.elasticsearch.core.index.PutTemplateRequest;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
@ -102,9 +110,101 @@ class RequestConverter {
}
// region Cluster client
public HealthRequest clusterHealthRequest() {
public co.elastic.clients.elasticsearch.cluster.HealthRequest clusterHealthRequest() {
return new HealthRequest.Builder().build();
}
public co.elastic.clients.elasticsearch.cluster.PutComponentTemplateRequest clusterPutComponentTemplateRequest(
org.springframework.data.elasticsearch.core.index.PutComponentTemplateRequest putComponentTemplateRequest) {
Assert.notNull(putComponentTemplateRequest, "putComponentTemplateRequest must not be null");
return PutComponentTemplateRequest.of(b -> b //
.name(putComponentTemplateRequest.name()) //
.create(putComponentTemplateRequest.create()) //
.version(putComponentTemplateRequest.version()) //
.masterTimeout(time(putComponentTemplateRequest.masterTimeout())) //
.template(isb -> {
var componentTemplateData = putComponentTemplateRequest.template();
isb //
.mappings(typeMapping(componentTemplateData.mapping())) //
.settings(indexSettings(componentTemplateData.settings()));
// same code schema, but different Elasticsearch builder types
// noinspection DuplicatedCode
var aliasActions = componentTemplateData.aliasActions();
if (aliasActions != null) {
aliasActions.getActions().forEach(aliasAction -> {
if (aliasAction instanceof AliasAction.Add add) {
var parameters = add.getParameters();
// noinspection DuplicatedCode
String[] parametersAliases = parameters.getAliases();
if (parametersAliases != null) {
for (String aliasName : parametersAliases) {
isb.aliases(aliasName, aliasBuilder -> buildAlias(parameters, aliasBuilder));
}
}
}
});
}
return isb;
}));
}
private Alias.Builder buildAlias(AliasActionParameters parameters, Alias.Builder aliasBuilder) {
// noinspection DuplicatedCode
if (parameters.getRouting() != null) {
aliasBuilder.routing(parameters.getRouting());
}
if (parameters.getIndexRouting() != null) {
aliasBuilder.indexRouting(parameters.getIndexRouting());
}
if (parameters.getSearchRouting() != null) {
aliasBuilder.searchRouting(parameters.getSearchRouting());
}
if (parameters.getHidden() != null) {
aliasBuilder.isHidden(parameters.getHidden());
}
if (parameters.getWriteIndex() != null) {
aliasBuilder.isWriteIndex(parameters.getWriteIndex());
}
Query filterQuery = parameters.getFilterQuery();
if (filterQuery != null) {
co.elastic.clients.elasticsearch._types.query_dsl.Query esQuery = getQuery(filterQuery, null);
if (esQuery != null) {
aliasBuilder.filter(esQuery);
}
}
return aliasBuilder;
}
public ExistsComponentTemplateRequest clusterExistsComponentTemplateRequest(
org.springframework.data.elasticsearch.core.index.ExistsComponentTemplateRequest existsComponentTemplateRequest) {
Assert.notNull(existsComponentTemplateRequest, "existsComponentTemplateRequest must not be null");
return ExistsComponentTemplateRequest.of(b -> b.name(existsComponentTemplateRequest.templateName()));
}
public GetComponentTemplateRequest clusterGetComponentTemplateRequest(
org.springframework.data.elasticsearch.core.index.GetComponentTemplateRequest getComponentTemplateRequest) {
Assert.notNull(getComponentTemplateRequest, "getComponentTemplateRequest must not be null");
return GetComponentTemplateRequest.of(b -> b.name(getComponentTemplateRequest.templateName()));
}
public DeleteComponentTemplateRequest clusterDeleteComponentTemplateRequest(
org.springframework.data.elasticsearch.core.index.DeleteComponentTemplateRequest deleteComponentTemplateRequest) {
return DeleteComponentTemplateRequest.of(b -> b.name(deleteComponentTemplateRequest.templateName()));
}
// endregion
// region Indices client
@ -121,20 +221,12 @@ class RequestConverter {
Assert.notNull(indexCoordinates, "indexCoordinates must not be null");
Assert.notNull(settings, "settings must not be null");
CreateIndexRequest.Builder createRequestBuilder = new CreateIndexRequest.Builder();
createRequestBuilder.index(indexCoordinates.getIndexName());
// note: the new client does not support the index.storeType anymore
createRequestBuilder.settings(IndexSettings.of(b -> b //
.withJson(new StringReader(Document.from(settings).toJson()))));
if (mapping != null) {
createRequestBuilder.mappings(TypeMapping.of(b -> b //
.withJson(new StringReader(mapping.toJson()))));
}
return createRequestBuilder.build();
return new CreateIndexRequest.Builder() //
.index(indexCoordinates.getIndexName()) //
.settings(indexSettings(settings)) //
.mappings(typeMapping(mapping)) //
.build();
}
public RefreshRequest indicesRefreshRequest(IndexCoordinates indexCoordinates) {
@ -235,18 +327,7 @@ class RequestConverter {
Assert.notNull(indexCoordinates, "indexCoordinates must not be null");
return new GetMappingRequest.Builder().index(Arrays.asList(indexCoordinates.getIndexNames())).build();
}
private Property getProperty(Object value) {
// noinspection SpellCheckingInspection
ByteArrayOutputStream baos = new ByteArrayOutputStream();
JsonGenerator generator = jsonpMapper.jsonProvider().createGenerator(baos);
jsonpMapper.serialize(value, generator);
generator.close();
// noinspection SpellCheckingInspection
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
return fromJson(bais, Property._DESERIALIZER);
return new GetMappingRequest.Builder().index(List.of(indexCoordinates.getIndexNames())).build();
}
public GetIndicesSettingsRequest indicesGetSettingsRequest(IndexCoordinates indexCoordinates,
@ -303,7 +384,7 @@ class RequestConverter {
}
if (putTemplateRequest.getMappings() != null) {
builder.mappings(fromJson(putTemplateRequest.getMappings().toJson(), TypeMapping._DESERIALIZER));
builder.mappings(typeMapping(putTemplateRequest.getMappings()));
}
if (putTemplateRequest.getVersion() != null) {
@ -314,43 +395,14 @@ class RequestConverter {
if (aliasActions != null) {
aliasActions.getActions().forEach(aliasAction -> {
AliasActionParameters parameters = aliasAction.getParameters();
// noinspection DuplicatedCode
String[] parametersAliases = parameters.getAliases();
if (parametersAliases != null) {
for (String aliasName : parametersAliases) {
builder.aliases(aliasName, aliasBuilder -> {
// noinspection DuplicatedCode
if (parameters.getRouting() != null) {
aliasBuilder.routing(parameters.getRouting());
}
if (parameters.getIndexRouting() != null) {
aliasBuilder.indexRouting(parameters.getIndexRouting());
}
if (parameters.getSearchRouting() != null) {
aliasBuilder.searchRouting(parameters.getSearchRouting());
}
if (parameters.getHidden() != null) {
aliasBuilder.isHidden(parameters.getHidden());
}
if (parameters.getWriteIndex() != null) {
aliasBuilder.isWriteIndex(parameters.getWriteIndex());
}
Query filterQuery = parameters.getFilterQuery();
if (filterQuery != null) {
co.elastic.clients.elasticsearch._types.query_dsl.Query esQuery = getQuery(filterQuery, null);
if (esQuery != null) {
aliasBuilder.filter(esQuery);
}
}
return aliasBuilder;
return buildAlias(parameters, aliasBuilder);
});
}
}
@ -360,6 +412,55 @@ class RequestConverter {
return builder.build();
}
public co.elastic.clients.elasticsearch.indices.PutIndexTemplateRequest indicesPutIndexTemplateRequest(
PutIndexTemplateRequest putIndexTemplateRequest) {
Assert.notNull(putIndexTemplateRequest, "putIndexTemplateRequest must not be null");
var builder = new co.elastic.clients.elasticsearch.indices.PutIndexTemplateRequest.Builder()
.name(putIndexTemplateRequest.name()) //
.indexPatterns(Arrays.asList(putIndexTemplateRequest.indexPatterns())) //
.template(t -> {
t //
.settings(indexSettings(putIndexTemplateRequest.settings())) //
.mappings(typeMapping(putIndexTemplateRequest.mapping()));
// same code schema, but different Elasticsearch builder types
// noinspection DuplicatedCode
var aliasActions = putIndexTemplateRequest.aliasActions();
if (aliasActions != null) {
aliasActions.getActions().forEach(aliasAction -> {
if (aliasAction instanceof AliasAction.Add add) {
var parameters = add.getParameters();
// noinspection DuplicatedCode
String[] parametersAliases = parameters.getAliases();
if (parametersAliases != null) {
for (String aliasName : parametersAliases) {
t.aliases(aliasName, aliasBuilder -> buildAlias(parameters, aliasBuilder));
}
}
}
});
}
return t;
});
if (!putIndexTemplateRequest.composedOf().isEmpty()) {
builder.composedOf(putIndexTemplateRequest.composedOf());
}
return builder.build();
}
public ExistsIndexTemplateRequest indicesExistsIndexTemplateRequest(
org.springframework.data.elasticsearch.core.index.ExistsIndexTemplateRequest existsIndexTemplateRequest) {
Assert.notNull(existsIndexTemplateRequest, "existsIndexTemplateRequest must not be null");
return co.elastic.clients.elasticsearch.indices.ExistsIndexTemplateRequest
.of(b -> b.name(existsIndexTemplateRequest.templateName()));
}
public co.elastic.clients.elasticsearch.indices.ExistsTemplateRequest indicesExistsTemplateRequest(
ExistsTemplateRequest existsTemplateRequest) {
@ -369,6 +470,24 @@ class RequestConverter {
.of(etr -> etr.name(existsTemplateRequest.getTemplateName()));
}
public co.elastic.clients.elasticsearch.indices.GetIndexTemplateRequest indicesGetIndexTemplateRequest(
GetIndexTemplateRequest getIndexTemplateRequest) {
Assert.notNull(getIndexTemplateRequest, "getIndexTemplateRequest must not be null");
return co.elastic.clients.elasticsearch.indices.GetIndexTemplateRequest
.of(gitr -> gitr.name(getIndexTemplateRequest.templateName()));
}
public co.elastic.clients.elasticsearch.indices.DeleteIndexTemplateRequest indicesDeleteIndexTemplateRequest(
DeleteIndexTemplateRequest deleteIndexTemplateRequest) {
Assert.notNull(deleteIndexTemplateRequest, "deleteIndexTemplateRequest must not be null");
return co.elastic.clients.elasticsearch.indices.DeleteIndexTemplateRequest
.of(ditr -> ditr.name(deleteIndexTemplateRequest.templateName()));
}
public co.elastic.clients.elasticsearch.indices.DeleteTemplateRequest indicesDeleteTemplateRequest(
DeleteTemplateRequest existsTemplateRequest) {
@ -440,7 +559,7 @@ class RequestConverter {
}
}
builder.refresh(TypeUtils.refresh(refreshPolicy));
builder.refresh(refresh(refreshPolicy));
return builder.build();
}
@ -607,9 +726,9 @@ class RequestConverter {
builder.timeout(tb -> tb.time(Long.valueOf(bulkOptions.getTimeout().toMillis()).toString() + "ms"));
}
builder.refresh(TypeUtils.refresh(refreshPolicy));
builder.refresh(refresh(refreshPolicy));
if (bulkOptions.getRefreshPolicy() != null) {
builder.refresh(TypeUtils.refresh(bulkOptions.getRefreshPolicy()));
builder.refresh(refresh(bulkOptions.getRefreshPolicy()));
}
if (bulkOptions.getWaitForActiveShards() != null) {
@ -752,13 +871,13 @@ class RequestConverter {
ReindexRequest.Dest dest = reindexRequest.getDest();
return d //
.index(dest.getIndex().getIndexName()) //
.versionType(TypeUtils.versionType(dest.getVersionType())) //
.opType(TypeUtils.opType(dest.getOpType()));
.versionType(versionType(dest.getVersionType())) //
.opType(opType(dest.getOpType()));
} //
);
if (reindexRequest.getConflicts() != null) {
builder.conflicts(TypeUtils.conflicts(reindexRequest.getConflicts()));
builder.conflicts(conflicts(reindexRequest.getConflicts()));
}
ReindexRequest.Script script = reindexRequest.getScript();
@ -771,7 +890,7 @@ class RequestConverter {
if (reindexRequest.getWaitForActiveShards() != null) {
builder.waitForActiveShards(wfas -> wfas //
.count(TypeUtils.waitForActiveShardsCount(reindexRequest.getWaitForActiveShards())));
.count(waitForActiveShardsCount(reindexRequest.getWaitForActiveShards())));
}
builder //
@ -796,7 +915,7 @@ class RequestConverter {
if (routing != null) {
r.routing(routing);
}
r.refresh(TypeUtils.refresh(refreshPolicy));
r.refresh(refresh(refreshPolicy));
return r;
});
}
@ -869,7 +988,7 @@ class RequestConverter {
.docAsUpsert(query.getDocAsUpsert()) //
.ifSeqNo(query.getIfSeqNo() != null ? Long.valueOf(query.getIfSeqNo()) : null) //
.ifPrimaryTerm(query.getIfPrimaryTerm() != null ? Long.valueOf(query.getIfPrimaryTerm()) : null) //
.refresh(TypeUtils.refresh(refreshPolicy)) //
.refresh(refresh(refreshPolicy)) //
.retryOnConflict(query.getRetryOnConflict()) //
;
@ -953,7 +1072,7 @@ class RequestConverter {
}
if (updateQuery.getWaitForActiveShards() != null) {
ub.waitForActiveShards(w -> w.count(TypeUtils.waitForActiveShardsCount(updateQuery.getWaitForActiveShards())));
ub.waitForActiveShards(w -> w.count(waitForActiveShardsCount(updateQuery.getWaitForActiveShards())));
}
return ub;
@ -1299,7 +1418,7 @@ class RequestConverter {
return Rescore.of(r -> r //
.query(rq -> rq //
.query(getQuery(rescorerQuery.getQuery(), null)) //
.scoreMode(TypeUtils.scoreMode(rescorerQuery.getScoreMode())) //
.scoreMode(scoreMode(rescorerQuery.getScoreMode())) //
.queryWeight(rescorerQuery.getQueryWeight() != null ? Double.valueOf(rescorerQuery.getQueryWeight()) : 1.0) //
.rescoreQueryWeight(
rescorerQuery.getRescoreQueryWeight() != null ? Double.valueOf(rescorerQuery.getRescoreQueryWeight())
@ -1359,9 +1478,8 @@ class RequestConverter {
.geoDistance(gd -> gd //
.field(fieldName) //
.location(loc -> loc.latlon(Queries.latLon(geoDistanceOrder.getGeoPoint())))//
.distanceType(TypeUtils.geoDistanceType(geoDistanceOrder.getDistanceType()))
.mode(TypeUtils.sortMode(finalMode)) //
.unit(TypeUtils.distanceUnit(geoDistanceOrder.getUnit())) //
.distanceType(geoDistanceType(geoDistanceOrder.getDistanceType())).mode(sortMode(finalMode)) //
.unit(distanceUnit(geoDistanceOrder.getUnit())) //
.ignoreUnmapped(geoDistanceOrder.getIgnoreUnmapped())));
} else {
String missing = (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) ? "_first"
@ -1371,10 +1489,10 @@ class RequestConverter {
.field(f -> {
f.field(fieldName) //
.order(sortOrder) //
.mode(TypeUtils.sortMode(finalMode));
.mode(sortMode(finalMode));
if (finalUnmappedType != null) {
FieldType fieldType = TypeUtils.fieldType(finalUnmappedType);
FieldType fieldType = fieldType(finalUnmappedType);
if (fieldType != null) {
f.unmappedType(fieldType);

View File

@ -15,37 +15,28 @@
*/
package org.springframework.data.elasticsearch.client.elc;
import static org.springframework.data.elasticsearch.client.elc.JsonUtils.*;
import static org.springframework.data.elasticsearch.client.elc.JsonUtils.toJson;
import static org.springframework.data.elasticsearch.client.elc.TypeUtils.removePrefixFromJson;
import static org.springframework.data.elasticsearch.client.elc.TypeUtils.typeMapping;
import co.elastic.clients.elasticsearch._types.BulkIndexByScrollFailure;
import co.elastic.clients.elasticsearch._types.ErrorCause;
import co.elastic.clients.elasticsearch._types.Time;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch.cluster.ComponentTemplateSummary;
import co.elastic.clients.elasticsearch.cluster.GetComponentTemplateResponse;
import co.elastic.clients.elasticsearch.cluster.HealthResponse;
import co.elastic.clients.elasticsearch.core.DeleteByQueryResponse;
import co.elastic.clients.elasticsearch.core.GetScriptResponse;
import co.elastic.clients.elasticsearch.core.UpdateByQueryResponse;
import co.elastic.clients.elasticsearch.core.mget.MultiGetError;
import co.elastic.clients.elasticsearch.core.mget.MultiGetResponseItem;
import co.elastic.clients.elasticsearch.indices.Alias;
import co.elastic.clients.elasticsearch.indices.AliasDefinition;
import co.elastic.clients.elasticsearch.indices.GetAliasResponse;
import co.elastic.clients.elasticsearch.indices.GetIndexResponse;
import co.elastic.clients.elasticsearch.indices.GetIndicesSettingsResponse;
import co.elastic.clients.elasticsearch.indices.GetMappingResponse;
import co.elastic.clients.elasticsearch.indices.GetTemplateResponse;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import co.elastic.clients.elasticsearch.indices.IndexState;
import co.elastic.clients.elasticsearch.indices.TemplateMapping;
import co.elastic.clients.elasticsearch.indices.*;
import co.elastic.clients.elasticsearch.indices.get_index_template.IndexTemplateItem;
import co.elastic.clients.elasticsearch.indices.get_mapping.IndexMappingRecord;
import co.elastic.clients.json.JsonpMapper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -56,9 +47,7 @@ import org.springframework.data.elasticsearch.core.IndexInformation;
import org.springframework.data.elasticsearch.core.MultiGetItem;
import org.springframework.data.elasticsearch.core.cluster.ClusterHealth;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.index.AliasData;
import org.springframework.data.elasticsearch.core.index.Settings;
import org.springframework.data.elasticsearch.core.index.TemplateData;
import org.springframework.data.elasticsearch.core.index.*;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.ByQueryResponse;
import org.springframework.data.elasticsearch.core.query.StringQuery;
@ -107,6 +96,54 @@ class ResponseConverter {
.withUnassignedShards(healthResponse.unassignedShards()) //
.build(); //
}
public List<TemplateResponse> clusterGetComponentTemplates(
GetComponentTemplateResponse getComponentTemplateResponse) {
Assert.notNull(getComponentTemplateResponse, "getComponentTemplateResponse must not be null");
var componentTemplates = new ArrayList<TemplateResponse>();
getComponentTemplateResponse.componentTemplates().forEach(componentTemplate -> {
componentTemplates.add(clusterGetComponentTemplate(componentTemplate));
});
return componentTemplates;
}
private TemplateResponse clusterGetComponentTemplate(
co.elastic.clients.elasticsearch.cluster.ComponentTemplate componentTemplate) {
var componentTemplateNode = componentTemplate.componentTemplate();
var componentTemplateSummary = componentTemplateNode.template();
return TemplateResponse.builder() //
.withName(componentTemplate.name()) //
.withVersion(componentTemplateNode.version()) //
.withTemplateData(clusterGetComponentTemplateData(componentTemplateSummary)) //
.build();
}
private TemplateResponseData clusterGetComponentTemplateData(
ComponentTemplateSummary componentTemplateSummary) {
var mapping = typeMapping(componentTemplateSummary.mappings());
var settings = new Settings();
componentTemplateSummary.settings().forEach((key, indexSettings) -> {
settings.put(key, Settings.parse(removePrefixFromJson(indexSettings.toString())));
});
Function<? super Map.Entry<String, AliasDefinition>, String> keyMapper = Map.Entry::getKey;
Function<? super Map.Entry<String, AliasDefinition>, AliasData> valueMapper = entry -> indicesGetAliasData(
entry.getKey(), entry.getValue());
Map<String, AliasData> aliases = componentTemplateSummary.aliases().entrySet().stream()
.collect(Collectors.toMap(keyMapper, valueMapper));
return TemplateResponseData.builder() //
.withMapping(mapping) //
.withSettings(settings) //
.withAliases(aliases) //
.build();
}
// endregion
// region indices client
@ -265,6 +302,59 @@ class ResponseConverter {
return null;
}
public List<TemplateResponse> getIndexTemplates(GetIndexTemplateResponse getIndexTemplateResponse) {
Assert.notNull(getIndexTemplateResponse, "getIndexTemplateResponse must not be null");
var componentTemplates = new ArrayList<TemplateResponse>();
getIndexTemplateResponse.indexTemplates().forEach(indexTemplateItem -> {
componentTemplates.add(indexGetComponentTemplate(indexTemplateItem));
});
return componentTemplates;
}
private TemplateResponse indexGetComponentTemplate(IndexTemplateItem indexTemplateItem) {
var indexTemplate = indexTemplateItem.indexTemplate();
var composedOf = indexTemplate.composedOf();
var indexTemplateSummary = indexTemplate.template();
return TemplateResponse.builder() //
.withName(indexTemplateItem.name()) //
.withVersion(indexTemplate.version()) //
.withTemplateData(indexGetComponentTemplateData(indexTemplateSummary, composedOf)) //
.build();
}
private TemplateResponseData indexGetComponentTemplateData(IndexTemplateSummary indexTemplateSummary,
List<String> composedOf) {
var mapping = typeMapping(indexTemplateSummary.mappings());
Function<IndexSettings, Settings> indexSettingsToSettings = indexSettings -> {
if (indexSettings == null) {
return null;
}
Settings parsedSettings = Settings.parse(toJson(indexSettings, jsonpMapper));
return (indexSettings.index() != null) ? parsedSettings : new Settings().append("index", parsedSettings);
};
var settings = indexSettingsToSettings.apply(indexTemplateSummary.settings());
Function<? super Map.Entry<String, Alias>, String> keyMapper = Map.Entry::getKey;
Function<? super Map.Entry<String, Alias>, AliasData> valueMapper = entry -> indicesGetAliasData(entry.getKey(),
entry.getValue());
Map<String, Alias> aliases1 = indexTemplateSummary.aliases();
Map<String, AliasData> aliases = aliases1.entrySet().stream().collect(Collectors.toMap(keyMapper, valueMapper));
return TemplateResponseData.builder() //
.withMapping(mapping) //
.withSettings(settings) //
.withAliases(aliases) //
.withComposedOf(composedOf) //
.build();
}
// endregion
// region document operations
@ -465,6 +555,5 @@ class ResponseConverter {
return null;
}
}
// endregion
}

View File

@ -17,27 +17,21 @@ package org.springframework.data.elasticsearch.client.elc;
import co.elastic.clients.elasticsearch._types.*;
import co.elastic.clients.elasticsearch._types.mapping.FieldType;
import co.elastic.clients.elasticsearch.core.search.BoundaryScanner;
import co.elastic.clients.elasticsearch.core.search.HighlighterEncoder;
import co.elastic.clients.elasticsearch.core.search.HighlighterFragmenter;
import co.elastic.clients.elasticsearch.core.search.HighlighterOrder;
import co.elastic.clients.elasticsearch.core.search.HighlighterTagsSchema;
import co.elastic.clients.elasticsearch.core.search.HighlighterType;
import co.elastic.clients.elasticsearch.core.search.ScoreMode;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch.core.search.*;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import java.io.StringReader;
import java.time.Duration;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.data.elasticsearch.core.RefreshPolicy;
import org.springframework.data.elasticsearch.core.query.GeoDistanceOrder;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.data.elasticsearch.core.query.IndicesOptions;
import org.springframework.data.elasticsearch.core.query.Order;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.RescorerQuery;
import org.springframework.data.elasticsearch.core.query.UpdateResponse;
import org.springframework.data.elasticsearch.core.reindex.ReindexRequest;
import org.springframework.lang.Nullable;
@ -406,4 +400,27 @@ final class TypeUtils {
.map(wildcardState -> ExpandWildcard.valueOf(wildcardState.name().toLowerCase())).collect(Collectors.toList())
: null;
}
@Nullable
static TypeMapping typeMapping(@Nullable Document mapping) {
if (mapping != null) {
return TypeMapping.of(b -> b.withJson(new StringReader(mapping.toJson())));
}
return null;
}
@Nullable
static Document typeMapping(@Nullable TypeMapping typeMapping) {
return (typeMapping != null) ? Document.parse(removePrefixFromJson(typeMapping.toString())) : null;
}
public static String removePrefixFromJson(String jsonWithPrefix) {
return jsonWithPrefix.substring(jsonWithPrefix.indexOf("{"));
}
@Nullable
static IndexSettings indexSettings(@Nullable Map<String, Object> settings) {
return settings != null ? IndexSettings.of(b -> b.withJson(new StringReader(Document.from(settings).toJson())))
: null;
}
}

View File

@ -20,6 +20,7 @@ import reactor.core.publisher.Mono;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.core.cluster.ClusterHealth;
import org.springframework.data.elasticsearch.core.cluster.ReactiveClusterOperations;
/**
* Default implementation of {@link ReactiveClusterOperations} using the {@link ReactiveElasticsearchOperations}.

View File

@ -47,24 +47,13 @@ import org.reactivestreams.Publisher;
import org.springframework.data.elasticsearch.BulkFailureException;
import org.springframework.data.elasticsearch.NoSuchIndexException;
import org.springframework.data.elasticsearch.UncategorizedElasticsearchException;
import org.springframework.data.elasticsearch.core.AbstractReactiveElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.AggregationContainer;
import org.springframework.data.elasticsearch.core.IndexedObjectInformation;
import org.springframework.data.elasticsearch.core.MultiGetItem;
import org.springframework.data.elasticsearch.core.ReactiveIndexOperations;
import org.springframework.data.elasticsearch.core.RefreshPolicy;
import org.springframework.data.elasticsearch.core.SearchHitMapping;
import org.springframework.data.elasticsearch.core.SearchHitSupport;
import org.springframework.data.elasticsearch.core.SearchPage;
import org.springframework.data.elasticsearch.core.*;
import org.springframework.data.elasticsearch.core.cluster.ReactiveClusterOperations;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.document.SearchDocument;
import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.BulkOptions;
import org.springframework.data.elasticsearch.core.query.ByQueryResponse;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.elasticsearch.core.query.UpdateResponse;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.data.elasticsearch.core.reindex.ReindexRequest;
import org.springframework.data.elasticsearch.core.reindex.ReindexResponse;
import org.springframework.http.HttpStatus;

View File

@ -15,13 +15,9 @@
*/
package org.springframework.data.elasticsearch.client.erhlc;
import static org.elasticsearch.client.Requests.*;
import static org.springframework.util.StringUtils.*;
import static org.elasticsearch.client.Requests.refreshRequest;
import static org.springframework.util.StringUtils.hasText;
import org.springframework.data.elasticsearch.core.IndexInformation;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ReactiveIndexOperations;
import org.springframework.data.elasticsearch.core.ReactiveResourceUtil;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@ -36,27 +32,21 @@ import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest;
import org.elasticsearch.client.GetAliasesResponse;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexTemplatesRequest;
import org.elasticsearch.client.indices.GetMappingsRequest;
import org.elasticsearch.client.indices.IndexTemplatesExistRequest;
import org.elasticsearch.client.indices.*;
import org.elasticsearch.client.indices.PutIndexTemplateRequest;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.elasticsearch.NoSuchIndexException;
import org.springframework.data.elasticsearch.annotations.Mapping;
import org.springframework.data.elasticsearch.core.IndexInformation;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ReactiveIndexOperations;
import org.springframework.data.elasticsearch.core.ReactiveResourceUtil;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.index.AliasActions;
import org.springframework.data.elasticsearch.core.index.AliasData;
import org.springframework.data.elasticsearch.core.index.DeleteTemplateRequest;
import org.springframework.data.elasticsearch.core.index.ExistsTemplateRequest;
import org.springframework.data.elasticsearch.core.index.GetTemplateRequest;
import org.springframework.data.elasticsearch.core.index.PutTemplateRequest;
import org.springframework.data.elasticsearch.core.index.ReactiveMappingBuilder;
import org.springframework.data.elasticsearch.core.index.Settings;
import org.springframework.data.elasticsearch.core.index.TemplateData;
import org.springframework.data.elasticsearch.core.index.*;
import org.springframework.data.elasticsearch.core.index.DeleteComponentTemplateRequest;
import org.springframework.data.elasticsearch.core.index.PutComponentTemplateRequest;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.lang.Nullable;
@ -290,6 +280,48 @@ class ReactiveIndexTemplate implements ReactiveIndexOperations {
return Mono.from(operations.executeWithIndicesClient(client -> client.putTemplate(putIndexTemplateRequest)));
}
@Override
public Mono<Boolean> putComponentTemplate(PutComponentTemplateRequest putComponentTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public Flux<TemplateResponse> getComponentTemplate(GetComponentTemplateRequest request) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public Mono<Boolean> existsComponentTemplate(ExistsComponentTemplateRequest existsComponentTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public Mono<Boolean> deleteComponentTemplate(DeleteComponentTemplateRequest deleteComponentTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public Mono<Boolean> putIndexTemplate(
org.springframework.data.elasticsearch.core.index.PutIndexTemplateRequest putIndexTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public Mono<Boolean> existsIndexTemplate(ExistsIndexTemplateRequest existsIndexTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public Flux<TemplateResponse> getIndexTemplate(GetIndexTemplateRequest getIndexTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public Mono<Boolean> deleteIndexTemplate(
org.springframework.data.elasticsearch.core.index.DeleteIndexTemplateRequest deleteIndexTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public Mono<TemplateData> getTemplate(GetTemplateRequest getTemplateRequest) {

View File

@ -348,6 +348,7 @@ class RequestFactory {
for (String aliasName : parametersAliases) {
Alias alias = new Alias(aliasName);
//noinspection DuplicatedCode
if (parameters.getRouting() != null) {
alias.routing(parameters.getRouting());
}

View File

@ -44,14 +44,7 @@ import org.springframework.data.elasticsearch.core.AbstractIndexTemplate;
import org.springframework.data.elasticsearch.core.IndexInformation;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.index.AliasActions;
import org.springframework.data.elasticsearch.core.index.AliasData;
import org.springframework.data.elasticsearch.core.index.DeleteTemplateRequest;
import org.springframework.data.elasticsearch.core.index.ExistsTemplateRequest;
import org.springframework.data.elasticsearch.core.index.GetTemplateRequest;
import org.springframework.data.elasticsearch.core.index.PutTemplateRequest;
import org.springframework.data.elasticsearch.core.index.Settings;
import org.springframework.data.elasticsearch.core.index.TemplateData;
import org.springframework.data.elasticsearch.core.index.*;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@ -231,6 +224,48 @@ class RestIndexTemplate extends AbstractIndexTemplate implements IndexOperations
client -> client.indices().deleteTemplate(deleteIndexTemplateRequest, RequestOptions.DEFAULT).isAcknowledged());
}
@Override
public boolean putIndexTemplate(
org.springframework.data.elasticsearch.core.index.PutIndexTemplateRequest putIndexTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public boolean existsIndexTemplate(ExistsIndexTemplateRequest existsTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public List<TemplateResponse> getIndexTemplate(GetIndexTemplateRequest getIndexTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public boolean deleteIndexTemplate(
org.springframework.data.elasticsearch.core.index.DeleteIndexTemplateRequest deleteIndexTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public boolean putComponentTemplate(PutComponentTemplateRequest putComponentTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public boolean existsComponentTemplate(ExistsComponentTemplateRequest existsComponentTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public List<TemplateResponse> getComponentTemplate(GetComponentTemplateRequest getComponentTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public boolean deleteComponentTemplate(DeleteComponentTemplateRequest deleteComponentTemplateRequest) {
throw new UnsupportedOperationException("not implemented");
}
@Override
public List<IndexInformation> getInformation(IndexCoordinates index) {

View File

@ -20,14 +20,7 @@ import java.util.Map;
import java.util.Set;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.index.AliasActions;
import org.springframework.data.elasticsearch.core.index.AliasData;
import org.springframework.data.elasticsearch.core.index.DeleteTemplateRequest;
import org.springframework.data.elasticsearch.core.index.ExistsTemplateRequest;
import org.springframework.data.elasticsearch.core.index.GetTemplateRequest;
import org.springframework.data.elasticsearch.core.index.PutTemplateRequest;
import org.springframework.data.elasticsearch.core.index.Settings;
import org.springframework.data.elasticsearch.core.index.TemplateData;
import org.springframework.data.elasticsearch.core.index.*;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.lang.Nullable;
@ -224,16 +217,65 @@ public interface IndexOperations {
* @param putTemplateRequest template request parameters
* @return true if successful
* @since 4.1
* @deprecated since 5.1, as the underlying Elasticsearch API is deprecated.
*/
@Deprecated
boolean putTemplate(PutTemplateRequest putTemplateRequest);
/**
* Creates an index template
*
* @param putIndexTemplateRequest template request parameters
* @return {@literal true} if successful
* @since 5.1
*/
boolean putIndexTemplate(PutIndexTemplateRequest putIndexTemplateRequest);
/**
* Writes a component index template that can be used in a composable index template.
*
* @param putComponentTemplateRequest index template request parameters
* @return {@literal true} if successful
* @since 5.1
*/
boolean putComponentTemplate(PutComponentTemplateRequest putComponentTemplateRequest);
/**
* Checks wether a component index template exists.
*
* @param existsComponentTemplateRequest the parameters for the request
* @return {@literal true} if the componentTemplate exists.
* @since 5.1
*/
boolean existsComponentTemplate(ExistsComponentTemplateRequest existsComponentTemplateRequest);
/**
* Get a component template.
*
* @param getComponentTemplateRequest parameters for the request, may contain wildcard names
* @return the found {@link TemplateResponse}s, may be empty
* @since 5.1
*/
List<TemplateResponse> getComponentTemplate(GetComponentTemplateRequest getComponentTemplateRequest);
/**
* Deletes the given component index template
*
* @param deleteComponentTemplateRequest request parameters
* @return {@literal true} if successful.
* @since 5.1
*/
boolean deleteComponentTemplate(DeleteComponentTemplateRequest deleteComponentTemplateRequest);
/**
* gets an index template using the legacy Elasticsearch interface.
*
* @param templateName the template name
* @return TemplateData, {@literal null} if no template with the given name exists.
* @since 4.1
* @deprecated since 5.1, as the underlying Elasticsearch API is deprecated.
*/
@Deprecated
@Nullable
default TemplateData getTemplate(String templateName) {
return getTemplate(new GetTemplateRequest(templateName));
@ -245,7 +287,9 @@ public interface IndexOperations {
* @param getTemplateRequest the request parameters
* @return TemplateData, {@literal null} if no template with the given name exists.
* @since 4.1
* @deprecated since 5.1, as the underlying Elasticsearch API is deprecated.
*/
@Deprecated
@Nullable
TemplateData getTemplate(GetTemplateRequest getTemplateRequest);
@ -255,7 +299,9 @@ public interface IndexOperations {
* @param templateName the template name
* @return {@literal true} if the index exists
* @since 4.1
* @deprecated since 5.1, as the underlying Elasticsearch API is deprecated.
*/
@Deprecated
default boolean existsTemplate(String templateName) {
return existsTemplate(new ExistsTemplateRequest(templateName));
}
@ -266,9 +312,69 @@ public interface IndexOperations {
* @param existsTemplateRequest the request parameters
* @return {@literal true} if the index exists
* @since 4.1
* @deprecated since 5.1, as the underlying Elasticsearch API is deprecated.
*/
@Deprecated
boolean existsTemplate(ExistsTemplateRequest existsTemplateRequest);
/**
* check if an index template exists.
*
* @param templateName the template name
* @return true if the index template exists
* @since 5.1
*/
default boolean existsIndexTemplate(String templateName) {
return existsIndexTemplate(new ExistsIndexTemplateRequest(templateName));
}
/**
* check if an index template exists.
*
* @param existsTemplateRequest the request parameters
* @return true if the index template exists
* @since 5.1
*/
boolean existsIndexTemplate(ExistsIndexTemplateRequest existsTemplateRequest);
/**
* Gets an index template.
*
* @param templateName template name
* @since 5.1
*/
default List<TemplateResponse> getIndexTemplate(String templateName) {
return getIndexTemplate(new GetIndexTemplateRequest(templateName));
}
/**
* Gets an index template.
*
* @param getIndexTemplateRequest the request parameters
* @since 5.1
*/
List<TemplateResponse> getIndexTemplate(GetIndexTemplateRequest getIndexTemplateRequest);
/**
* Deletes an index template.
*
* @param templateName template name
* @return true if successful
* @since 5.1
*/
default boolean deleteIndexTemplate(String templateName) {
return deleteIndexTemplate(new DeleteIndexTemplateRequest(templateName));
}
/**
* Deletes an index template.
*
* @param deleteIndexTemplateRequest template request parameters
* @return true if successful
* @since 5.1
*/
boolean deleteIndexTemplate(DeleteIndexTemplateRequest deleteIndexTemplateRequest);
/**
* Deletes an index template using the legacy Elasticsearch interface (@see
* https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates-v1.html).
@ -276,7 +382,9 @@ public interface IndexOperations {
* @param templateName the template name
* @return true if successful
* @since 4.1
* @deprecated since 5.1, as the underlying Elasticsearch API is deprecated.
*/
@Deprecated
default boolean deleteTemplate(String templateName) {
return deleteTemplate(new DeleteTemplateRequest(templateName));
}
@ -288,7 +396,9 @@ public interface IndexOperations {
* @param deleteTemplateRequest template request parameters
* @return true if successful
* @since 4.1
* @deprecated since 5.1, as the underlying Elasticsearch API is deprecated.
*/
@Deprecated
boolean deleteTemplate(DeleteTemplateRequest deleteTemplateRequest);
// endregion

View File

@ -16,9 +16,9 @@
package org.springframework.data.elasticsearch.core;
import org.reactivestreams.Publisher;
import org.springframework.data.elasticsearch.client.erhlc.ReactiveClusterOperations;
import org.springframework.data.elasticsearch.client.erhlc.ReactiveElasticsearchClient;
import org.springframework.data.elasticsearch.client.erhlc.ReactiveElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.cluster.ReactiveClusterOperations;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;

View File

@ -22,14 +22,7 @@ import java.util.Map;
import java.util.Set;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.index.AliasActions;
import org.springframework.data.elasticsearch.core.index.AliasData;
import org.springframework.data.elasticsearch.core.index.DeleteTemplateRequest;
import org.springframework.data.elasticsearch.core.index.ExistsTemplateRequest;
import org.springframework.data.elasticsearch.core.index.GetTemplateRequest;
import org.springframework.data.elasticsearch.core.index.PutTemplateRequest;
import org.springframework.data.elasticsearch.core.index.Settings;
import org.springframework.data.elasticsearch.core.index.TemplateData;
import org.springframework.data.elasticsearch.core.index.*;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
/**
@ -226,16 +219,125 @@ public interface ReactiveIndexOperations {
* @param putTemplateRequest template request parameters
* @return Mono of {@literal true} if the template could be stored
* @since 4.1
* @deprecated since 5.1, as the underlying Elasticsearch API is deprecated.
*/
@Deprecated
Mono<Boolean> putTemplate(PutTemplateRequest putTemplateRequest);
/**
* Writes a component index template that can be used in a composable index template.
*
* @param putComponentTemplateRequest index template request parameters
* @return {@literal true} if successful
* @since 5.1
*/
Mono<Boolean> putComponentTemplate(PutComponentTemplateRequest putComponentTemplateRequest);
/**
* Get component template(s).
*
* @param getComponentTemplateRequest the getComponentTemplateRequest parameters
* @return a {@link Flux} of {@link TemplateResponse}
* @since 5.1
*/
Flux<TemplateResponse> getComponentTemplate(GetComponentTemplateRequest getComponentTemplateRequest);
/**
* Checks wether a component index template exists.
*
* @param existsComponentTemplateRequest the parameters for the request
* @return Mono with the value if the componentTemplate exists.
* @since 5.1
*/
Mono<Boolean> existsComponentTemplate(ExistsComponentTemplateRequest existsComponentTemplateRequest);
/**
* Deletes a component index template.
*
* @param deleteComponentTemplateRequest the parameters for the request
* @return Mono with the value if the request was acknowledged.
* @since 5.1
*/
Mono<Boolean> deleteComponentTemplate(DeleteComponentTemplateRequest deleteComponentTemplateRequest);
/**
* Creates an index template.
*
* @param putIndexTemplateRequest template request parameters
* @return {@literal true} if successful
* @since 5.1
*/
Mono<Boolean> putIndexTemplate(PutIndexTemplateRequest putIndexTemplateRequest);
/**
* Checks if an index template exists.
*
* @param indexTemplateName the name of the index template
* @return Mono with the value if the index template exists.
* @since 5.1
*/
default Mono<Boolean> existsIndexTemplate(String indexTemplateName) {
return existsIndexTemplate(new ExistsIndexTemplateRequest(indexTemplateName));
}
/**
* Checks if an index template exists.
*
* @param existsIndexTemplateRequest the parameters for the request
* @return Mono with the value if the index template exists.
* @since 5.1
*/
Mono<Boolean> existsIndexTemplate(ExistsIndexTemplateRequest existsIndexTemplateRequest);
/**
* Get index template(s).
*
* @param indexTemplateName the name of the index template
* @return a {@link Flux} of {@link TemplateResponse}
* @since 5.1
*/
default Flux<TemplateResponse> getIndexTemplate(String indexTemplateName) {
return getIndexTemplate(new GetIndexTemplateRequest(indexTemplateName));
}
/**
* Get index template(s).
*
* @param getIndexTemplateRequest
* @return a {@link Flux} of {@link TemplateResponse}
* @since 5.1
*/
Flux<TemplateResponse> getIndexTemplate(GetIndexTemplateRequest getIndexTemplateRequest);
/**
* Deletes an index template.
*
* @param indexTemplateName the name of the index template
* @return Mono with the value if the request was acknowledged.
* @since 5.1
*/
default Mono<Boolean> deleteIndexTemplate(String indexTemplateName) {
return deleteIndexTemplate(new DeleteIndexTemplateRequest(indexTemplateName));
}
/**
* Deletes an index template.
*
* @param deleteIndexTemplateRequest the parameters for the request
* @return Mono with the value if the request was acknowledged.
* @since 5.1
*/
Mono<Boolean> deleteIndexTemplate(DeleteIndexTemplateRequest deleteIndexTemplateRequest);
/**
* gets an index template using the legacy Elasticsearch interface.
*
* @param templateName the template name
* @return Mono of TemplateData, {@literal Mono.empty()} if no template with the given name exists.
* @since 4.1
* @deprecated since 5.1, as the underlying Elasticsearch API is deprecated.
*/
@Deprecated
default Mono<TemplateData> getTemplate(String templateName) {
return getTemplate(new GetTemplateRequest(templateName));
}
@ -246,7 +348,9 @@ public interface ReactiveIndexOperations {
* @param getTemplateRequest the request parameters
* @return Mono of TemplateData, {@literal Mono.empty()} if no template with the given name exists.
* @since 4.1
* @deprecated since 5.1, as the underlying Elasticsearch API is deprecated.
*/
@Deprecated
Mono<TemplateData> getTemplate(GetTemplateRequest getTemplateRequest);
/**
@ -256,7 +360,9 @@ public interface ReactiveIndexOperations {
* @param templateName the template name
* @return Mono of {@literal true} if the template exists
* @since 4.1
* @deprecated since 5.1, as the underlying Elasticsearch API is deprecated.
*/
@Deprecated
default Mono<Boolean> existsTemplate(String templateName) {
return existsTemplate(new ExistsTemplateRequest(templateName));
}
@ -268,7 +374,9 @@ public interface ReactiveIndexOperations {
* @param existsTemplateRequest template request parameters
* @return Mono of {@literal true} if the template exists
* @since 4.1
* @deprecated since 5.1, as the underlying Elasticsearch API is deprecated.
*/
@Deprecated
Mono<Boolean> existsTemplate(ExistsTemplateRequest existsTemplateRequest);
/**
@ -278,7 +386,9 @@ public interface ReactiveIndexOperations {
* @param templateName the template name
* @return Mono of {@literal true} if the template could be deleted
* @since 4.1
* @deprecated since 5.1, as the underlying Elasticsearch API is deprecated.
*/
@Deprecated
default Mono<Boolean> deleteTemplate(String templateName) {
return deleteTemplate(new DeleteTemplateRequest(templateName));
}
@ -290,7 +400,9 @@ public interface ReactiveIndexOperations {
* @param deleteTemplateRequest template request parameters
* @return Mono of {@literal true} if the template could be deleted
* @since 4.1
* @deprecated since 5.1, as the underlying Elasticsearch API is deprecated.
*/
@Deprecated
Mono<Boolean> deleteTemplate(DeleteTemplateRequest deleteTemplateRequest);
// endregion

View File

@ -13,20 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.client.erhlc;
package org.springframework.data.elasticsearch.core.cluster;
import reactor.core.publisher.Mono;
import org.springframework.data.elasticsearch.core.cluster.ClusterHealth;
/**
* Reactive Elasticsearch operations on cluster level.
*
* @author Peter-Josef Meisch
* @since 4.2
* @deprecated since 5.0
*/
@Deprecated
public interface ReactiveClusterOperations {
/**

View File

@ -0,0 +1,71 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.index;
import java.util.Map;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* A component template to be used in a component template request.
*
* @author Peter-Josef Meisch
* @since 5.1
*/
public record ComponentTemplateRequestData(@Nullable Settings settings, @Nullable Document mapping,
@Nullable AliasActions aliasActions, @Nullable Boolean allowAutoCreate) {
public static Builder builder() {
return new Builder();
}
public static final class Builder {
@Nullable private Settings settings;
@Nullable private Document mapping;
@Nullable private AliasActions aliasActions;
@Nullable private Boolean allowAutoCreate;
public Builder withSettings(Map<String, Object> settings) {
this.settings = new Settings(settings);
return this;
}
public Builder withMapping(Document mapping) {
this.mapping = mapping;
return this;
}
public Builder withAliasActions(AliasActions aliasActions) {
aliasActions.getActions().forEach(action -> Assert.isTrue(action instanceof AliasAction.Add,
"only alias add actions are allowed in templates"));
this.aliasActions = aliasActions;
return this;
}
public Builder withAllowAutoCreate(@Nullable Boolean allowAutoCreate) {
this.allowAutoCreate = allowAutoCreate;
return this;
}
public ComponentTemplateRequestData build() {
return new ComponentTemplateRequestData(settings, mapping, aliasActions, allowAutoCreate);
}
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.index;
import org.springframework.util.Assert;
/**
* @author Peter-Josef Meisch
* @since 5.1
*/
public record DeleteComponentTemplateRequest(String templateName) {
public DeleteComponentTemplateRequest {
Assert.notNull(templateName, "templateName must not be null");
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.index;
import org.springframework.util.Assert;
/**
* @author Peter-Josef Meisch
* @since 5.1
*/
public record DeleteIndexTemplateRequest(String templateName) {
public DeleteIndexTemplateRequest {
Assert.notNull(templateName, "templateName must not be null");
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.index;
import org.springframework.util.Assert;
/**
* @author Peter-Josef Meisch
* @since 5.1
*/
public record ExistsComponentTemplateRequest(String templateName) {
public ExistsComponentTemplateRequest {
Assert.notNull(templateName, "templateName must not be null");
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.index;
import org.springframework.util.Assert;
/**
* @author Peter-Josef Meisch
* @since 5.1
*/
public record ExistsIndexTemplateRequest(String templateName) {
public ExistsIndexTemplateRequest {
Assert.notNull(templateName, "templateName must not be null");
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.index;
import org.springframework.util.Assert;
/**
* @author Peter-Josef Meisch
* @since 5.1
*/
public record GetComponentTemplateRequest(String templateName) {
public GetComponentTemplateRequest {
Assert.notNull(templateName, "templateName must not be null");
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.index;
import org.springframework.util.Assert;
/**
* @author Peter-Josef Meisch
* @since 5.1
*/
public record GetIndexTemplateRequest(String templateName) {
public GetIndexTemplateRequest {
Assert.notNull(templateName, "templateName must not be null");
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.index;
import java.time.Duration;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* @author Peter-Josef Meisch
* @since 5.1
*/
public record PutComponentTemplateRequest(String name, @Nullable Long version, @Nullable Boolean create,
@Nullable Duration masterTimeout, ComponentTemplateRequestData template) {
public PutComponentTemplateRequest {
Assert.notNull(name, "name must not be null");
Assert.notNull(template, "template must not be null");
}
public static Builder builder() {
return new Builder();
}
public static final class Builder {
@Nullable private String name;
@Nullable private Long version;
@Nullable private Boolean create;
@Nullable private Duration masterTimeout;
@Nullable private ComponentTemplateRequestData template;
public Builder withName(String name) {
this.name = name;
return this;
}
public Builder withVersion(Long version) {
this.version = version;
return this;
}
public Builder withCreate(Boolean create) {
this.create = create;
return this;
}
public Builder withMasterTimeout(Duration masterTimeout) {
this.masterTimeout = masterTimeout;
return this;
}
public Builder withTemplateData(ComponentTemplateRequestData template) {
this.template = template;
return this;
}
public PutComponentTemplateRequest build() {
Assert.notNull(name, "name must not be null");
Assert.notNull(template, "template must not be null");
return new PutComponentTemplateRequest(name, version, create, masterTimeout, template);
}
}
}

View File

@ -0,0 +1,85 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.index;
import java.util.List;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* @author Peter-Josef Meisch
* @since 5.1
*/
public record PutIndexTemplateRequest(String name, String[] indexPatterns, @Nullable Settings settings,
@Nullable Document mapping, @Nullable AliasActions aliasActions, List<String> composedOf) {
public static Builder builder() {
return new Builder();
}
public static class Builder {
@Nullable private String name;
@Nullable private String[] indexPatterns;
@Nullable private Settings settings;
@Nullable private Document mapping;
@Nullable AliasActions aliasActions;
@Nullable List<String> composedOf;
public Builder withName(String name) {
this.name = name;
return this;
}
public Builder withIndexPatterns(String... indexPatterns) {
this.indexPatterns = indexPatterns;
return this;
}
public Builder withSettings(Settings settings) {
this.settings = settings;
return this;
}
public Builder withMapping(Document mapping) {
this.mapping = mapping;
return this;
}
public Builder withAliasActions(AliasActions aliasActions) {
this.aliasActions = aliasActions;
return this;
}
public Builder withComposedOf(List<String> composedOf) {
this.composedOf = composedOf;
return this;
}
public PutIndexTemplateRequest build() {
Assert.notNull(name, "name must not be null");
Assert.notNull(indexPatterns, "indexPatterns must not be null");
Assert.isTrue(indexPatterns.length > 0, "indexPatterns must not be empty");
return new PutIndexTemplateRequest(name, indexPatterns, settings, mapping, aliasActions,
composedOf != null ? composedOf : List.of());
}
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.index;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* @author Peter-Josef Meisch
* @since 5.1
*/
public record TemplateResponse(String name, @Nullable Long version, @Nullable TemplateResponseData templateData) {
public TemplateResponse {
Assert.notNull(name, "name must not be null");
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
@Nullable private String name;
@Nullable private Long version;
@Nullable private TemplateResponseData templateData;
public Builder withName(String name) {
this.name = name;
return this;
}
public Builder withVersion(Long version) {
this.version = version;
return this;
}
public Builder withTemplateData(TemplateResponseData templateData) {
this.templateData = templateData;
return this;
}
public TemplateResponse build() {
return new TemplateResponse(name, version, templateData);
}
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.index;
import java.util.List;
import java.util.Map;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* @author Peter-Josef Meisch
* @since 5.1
*/
public record TemplateResponseData(@Nullable Document mapping, @Nullable Settings settings,
Map<String, AliasData> aliases, List<String> composedOf) {
public TemplateResponseData {
Assert.notNull(aliases, "aliases must not be null");
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
@Nullable private Document mapping;
@Nullable private Settings settings;
@Nullable private Map<String, AliasData> aliases;
@Nullable private List<String> composedOf;
public Builder withMapping(@Nullable Document mapping) {
this.mapping = mapping;
return this;
}
public Builder withSettings(@Nullable Settings settings) {
this.settings = settings;
return this;
}
public Builder withAliases(@Nullable Map<String, AliasData> aliases) {
this.aliases = aliases;
return this;
}
public Builder withComposedOf(@Nullable List<String> composedOf) {
this.composedOf = composedOf;
return this;
}
public TemplateResponseData build() {
return new TemplateResponseData(mapping, settings, aliases != null ? aliases : Map.of(),
composedOf != null ? composedOf : List.of());
}
}
}

View File

@ -15,6 +15,8 @@
*/
package org.springframework.data.elasticsearch.repository.query;
import java.util.Collections;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHitSupport;
@ -32,8 +34,6 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import java.util.Collections;
/**
* AbstractElasticsearchRepositoryQuery
*
@ -148,9 +148,6 @@ public abstract class AbstractElasticsearchRepositoryQuery implements Repository
query.addSourceFilter(sourceFilter);
}
// todo #2338 remove that call, this should be done when the real request is built
// elasticsearchConverter.updateQuery(query, clazz);
return query;
}

View File

@ -35,7 +35,6 @@ import org.springframework.data.elasticsearch.core.document.SearchDocument;
* @author Peter-Josef Meisch
* @since 4.4
*/
// todo #1973 check that all is tested what was in the elasticsearch7 version
class DocumentAdaptersUnitTests {
private final JsonpMapper jsonpMapper = new JacksonJsonpMapper();

View File

@ -15,9 +15,17 @@
*/
package org.springframework.data.elasticsearch.client.elc;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import co.elastic.clients.elasticsearch.indices.RefreshRequest;
import co.elastic.clients.json.JsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -27,13 +35,6 @@ import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;
/**
* @author Urs Keller
@ -43,6 +44,7 @@ import static org.mockito.Mockito.*;
class ReactiveIndicesTemplateTest {
@Mock private ElasticsearchConverter elasticsearchConverter;
@Mock private ReactiveElasticsearchIndicesClient client;
@Mock private ReactiveClusterTemplate cluster;
@Mock private ElasticsearchTransport transport;
@Mock private JsonpMapper jsonpMapper;
@Captor ArgumentCaptor<RefreshRequest> refreshRequest;
@ -59,7 +61,8 @@ class ReactiveIndicesTemplateTest {
@Test
void refresh() {
IndexCoordinates indexCoordinate = IndexCoordinates.of("i1", "i2");
ReactiveIndicesTemplate template = new ReactiveIndicesTemplate(client, elasticsearchConverter, indexCoordinate);
ReactiveIndicesTemplate template = new ReactiveIndicesTemplate(client, cluster, elasticsearchConverter,
indexCoordinate);
doReturn(Mono.empty()).when(client).refresh(any(RefreshRequest.class));
template.refresh().as(StepVerifier::create).verifyComplete();

View File

@ -26,7 +26,6 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.client.erhlc.ReactiveClusterOperations;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.indices;
package org.springframework.data.elasticsearch.core.index;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.indices;
package org.springframework.data.elasticsearch.core.index;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.indices;
package org.springframework.data.elasticsearch.core.index;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import java.util.Map;
@ -36,11 +36,6 @@ import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.IndexInformation;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.index.AliasAction;
import org.springframework.data.elasticsearch.core.index.AliasActionParameters;
import org.springframework.data.elasticsearch.core.index.AliasActions;
import org.springframework.data.elasticsearch.core.index.AliasData;
import org.springframework.data.elasticsearch.core.index.Settings;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;

View File

@ -15,13 +15,15 @@
*/
package org.springframework.data.elasticsearch.core.index;
import static org.assertj.core.api.Assertions.assertThat;
import static org.skyscreamer.jsonassert.JSONAssert.assertEquals;
import static org.assertj.core.api.Assertions.*;
import static org.skyscreamer.jsonassert.JSONAssert.*;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.json.JSONException;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIf;
import org.springframework.beans.factory.annotation.Autowired;
@ -37,6 +39,7 @@ import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.lang.Nullable;
@ -55,7 +58,7 @@ public abstract class IndexTemplateIntegrationTests implements NewElasticsearchC
@DisabledIf(value = "rhlcWithCluster8", disabledReason = "RHLC fails to parse response from ES 8.2")
@Test // DATAES-612
void shouldCreateTemplate() {
void shouldPutTemplate() {
IndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care"));
@ -75,6 +78,232 @@ public abstract class IndexTemplateIntegrationTests implements NewElasticsearchC
assertThat(acknowledged).isTrue();
}
@DisabledIf(value = "oldElasticsearchClient", disabledReason = "not implemented for the deprecated old client")
@Test // #1458
@DisplayName("should create component template")
void shouldCreateComponentTemplate() {
IndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care"));
org.springframework.data.elasticsearch.core.document.Document mapping = indexOps.createMapping(TemplateClass.class);
Settings settings = indexOps.createSettings(TemplateClass.class);
AliasActions aliasActions = new AliasActions( //
new AliasAction.Add(AliasActionParameters.builderForTemplate() //
.withAliases("alias1", "alias2") //
.withFilterQuery(Query.findAll()) //
.build())); //
var putComponentTemplateRequest = PutComponentTemplateRequest.builder() //
.withName("test-component-template") //
.withTemplateData(ComponentTemplateRequestData.builder() //
.withAliasActions(aliasActions) //
.withMapping(mapping) //
.withSettings(settings) //
.build() //
).build();
boolean acknowledged = indexOps.putComponentTemplate(putComponentTemplateRequest);
assertThat(acknowledged).isTrue();
}
@DisabledIf(value = "oldElasticsearchClient", disabledReason = "not implemented for the deprecated old client")
@Test // #1458
@DisplayName("should get component template")
void shouldGetComponentTemplate() throws JSONException {
IndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care"));
org.springframework.data.elasticsearch.core.document.Document mapping = indexOps.createMapping(TemplateClass.class);
Settings settings = indexOps.createSettings(TemplateClass.class);
var filterQuery = CriteriaQuery.builder(Criteria.where("message").is("foo")).build();
AliasActions aliasActions = new AliasActions(new AliasAction.Add(AliasActionParameters.builderForTemplate() //
.withAliases("alias1", "alias2") //
.withFilterQuery(filterQuery, TemplateClass.class)//
.build()));
PutComponentTemplateRequest putComponentTemplateRequest = PutComponentTemplateRequest.builder() //
.withName("test-component-template") //
.withVersion(42L) //
.withTemplateData(ComponentTemplateRequestData.builder() //
.withSettings(settings) //
.withMapping(mapping) //
.withAliasActions(aliasActions) //
.build()) //
.build();
boolean acknowledged = indexOps.putComponentTemplate(putComponentTemplateRequest);
assertThat(acknowledged).isTrue();
GetComponentTemplateRequest getComponentTemplateRequest = new GetComponentTemplateRequest(
putComponentTemplateRequest.name());
var componentTemplates = indexOps.getComponentTemplate(getComponentTemplateRequest);
assertThat(componentTemplates).isNotNull().hasSize(1);
var returnedComponentTemplate = componentTemplates.iterator().next();
assertThat(returnedComponentTemplate.version()).isEqualTo(putComponentTemplateRequest.version());
var componentTemplateData = returnedComponentTemplate.templateData();
assertEquals(mapping.toJson(), componentTemplateData.mapping().toJson(), false);
assertEquals(settings.flatten().toJson(), componentTemplateData.settings().flatten().toJson(), false);
var aliases = componentTemplateData.aliases();
assertThat(aliases).hasSize(2);
AliasData alias1 = aliases.get("alias1");
assertThat(alias1.getAlias()).isEqualTo("alias1");
assertThat(alias1.getFilterQuery()).isNotNull();
AliasData alias2 = aliases.get("alias2");
assertThat(alias2.getFilterQuery()).isNotNull();
assertThat(alias2.getAlias()).isEqualTo("alias2");
}
@DisabledIf(value = "oldElasticsearchClient", disabledReason = "not implemented for the deprecated old client")
@Test // #1458
@DisplayName("should delete component template")
void shouldDeleteComponentTemplate() {
IndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care"));
String templateName = "template" + UUID.randomUUID().toString();
var putComponentTemplateRequest = PutComponentTemplateRequest.builder() //
.withName(templateName) //
.withTemplateData(ComponentTemplateRequestData.builder() //
.withSettings(indexOps.createSettings(TemplateClass.class)) //
.build() //
).build();
ExistsComponentTemplateRequest existsComponentTemplateRequest = new ExistsComponentTemplateRequest(templateName);
boolean acknowledged = indexOps.putComponentTemplate(putComponentTemplateRequest);
assertThat(acknowledged).isTrue();
boolean exists = indexOps.existsComponentTemplate(existsComponentTemplateRequest);
assertThat(exists).isTrue();
acknowledged = indexOps.deleteComponentTemplate(new DeleteComponentTemplateRequest(templateName));
assertThat(acknowledged).isTrue();
exists = indexOps.existsComponentTemplate(existsComponentTemplateRequest);
assertThat(exists).isFalse();
}
@DisabledIf(value = "oldElasticsearchClient", disabledReason = "not implemented for the deprecated old client")
@Test // #1458
@DisplayName("should put, get and delete index template with template")
void shouldPutGetAndDeleteIndexTemplateWithTemplate() {
IndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care"));
org.springframework.data.elasticsearch.core.document.Document mapping = indexOps.createMapping(TemplateClass.class);
Settings settings = indexOps.createSettings(TemplateClass.class);
AliasActions aliasActions = new AliasActions( //
new AliasAction.Add(AliasActionParameters.builderForTemplate() //
.withAliases("alias1", "alias2") //
.withFilterQuery(Query.findAll()) //
.build())); //
var indexTemplateName = "test-index-template";
var putIndexTemplateRequest = PutIndexTemplateRequest.builder() //
.withName(indexTemplateName) //
.withIndexPatterns("index-*", "endix-*") //
.withSettings(settings) //
.withMapping(mapping) //
.withAliasActions(aliasActions) //
.build();
boolean acknowledged = indexOps.putIndexTemplate(putIndexTemplateRequest);
assertThat(acknowledged).isTrue();
var exists = indexOps.existsIndexTemplate(indexTemplateName);
assertThat(exists).isTrue();
var indexTemplates = indexOps.getIndexTemplate(indexTemplateName);
assertThat(indexTemplates).hasSize(1);
// delete template
acknowledged = indexOps.deleteIndexTemplate(indexTemplateName);
assertThat(acknowledged).isTrue();
exists = indexOps.existsIndexTemplate(indexTemplateName);
assertThat(exists).isFalse();
}
@DisabledIf(value = "oldElasticsearchClient", disabledReason = "not implemented for the deprecated old client")
@Test // #1458
@DisplayName("should put, get and delete index template of components")
void shouldPutGetAndDeleteIndexTemplateOfComponents() {
IndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care"));
org.springframework.data.elasticsearch.core.document.Document mapping = indexOps.createMapping(TemplateClass.class);
Settings settings = indexOps.createSettings(TemplateClass.class);
var filterQuery = CriteriaQuery.builder(Criteria.where("message").is("foo")).build();
AliasActions aliasActions = new AliasActions(new AliasAction.Add(AliasActionParameters.builderForTemplate() //
.withAliases("alias1", "alias2") //
.withFilterQuery(filterQuery, TemplateClass.class)//
.build()));
PutComponentTemplateRequest putComponentTemplateRequestMapping = PutComponentTemplateRequest.builder() //
.withName("test-component-template-mapping") //
.withVersion(42L) //
.withTemplateData(ComponentTemplateRequestData.builder() //
.withMapping(mapping) //
.build()) //
.build();
boolean acknowledged = indexOps.putComponentTemplate(putComponentTemplateRequestMapping);
assertThat(acknowledged).isTrue();
PutComponentTemplateRequest putComponentTemplateRequestSettings = PutComponentTemplateRequest.builder() //
.withName("test-component-template-settings") //
.withVersion(42L) //
.withTemplateData(ComponentTemplateRequestData.builder() //
.withSettings(settings) //
.build()) //
.build();
acknowledged = indexOps.putComponentTemplate(putComponentTemplateRequestSettings);
assertThat(acknowledged).isTrue();
PutComponentTemplateRequest putComponentTemplateRequestAliases = PutComponentTemplateRequest.builder() //
.withName("test-component-template-aliases") //
.withVersion(42L) //
.withTemplateData(ComponentTemplateRequestData.builder() //
.withAliasActions(aliasActions) //
.build()) //
.build();
acknowledged = indexOps.putComponentTemplate(putComponentTemplateRequestAliases);
assertThat(acknowledged).isTrue();
var indexTemplateName = "test-index-template";
var composedOf = List.of("test-component-template-mapping", "test-component-template-settings",
"test-component-template-aliases");
var putIndexTemplateRequest = PutIndexTemplateRequest.builder() //
.withName(indexTemplateName) //
.withIndexPatterns("index-*", "endix-*") //
.withComposedOf(composedOf) //
.build();
acknowledged = indexOps.putIndexTemplate(putIndexTemplateRequest);
assertThat(acknowledged).isTrue();
var indexTemplates = indexOps.getIndexTemplate(indexTemplateName);
assertThat(indexTemplates).hasSize(1);
assertThat(indexTemplates.get(0).templateData().composedOf()).isEqualTo(composedOf);
// delete template and components
acknowledged = indexOps.deleteIndexTemplate(indexTemplateName);
assertThat(acknowledged).isTrue();
acknowledged = indexOps
.deleteComponentTemplate(new DeleteComponentTemplateRequest("test-component-template-mapping"));
assertThat(acknowledged).isTrue();
acknowledged = indexOps
.deleteComponentTemplate(new DeleteComponentTemplateRequest("test-component-template-settings"));
assertThat(acknowledged).isTrue();
acknowledged = indexOps
.deleteComponentTemplate(new DeleteComponentTemplateRequest("test-component-template-aliases"));
assertThat(acknowledged).isTrue();
}
@Test // DATAES-612
void shouldReturnNullOnNonExistingGetTemplate() {
@ -177,7 +406,6 @@ public abstract class IndexTemplateIntegrationTests implements NewElasticsearchC
exists = indexOps.existsTemplate(existsTemplateRequest);
assertThat(exists).isFalse();
}
@Document(indexName = "test-template")

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.indices;
package org.springframework.data.elasticsearch.core.index;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.indices;
package org.springframework.data.elasticsearch.core.index;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.indices;
package org.springframework.data.elasticsearch.core.index;
import static org.assertj.core.api.Assertions.*;
import static org.skyscreamer.jsonassert.JSONAssert.*;
@ -22,16 +22,12 @@ import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.time.LocalDate;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.assertj.core.api.SoftAssertions;
import org.json.JSONException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIf;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.NewElasticsearchClientDevelopment;
@ -44,16 +40,6 @@ import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.data.elasticsearch.core.AbstractReactiveElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ReactiveIndexOperations;
import org.springframework.data.elasticsearch.core.index.AliasAction;
import org.springframework.data.elasticsearch.core.index.AliasActionParameters;
import org.springframework.data.elasticsearch.core.index.AliasActions;
import org.springframework.data.elasticsearch.core.index.AliasData;
import org.springframework.data.elasticsearch.core.index.DeleteTemplateRequest;
import org.springframework.data.elasticsearch.core.index.ExistsTemplateRequest;
import org.springframework.data.elasticsearch.core.index.GetTemplateRequest;
import org.springframework.data.elasticsearch.core.index.PutTemplateRequest;
import org.springframework.data.elasticsearch.core.index.Settings;
import org.springframework.data.elasticsearch.core.index.TemplateData;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
@ -376,124 +362,6 @@ public abstract class ReactiveIndexOperationsIntegrationTests implements NewElas
.verifyComplete();
}
@DisabledIf(value = "rhlcWithCluster8", disabledReason = "RHLC fails to parse response from ES 8.2")
@Test // DATAES-612
void shouldPutTemplate() {
org.springframework.data.elasticsearch.core.document.Document mapping = indexOperations
.createMapping(TemplateClass.class).block();
Settings settings = indexOperations.createSettings(TemplateClass.class).block();
AliasActions aliasActions = new AliasActions(
new AliasAction.Add(AliasActionParameters.builderForTemplate().withAliases("alias1", "alias2").build()));
PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder("test-template", "log-*") //
.withSettings(settings) //
.withMappings(mapping) //
.withAliasActions(aliasActions) //
.withOrder(11) //
.withVersion(42) //
.build();
Boolean acknowledged = indexOperations.putTemplate(putTemplateRequest).block();
assertThat(acknowledged).isTrue();
}
@Test // DATAES-612
void shouldReturnNullOnNonExistingGetTemplate() {
String templateName = "template" + UUID.randomUUID().toString();
GetTemplateRequest getTemplateRequest = new GetTemplateRequest(templateName);
indexOperations.getTemplate(getTemplateRequest) //
.as(StepVerifier::create) //
.verifyComplete();
}
@DisabledIf(value = "rhlcWithCluster8", disabledReason = "RHLC fails to parse response from ES 8.2")
@Test // DATAES-612
void shouldGetTemplate() throws JSONException {
org.springframework.data.elasticsearch.core.document.Document mapping = indexOperations
.createMapping(TemplateClass.class).block();
Settings settings = indexOperations.createSettings(TemplateClass.class).block();
AliasActions aliasActions = new AliasActions(
new AliasAction.Add(AliasActionParameters.builderForTemplate().withAliases("alias1", "alias2").build()));
PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder("test-template", "log-*") //
.withSettings(settings) //
.withMappings(mapping) //
.withAliasActions(aliasActions) //
.withOrder(11) //
.withVersion(42) //
.build();
Boolean acknowledged = indexOperations.putTemplate(putTemplateRequest).block();
assertThat(acknowledged).isTrue();
GetTemplateRequest getTemplateRequest = new GetTemplateRequest(putTemplateRequest.getName());
TemplateData templateData = indexOperations.getTemplate(getTemplateRequest).block();
SoftAssertions softly = new SoftAssertions();
softly.assertThat(templateData).isNotNull();
softly.assertThat(templateData.getIndexPatterns()).containsExactlyInAnyOrder(putTemplateRequest.getIndexPatterns());
assertEquals(settings.flatten().toJson(), templateData.getSettings().toJson(), false);
assertEquals(mapping.toJson(), templateData.getMapping().toJson(), false);
Map<String, AliasData> aliases = templateData.getAliases();
softly.assertThat(aliases).hasSize(2);
AliasData alias1 = aliases.get("alias1");
softly.assertThat(alias1.getAlias()).isEqualTo("alias1");
AliasData alias2 = aliases.get("alias2");
softly.assertThat(alias2.getAlias()).isEqualTo("alias2");
softly.assertThat(templateData.getOrder()).isEqualTo(putTemplateRequest.getOrder());
softly.assertThat(templateData.getVersion()).isEqualTo(putTemplateRequest.getVersion());
softly.assertAll();
}
@Test // DATAES-612
void shouldCheckTemplateExists() {
String templateName = "template" + UUID.randomUUID().toString();
ExistsTemplateRequest existsTemplateRequest = new ExistsTemplateRequest(templateName);
boolean exists = indexOperations.existsTemplate(existsTemplateRequest).block();
assertThat(exists).isFalse();
PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder(templateName, "log-*") //
.withOrder(11) //
.withVersion(42) //
.build();
boolean acknowledged = indexOperations.putTemplate(putTemplateRequest).block();
assertThat(acknowledged).isTrue();
exists = indexOperations.existsTemplate(existsTemplateRequest).block();
assertThat(exists).isTrue();
}
@Test // DATAES-612
void shouldDeleteTemplate() {
String templateName = "template" + UUID.randomUUID().toString();
ExistsTemplateRequest existsTemplateRequest = new ExistsTemplateRequest(templateName);
PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder(templateName, "log-*") //
.withOrder(11) //
.withVersion(42) //
.build();
boolean acknowledged = indexOperations.putTemplate(putTemplateRequest).block();
assertThat(acknowledged).isTrue();
boolean exists = indexOperations.existsTemplate(existsTemplateRequest).block();
assertThat(exists).isTrue();
acknowledged = indexOperations.deleteTemplate(new DeleteTemplateRequest(templateName)).block();
assertThat(acknowledged).isTrue();
exists = indexOperations.existsTemplate(existsTemplateRequest).block();
assertThat(exists).isFalse();
}
@Document(indexName = "#{@indexNameProvider.indexName()}")
@Setting(shards = 3, replicas = 2, refreshInterval = "4s")
static class Entity {
@ -549,32 +417,4 @@ public abstract class ReactiveIndexOperationsIntegrationTests implements NewElas
this.id = id;
}
}
@Document(indexName = "#{@indexNameProvider.indexName()}")
@Setting(refreshInterval = "5s")
static class TemplateClass {
@Id
@Nullable private String id;
@Field(type = FieldType.Text)
@Nullable private String message;
@Nullable
public String getId() {
return id;
}
public void setId(@Nullable String id) {
this.id = id;
}
@Nullable
public String getMessage() {
return message;
}
public void setMessage(@Nullable String message) {
this.message = message;
}
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.index;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
import org.springframework.test.context.ContextConfiguration;
/**
* @author Peter-Josef Meisch
*/
@ContextConfiguration(classes = { ReactiveIndexTemplateELCIntegrationTests.Config.class })
public class ReactiveIndexTemplateELCIntegrationTests extends ReactiveIndexTemplateIntegrationTests {
@Configuration
@Import({ ReactiveElasticsearchTemplateConfiguration.class })
static class Config {
@Bean
IndexNameProvider indexNameProvider() {
return new IndexNameProvider("reactive-index-template");
}
}
@Override
public boolean newElasticsearchClient() {
return true;
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.index;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
import org.springframework.test.context.ContextConfiguration;
/**
* @author Peter-Josef Meisch
*/
@ContextConfiguration(classes = { ReactiveIndexTemplateERHLCIntegrationTests.Config.class })
public class ReactiveIndexTemplateERHLCIntegrationTests extends ReactiveIndexOperationsIntegrationTests {
@Configuration
@Import({ ReactiveElasticsearchRestTemplateConfiguration.class })
static class Config {
@Bean
IndexNameProvider indexNameProvider() {
return new IndexNameProvider("reactive-index-template-es7");
}
}
}

View File

@ -0,0 +1,454 @@
/*
* Copyright 2018-2023 the original author or authors.
*
* Licensed 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
*
* https://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.springframework.data.elasticsearch.core.index;
import static org.assertj.core.api.Assertions.*;
import static org.skyscreamer.jsonassert.JSONAssert.*;
import reactor.test.StepVerifier;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.assertj.core.api.SoftAssertions;
import org.json.JSONException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIf;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.NewElasticsearchClientDevelopment;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.data.elasticsearch.core.AbstractReactiveElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ReactiveIndexOperations;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
*/
@SpringIntegrationTest
public abstract class ReactiveIndexTemplateIntegrationTests implements NewElasticsearchClientDevelopment {
@Autowired private ReactiveElasticsearchOperations operations;
@Autowired private IndexNameProvider indexNameProvider;
private ReactiveIndexOperations indexOperations;
boolean rhlcWithCluster8() {
var clusterVersion = ((AbstractReactiveElasticsearchTemplate) operations).getClusterVersion().block();
return (oldElasticsearchClient() && clusterVersion != null && clusterVersion.startsWith("8"));
}
@BeforeEach
void setUp() {
indexNameProvider.increment();
indexOperations = operations.indexOps(IndexCoordinates.of(indexNameProvider.indexName()));
}
@Test
@Order(Integer.MAX_VALUE)
void cleanup() {
operations.indexOps(IndexCoordinates.of(indexNameProvider.getPrefix() + "*")).delete().block();
}
@DisabledIf(value = "rhlcWithCluster8", disabledReason = "RHLC fails to parse response from ES 8.2")
@Test // DATAES-612
void shouldPutTemplate() {
org.springframework.data.elasticsearch.core.document.Document mapping = indexOperations
.createMapping(TemplateClass.class).block();
Settings settings = indexOperations.createSettings(TemplateClass.class).block();
AliasActions aliasActions = new AliasActions(
new AliasAction.Add(AliasActionParameters.builderForTemplate().withAliases("alias1", "alias2").build()));
PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder("test-template", "log-*") //
.withSettings(settings) //
.withMappings(mapping) //
.withAliasActions(aliasActions) //
.withOrder(11) //
.withVersion(42) //
.build();
Boolean acknowledged = indexOperations.putTemplate(putTemplateRequest).block();
assertThat(acknowledged).isTrue();
}
@DisabledIf(value = "oldElasticsearchClient", disabledReason = "not implemented for the deprecated old client")
@Test // #1458
@DisplayName("should create component template")
void shouldCreateComponentTemplate() {
ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care"));
org.springframework.data.elasticsearch.core.document.Document mapping = indexOps.createMapping(TemplateClass.class)
.block();
Settings settings = indexOps.createSettings(TemplateClass.class).block();
AliasActions aliasActions = new AliasActions( //
new AliasAction.Add(AliasActionParameters.builderForTemplate() //
.withAliases("alias1", "alias2") //
.withFilterQuery(Query.findAll()) //
.build())); //
var putComponentTemplateRequest = PutComponentTemplateRequest.builder() //
.withName("test-component-template") //
.withTemplateData(ComponentTemplateRequestData.builder() //
.withAliasActions(aliasActions) //
.withMapping(mapping) //
.withSettings(settings) //
.build() //
).build();
boolean acknowledged = indexOps.putComponentTemplate(putComponentTemplateRequest).block();
assertThat(acknowledged).isTrue();
}
@DisabledIf(value = "oldElasticsearchClient", disabledReason = "not implemented for the deprecated old client")
@Test // #1458
@DisplayName("should get component template")
void shouldGetComponentTemplate() throws JSONException {
ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care"));
org.springframework.data.elasticsearch.core.document.Document mapping = indexOps.createMapping(TemplateClass.class)
.block();
Settings settings = indexOps.createSettings(TemplateClass.class).block();
var filterQuery = CriteriaQuery.builder(Criteria.where("message").is("foo")).build();
AliasActions aliasActions = new AliasActions(new AliasAction.Add(AliasActionParameters.builderForTemplate() //
.withAliases("alias1", "alias2") //
.withFilterQuery(filterQuery, TemplateClass.class)//
.build()));
PutComponentTemplateRequest putComponentTemplateRequest = PutComponentTemplateRequest.builder() //
.withName("test-component-template") //
.withVersion(42L) //
.withTemplateData(ComponentTemplateRequestData.builder() //
.withSettings(settings) //
.withMapping(mapping) //
.withAliasActions(aliasActions) //
.build()) //
.build();
boolean acknowledged = indexOps.putComponentTemplate(putComponentTemplateRequest).block();
assertThat(acknowledged).isTrue();
GetComponentTemplateRequest getComponentTemplateRequest = new GetComponentTemplateRequest(
putComponentTemplateRequest.name());
var componentTemplates = indexOps.getComponentTemplate(getComponentTemplateRequest).collectList().block();
assertThat(componentTemplates).isNotNull().hasSize(1);
var returnedComponentTemplate = componentTemplates.iterator().next();
assertThat(returnedComponentTemplate.version()).isEqualTo(putComponentTemplateRequest.version());
var componentTemplateData = returnedComponentTemplate.templateData();
assertEquals(mapping.toJson(), componentTemplateData.mapping().toJson(), false);
assertEquals(settings.flatten().toJson(), componentTemplateData.settings().flatten().toJson(), false);
var aliases = componentTemplateData.aliases();
assertThat(aliases).hasSize(2);
AliasData alias1 = aliases.get("alias1");
assertThat(alias1.getAlias()).isEqualTo("alias1");
assertThat(alias1.getFilterQuery()).isNotNull();
AliasData alias2 = aliases.get("alias2");
assertThat(alias2.getFilterQuery()).isNotNull();
assertThat(alias2.getAlias()).isEqualTo("alias2");
}
@DisabledIf(value = "oldElasticsearchClient", disabledReason = "not implemented for the deprecated old client")
@Test // #1458
@DisplayName("should delete component template")
void shouldDeleteComponentTemplate() {
ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care"));
String templateName = "template" + UUID.randomUUID().toString();
var putComponentTemplateRequest = PutComponentTemplateRequest.builder() //
.withName(templateName) //
.withTemplateData(ComponentTemplateRequestData.builder() //
.withSettings(indexOps.createSettings(TemplateClass.class).block()) //
.build() //
).build();
ExistsComponentTemplateRequest existsComponentTemplateRequest = new ExistsComponentTemplateRequest(templateName);
boolean acknowledged = indexOps.putComponentTemplate(putComponentTemplateRequest).block();
assertThat(acknowledged).isTrue();
boolean exists = indexOps.existsComponentTemplate(existsComponentTemplateRequest).block();
assertThat(exists).isTrue();
acknowledged = indexOps.deleteComponentTemplate(new DeleteComponentTemplateRequest(templateName)).block();
assertThat(acknowledged).isTrue();
exists = indexOps.existsComponentTemplate(existsComponentTemplateRequest).block();
assertThat(exists).isFalse();
}
@DisabledIf(value = "oldElasticsearchClient", disabledReason = "not implemented for the deprecated old client")
@Test // #1458
@DisplayName("should put, get and delete index template with template")
void shouldPutGetAndDeleteIndexTemplateWithTemplate() {
ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care"));
org.springframework.data.elasticsearch.core.document.Document mapping = indexOps.createMapping(TemplateClass.class)
.block();
Settings settings = indexOps.createSettings(TemplateClass.class).block();
AliasActions aliasActions = new AliasActions( //
new AliasAction.Add(AliasActionParameters.builderForTemplate() //
.withAliases("alias1", "alias2") //
.withFilterQuery(Query.findAll()) //
.build())); //
var indexTemplateName = "test-index-template";
var putIndexTemplateRequest = PutIndexTemplateRequest.builder() //
.withName(indexTemplateName) //
.withIndexPatterns("index-*", "endix-*") //
.withSettings(settings) //
.withMapping(mapping) //
.withAliasActions(aliasActions) //
.build();
Boolean acknowledged = indexOps.putIndexTemplate(putIndexTemplateRequest).block();
assertThat(acknowledged).isTrue();
var exists = indexOps.existsIndexTemplate(indexTemplateName).block();
assertThat(exists).isTrue();
var indexTemplates = indexOps.getIndexTemplate(indexTemplateName).collectList().block();
assertThat(indexTemplates).hasSize(1);
// delete template
acknowledged = indexOps.deleteIndexTemplate(indexTemplateName).block();
assertThat(acknowledged).isTrue();
exists = indexOps.existsIndexTemplate(indexTemplateName).block();
assertThat(exists).isFalse();
}
@DisabledIf(value = "oldElasticsearchClient", disabledReason = "not implemented for the deprecated old client")
@Test // #1458
@DisplayName("should put, get and delete index template of components")
void shouldPutGetAndDeleteIndexTemplateOfComponents() {
ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care"));
org.springframework.data.elasticsearch.core.document.Document mapping = indexOps.createMapping(TemplateClass.class)
.block();
Settings settings = indexOps.createSettings(TemplateClass.class).block();
var filterQuery = CriteriaQuery.builder(Criteria.where("message").is("foo")).build();
AliasActions aliasActions = new AliasActions(new AliasAction.Add(AliasActionParameters.builderForTemplate() //
.withAliases("alias1", "alias2") //
.withFilterQuery(filterQuery, IndexTemplateIntegrationTests.TemplateClass.class)//
.build()));
PutComponentTemplateRequest putComponentTemplateRequestMapping = PutComponentTemplateRequest.builder() //
.withName("test-component-template-mapping") //
.withVersion(42L) //
.withTemplateData(ComponentTemplateRequestData.builder() //
.withMapping(mapping) //
.build()) //
.build();
Boolean acknowledged = indexOps.putComponentTemplate(putComponentTemplateRequestMapping).block();
assertThat(acknowledged).isTrue();
PutComponentTemplateRequest putComponentTemplateRequestSettings = PutComponentTemplateRequest.builder() //
.withName("test-component-template-settings") //
.withVersion(42L) //
.withTemplateData(ComponentTemplateRequestData.builder() //
.withSettings(settings) //
.build()) //
.build();
acknowledged = indexOps.putComponentTemplate(putComponentTemplateRequestSettings).block();
assertThat(acknowledged).isTrue();
PutComponentTemplateRequest putComponentTemplateRequestAliases = PutComponentTemplateRequest.builder() //
.withName("test-component-template-aliases") //
.withVersion(42L) //
.withTemplateData(ComponentTemplateRequestData.builder() //
.withAliasActions(aliasActions) //
.build()) //
.build();
acknowledged = indexOps.putComponentTemplate(putComponentTemplateRequestAliases).block();
assertThat(acknowledged).isTrue();
var indexTemplateName = "test-index-template";
var composedOf = List.of("test-component-template-mapping", "test-component-template-settings",
"test-component-template-aliases");
var putIndexTemplateRequest = PutIndexTemplateRequest.builder() //
.withName(indexTemplateName) //
.withIndexPatterns("index-*", "endix-*") //
.withComposedOf(composedOf) //
.build();
acknowledged = indexOps.putIndexTemplate(putIndexTemplateRequest).block();
assertThat(acknowledged).isTrue();
var indexTemplates = indexOps.getIndexTemplate(indexTemplateName).collectList().block();
assertThat(indexTemplates).hasSize(1);
assertThat(indexTemplates.get(0).templateData().composedOf()).isEqualTo(composedOf);
// delete template and components
acknowledged = indexOps.deleteIndexTemplate(indexTemplateName).block();
assertThat(acknowledged).isTrue();
acknowledged = indexOps
.deleteComponentTemplate(new DeleteComponentTemplateRequest("test-component-template-mapping")).block();
assertThat(acknowledged).isTrue();
acknowledged = indexOps
.deleteComponentTemplate(new DeleteComponentTemplateRequest("test-component-template-settings")).block();
assertThat(acknowledged).isTrue();
acknowledged = indexOps
.deleteComponentTemplate(new DeleteComponentTemplateRequest("test-component-template-aliases")).block();
assertThat(acknowledged).isTrue();
}
@Test // DATAES-612
void shouldReturnNullOnNonExistingGetTemplate() {
String templateName = "template" + UUID.randomUUID().toString();
GetTemplateRequest getTemplateRequest = new GetTemplateRequest(templateName);
indexOperations.getTemplate(getTemplateRequest) //
.as(StepVerifier::create) //
.verifyComplete();
}
@DisabledIf(value = "rhlcWithCluster8", disabledReason = "RHLC fails to parse response from ES 8.2")
@Test // DATAES-612
void shouldGetTemplate() throws JSONException {
org.springframework.data.elasticsearch.core.document.Document mapping = indexOperations
.createMapping(TemplateClass.class).block();
Settings settings = indexOperations.createSettings(TemplateClass.class).block();
AliasActions aliasActions = new AliasActions(
new AliasAction.Add(AliasActionParameters.builderForTemplate().withAliases("alias1", "alias2").build()));
PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder("test-template", "log-*") //
.withSettings(settings) //
.withMappings(mapping) //
.withAliasActions(aliasActions) //
.withOrder(11) //
.withVersion(42) //
.build();
Boolean acknowledged = indexOperations.putTemplate(putTemplateRequest).block();
assertThat(acknowledged).isTrue();
GetTemplateRequest getTemplateRequest = new GetTemplateRequest(putTemplateRequest.getName());
TemplateData templateData = indexOperations.getTemplate(getTemplateRequest).block();
SoftAssertions softly = new SoftAssertions();
softly.assertThat(templateData).isNotNull();
softly.assertThat(templateData.getIndexPatterns()).containsExactlyInAnyOrder(putTemplateRequest.getIndexPatterns());
assertEquals(settings.flatten().toJson(), templateData.getSettings().toJson(), false);
assertEquals(mapping.toJson(), templateData.getMapping().toJson(), false);
Map<String, AliasData> aliases = templateData.getAliases();
softly.assertThat(aliases).hasSize(2);
AliasData alias1 = aliases.get("alias1");
softly.assertThat(alias1.getAlias()).isEqualTo("alias1");
AliasData alias2 = aliases.get("alias2");
softly.assertThat(alias2.getAlias()).isEqualTo("alias2");
softly.assertThat(templateData.getOrder()).isEqualTo(putTemplateRequest.getOrder());
softly.assertThat(templateData.getVersion()).isEqualTo(putTemplateRequest.getVersion());
softly.assertAll();
}
@Test // DATAES-612
void shouldCheckTemplateExists() {
String templateName = "template" + UUID.randomUUID().toString();
ExistsTemplateRequest existsTemplateRequest = new ExistsTemplateRequest(templateName);
boolean exists = indexOperations.existsTemplate(existsTemplateRequest).block();
assertThat(exists).isFalse();
PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder(templateName, "log-*") //
.withOrder(11) //
.withVersion(42) //
.build();
boolean acknowledged = indexOperations.putTemplate(putTemplateRequest).block();
assertThat(acknowledged).isTrue();
exists = indexOperations.existsTemplate(existsTemplateRequest).block();
assertThat(exists).isTrue();
}
@Test // DATAES-612
void shouldDeleteTemplate() {
String templateName = "template" + UUID.randomUUID().toString();
ExistsTemplateRequest existsTemplateRequest = new ExistsTemplateRequest(templateName);
PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder(templateName, "log-*") //
.withOrder(11) //
.withVersion(42) //
.build();
boolean acknowledged = indexOperations.putTemplate(putTemplateRequest).block();
assertThat(acknowledged).isTrue();
boolean exists = indexOperations.existsTemplate(existsTemplateRequest).block();
assertThat(exists).isTrue();
acknowledged = indexOperations.deleteTemplate(new DeleteTemplateRequest(templateName)).block();
assertThat(acknowledged).isTrue();
exists = indexOperations.existsTemplate(existsTemplateRequest).block();
assertThat(exists).isFalse();
}
@Document(indexName = "#{@indexNameProvider.indexName()}")
@Setting(refreshInterval = "5s")
static class TemplateClass {
@Id
@Nullable private String id;
@Field(type = FieldType.Text)
@Nullable private String message;
@Nullable
public String getId() {
return id;
}
public void setId(@Nullable String id) {
this.id = id;
}
@Nullable
public String getMessage() {
return message;
}
public void setMessage(@Nullable String message) {
this.message = message;
}
}
}