Update to Elasticsearch 7.17.3.

Original Pull Request #2145
Closes #2144

(cherry picked from commit 0950dd6c7a1fc2f3f94516e8720e83e1fb577deb)
This commit is contained in:
Peter-Josef Meisch 2022-04-24 11:53:19 +02:00
parent e5efd31973
commit 3dbb1e73d6
No known key found for this signature in database
GPG Key ID: DE108246970C7708
10 changed files with 54 additions and 41 deletions

10
pom.xml
View File

@ -18,8 +18,10 @@
<url>https://github.com/spring-projects/spring-data-elasticsearch</url> <url>https://github.com/spring-projects/spring-data-elasticsearch</url>
<properties> <properties>
<elasticsearch>7.17.2</elasticsearch> <!-- version of the RestHighLevelClient -->
<elasticsearch-java>7.17.2</elasticsearch-java> <elasticsearch-rhlc>7.17.3</elasticsearch-rhlc>
<!-- version of the new ElasticsearchClient -->
<elasticsearch-java>7.17.3</elasticsearch-java>
<log4j>2.17.1</log4j> <log4j>2.17.1</log4j>
<netty>4.1.65.Final</netty> <netty>4.1.65.Final</netty>
<springdata.commons>2.7.0-SNAPSHOT</springdata.commons> <springdata.commons>2.7.0-SNAPSHOT</springdata.commons>
@ -139,7 +141,7 @@
<dependency> <dependency>
<groupId>org.elasticsearch.client</groupId> <groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId> <artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch}</version> <version>${elasticsearch-rhlc}</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>commons-logging</groupId> <groupId>commons-logging</groupId>
@ -163,7 +165,7 @@
<dependency> <dependency>
<groupId>org.elasticsearch.client</groupId> <groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId> <!-- is Apache 2--> <artifactId>elasticsearch-rest-client</artifactId> <!-- is Apache 2-->
<version>${elasticsearch}</version> <version>${elasticsearch-java}</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>commons-logging</groupId> <groupId>commons-logging</groupId>

View File

@ -34,7 +34,7 @@ The following table shows the Elasticsearch versions that are used by Spring Dat
[cols="^,^,^,^,^",options="header"] [cols="^,^,^,^,^",options="header"]
|=== |===
| Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Framework | Spring Boot | Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Framework | Spring Boot
| 2022.0 (Raj) | 4.4.x | 7.17.2 | 5.3.x | 2.7.x | 2022.0 (Raj) | 4.4.x | 7.17.3 | 5.3.x | 2.7.x
| 2021.1 (Q) | 4.3.x | 7.15.2 | 5.3.x | 2.6.x | 2021.1 (Q) | 4.3.x | 7.15.2 | 5.3.x | 2.6.x
| 2021.0 (Pascal) | 4.2.x | 7.12.0 | 5.3.x | 2.5.x | 2021.0 (Pascal) | 4.2.x | 7.12.0 | 5.3.x | 2.5.x
| 2020.0 (Ockham)footnote:oom[Out of maintenance] | 4.1.xfootnote:oom[] | 7.9.3 | 5.3.2 | 2.4.x | 2020.0 (Ockham)footnote:oom[Out of maintenance] | 4.1.xfootnote:oom[] | 7.9.3 | 5.3.2 | 2.4.x

View File

@ -82,7 +82,7 @@ The dependencies for the new Elasticsearch client are still optional in Spring D
<dependency> <dependency>
<groupId>co.elastic.clients</groupId> <groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId> <artifactId>elasticsearch-java</artifactId>
<version>7.17.2</version> <version>7.17.3</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>commons-logging</groupId> <groupId>commons-logging</groupId>
@ -93,7 +93,7 @@ The dependencies for the new Elasticsearch client are still optional in Spring D
<dependency> <dependency>
<groupId>org.elasticsearch.client</groupId> <groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId> <!-- is Apache 2--> <artifactId>elasticsearch-rest-client</artifactId> <!-- is Apache 2-->
<version>7.17.2</version> <version>7.17.3</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>commons-logging</groupId> <groupId>commons-logging</groupId>

View File

@ -5,7 +5,7 @@
== New in Spring Data Elasticsearch 4.4 == New in Spring Data Elasticsearch 4.4
* Introduction of new imperative and reactive clients using the classes from the new Elasticsearch Java client * Introduction of new imperative and reactive clients using the classes from the new Elasticsearch Java client
* Upgrade to Elasticsearch 7.17.2. * Upgrade to Elasticsearch 7.17.3.
[[new-features.4-3-0]] [[new-features.4-3-0]]
== New in Spring Data Elasticsearch 4.3 == New in Spring Data Elasticsearch 4.3

View File

@ -22,6 +22,7 @@ import co.elastic.clients.elasticsearch._types.Time;
import co.elastic.clients.elasticsearch.core.*; import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem; import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem;
import co.elastic.clients.elasticsearch.core.msearch.MultiSearchResponseItem; import co.elastic.clients.elasticsearch.core.msearch.MultiSearchResponseItem;
import co.elastic.clients.elasticsearch.core.search.ResponseBody;
import co.elastic.clients.json.JsonpMapper; import co.elastic.clients.json.JsonpMapper;
import co.elastic.clients.transport.Version; import co.elastic.clients.transport.Version;
@ -353,8 +354,8 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate {
return getSearchScrollHits(clazz, index, response); return getSearchScrollHits(clazz, index, response);
} }
private <T, R extends SearchResponse<EntityAsMap>> SearchScrollHits<T> getSearchScrollHits(Class<T> clazz, private <T> SearchScrollHits<T> getSearchScrollHits(Class<T> clazz, IndexCoordinates index,
IndexCoordinates index, R response) { ResponseBody<EntityAsMap> response) {
ReadDocumentCallback<T> documentCallback = new ReadDocumentCallback<>(elasticsearchConverter, clazz, index); ReadDocumentCallback<T> documentCallback = new ReadDocumentCallback<>(elasticsearchConverter, clazz, index);
SearchDocumentResponseCallback<SearchScrollHits<T>> callback = new ReadSearchScrollDocumentResponseCallback<>(clazz, SearchDocumentResponseCallback<SearchScrollHits<T>> callback = new ReadSearchScrollDocumentResponseCallback<>(clazz,
index); index);
@ -446,7 +447,8 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate {
MultiSearchQueryParameter queryParameter = queryIterator.next(); MultiSearchQueryParameter queryParameter = queryIterator.next();
MultiSearchResponseItem<EntityAsMap> responseItem = responseIterator.next(); MultiSearchResponseItem<EntityAsMap> responseItem = responseIterator.next();
// if responseItem kind is Result then responsItem.value is a MultiSearchItem which is derived from SearchResponse // if responseItem kind is Result then responseItem.value is a MultiSearchItem which is derived from
// SearchResponse
if (responseItem.isResult()) { if (responseItem.isResult()) {

View File

@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.client.elc;
import co.elastic.clients.ApiClient; import co.elastic.clients.ApiClient;
import co.elastic.clients.elasticsearch._types.ErrorResponse; import co.elastic.clients.elasticsearch._types.ErrorResponse;
import co.elastic.clients.elasticsearch.core.*; import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.search.ResponseBody;
import co.elastic.clients.transport.ElasticsearchTransport; import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.JsonEndpoint; import co.elastic.clients.transport.JsonEndpoint;
import co.elastic.clients.transport.TransportOptions; import co.elastic.clients.transport.TransportOptions;
@ -218,7 +219,7 @@ public class ReactiveElasticsearchClient extends ApiClient<ElasticsearchTranspor
// endregion // endregion
// region search // region search
public <T> Mono<SearchResponse<T>> search(SearchRequest request, Class<T> tDocumentClass) { public <T> Mono<ResponseBody<T>> search(SearchRequest request, Class<T> tDocumentClass) {
Assert.notNull(request, "request must not be null"); Assert.notNull(request, "request must not be null");
Assert.notNull(tDocumentClass, "tDocumentClass must not be null"); Assert.notNull(tDocumentClass, "tDocumentClass must not be null");
@ -227,7 +228,7 @@ public class ReactiveElasticsearchClient extends ApiClient<ElasticsearchTranspor
SearchRequest.createSearchEndpoint(this.getDeserializer(tDocumentClass)), transportOptions)); SearchRequest.createSearchEndpoint(this.getDeserializer(tDocumentClass)), transportOptions));
} }
public <T> Mono<SearchResponse<T>> search(Function<SearchRequest.Builder, ObjectBuilder<SearchRequest>> fn, public <T> Mono<ResponseBody<T>> search(Function<SearchRequest.Builder, ObjectBuilder<SearchRequest>> fn,
Class<T> tDocumentClass) { Class<T> tDocumentClass) {
Assert.notNull(fn, "fn must not be null"); Assert.notNull(fn, "fn must not be null");

View File

@ -22,6 +22,7 @@ import co.elastic.clients.elasticsearch._types.Time;
import co.elastic.clients.elasticsearch.core.*; import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem; import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem;
import co.elastic.clients.elasticsearch.core.get.GetResult; import co.elastic.clients.elasticsearch.core.get.GetResult;
import co.elastic.clients.elasticsearch.core.search.ResponseBody;
import co.elastic.clients.json.JsonpMapper; import co.elastic.clients.json.JsonpMapper;
import co.elastic.clients.transport.Version; import co.elastic.clients.transport.Version;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
@ -326,22 +327,27 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
Time scrollTimeout = searchRequest.scroll() != null ? searchRequest.scroll() : Time.of(t -> t.time("1m")); Time scrollTimeout = searchRequest.scroll() != null ? searchRequest.scroll() : Time.of(t -> t.time("1m"));
Flux<SearchResponse<EntityAsMap>> searchResponses = Flux.usingWhen(Mono.fromSupplier(ScrollState::new), // Flux<ResponseBody<EntityAsMap>> searchResponses = Flux.usingWhen(Mono.fromSupplier(ScrollState::new), //
state -> Mono state -> {
.from(execute((ClientCallback<Publisher<SearchResponse<EntityAsMap>>>) client -> client return Mono
.search(searchRequest, EntityAsMap.class))) // .from(execute((ClientCallback<Publisher<ResponseBody<EntityAsMap>>>) client1 -> client1
.expand(entityAsMapSearchResponse -> { .search(searchRequest, EntityAsMap.class))) //
.expand(entityAsMapSearchResponse -> {
state.updateScrollId(entityAsMapSearchResponse.scrollId()); state.updateScrollId(entityAsMapSearchResponse.scrollId());
if (entityAsMapSearchResponse.hits() == null if (entityAsMapSearchResponse.hits() == null
|| CollectionUtils.isEmpty(entityAsMapSearchResponse.hits().hits())) { || CollectionUtils.isEmpty(entityAsMapSearchResponse.hits().hits())) {
return Mono.empty(); return Mono.empty();
} }
return Mono.from(execute((ClientCallback<Publisher<ScrollResponse<EntityAsMap>>>) client -> client.scroll( return Mono.from(execute((ClientCallback<Publisher<ScrollResponse<EntityAsMap>>>) client1 -> {
ScrollRequest.of(sr -> sr.scrollId(state.getScrollId()).scroll(scrollTimeout)), EntityAsMap.class))); ScrollRequest scrollRequest = ScrollRequest
}), .of(sr -> sr.scrollId(state.getScrollId()).scroll(scrollTimeout));
return client1.scroll(scrollRequest, EntityAsMap.class);
}));
});
},
this::cleanupScroll, (state, ex) -> cleanupScroll(state), this::cleanupScroll); this::cleanupScroll, (state, ex) -> cleanupScroll(state), this::cleanupScroll);
return searchResponses.flatMapIterable(entityAsMapSearchResponse -> entityAsMapSearchResponse.hits().hits()) return searchResponses.flatMapIterable(entityAsMapSearchResponse -> entityAsMapSearchResponse.hits().hits())
@ -363,7 +369,7 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
SearchRequest searchRequest = requestConverter.searchRequest(query, entityType, index, true, false); SearchRequest searchRequest = requestConverter.searchRequest(query, entityType, index, true, false);
return Mono return Mono
.from(execute((ClientCallback<Publisher<SearchResponse<EntityAsMap>>>) client -> client.search(searchRequest, .from(execute((ClientCallback<Publisher<ResponseBody<EntityAsMap>>>) client -> client.search(searchRequest,
EntityAsMap.class))) EntityAsMap.class)))
.map(searchResponse -> searchResponse.hits().total() != null ? searchResponse.hits().total().value() : 0L); .map(searchResponse -> searchResponse.hits().total() != null ? searchResponse.hits().total().value() : 0L);
} }
@ -371,7 +377,7 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
private Flux<SearchDocument> doFind(SearchRequest searchRequest) { private Flux<SearchDocument> doFind(SearchRequest searchRequest) {
return Mono return Mono
.from(execute((ClientCallback<Publisher<SearchResponse<EntityAsMap>>>) client -> client.search(searchRequest, .from(execute((ClientCallback<Publisher<ResponseBody<EntityAsMap>>>) client -> client.search(searchRequest,
EntityAsMap.class))) // EntityAsMap.class))) //
.flatMapIterable(entityAsMapSearchResponse -> entityAsMapSearchResponse.hits().hits()) // .flatMapIterable(entityAsMapSearchResponse -> entityAsMapSearchResponse.hits().hits()) //
.map(entityAsMapHit -> DocumentAdapters.from(entityAsMapHit, jsonpMapper)); .map(entityAsMapHit -> DocumentAdapters.from(entityAsMapHit, jsonpMapper));
@ -391,7 +397,7 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
.toFuture(); .toFuture();
return Mono return Mono
.from(execute((ClientCallback<Publisher<SearchResponse<EntityAsMap>>>) client -> client.search(searchRequest, .from(execute((ClientCallback<Publisher<ResponseBody<EntityAsMap>>>) client -> client.search(searchRequest,
EntityAsMap.class))) EntityAsMap.class)))
.map(searchResponse -> SearchDocumentResponseBuilder.from(searchResponse, entityCreator, jsonpMapper)); .map(searchResponse -> SearchDocumentResponseBuilder.from(searchResponse, entityCreator, jsonpMapper));
} }

View File

@ -19,6 +19,7 @@ import co.elastic.clients.elasticsearch._types.aggregations.Aggregate;
import co.elastic.clients.elasticsearch.core.SearchResponse; import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit; import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.core.search.HitsMetadata; import co.elastic.clients.elasticsearch.core.search.HitsMetadata;
import co.elastic.clients.elasticsearch.core.search.ResponseBody;
import co.elastic.clients.elasticsearch.core.search.Suggestion; import co.elastic.clients.elasticsearch.core.search.Suggestion;
import co.elastic.clients.elasticsearch.core.search.TotalHits; import co.elastic.clients.elasticsearch.core.search.TotalHits;
import co.elastic.clients.json.JsonpMapper; import co.elastic.clients.json.JsonpMapper;
@ -45,21 +46,22 @@ class SearchDocumentResponseBuilder {
/** /**
* creates a SearchDocumentResponse from the {@link SearchResponse} * creates a SearchDocumentResponse from the {@link SearchResponse}
* *
* @param searchResponse the Elasticsearch search response * @param responseBody the Elasticsearch response body
* @param entityCreator function to create an entity from a {@link SearchDocument} * @param entityCreator function to create an entity from a {@link SearchDocument}
* @param jsonpMapper to map JsonData objects * @param jsonpMapper to map JsonData objects
* @return the SearchDocumentResponse * @return the SearchDocumentResponse
*/ */
public static <T> SearchDocumentResponse from(SearchResponse<EntityAsMap> searchResponse, @SuppressWarnings("DuplicatedCode")
public static <T> SearchDocumentResponse from(ResponseBody<EntityAsMap> responseBody,
SearchDocumentResponse.EntityCreator<T> entityCreator, JsonpMapper jsonpMapper) { SearchDocumentResponse.EntityCreator<T> entityCreator, JsonpMapper jsonpMapper) {
Assert.notNull(searchResponse, "searchResponse must not be null"); Assert.notNull(responseBody, "responseBody must not be null");
Assert.notNull(entityCreator, "entityCreator must not be null"); Assert.notNull(entityCreator, "entityCreator must not be null");
HitsMetadata<EntityAsMap> hitsMetadata = searchResponse.hits(); HitsMetadata<EntityAsMap> hitsMetadata = responseBody.hits();
String scrollId = searchResponse.scrollId(); String scrollId = responseBody.scrollId();
Map<String, Aggregate> aggregations = searchResponse.aggregations(); Map<String, Aggregate> aggregations = responseBody.aggregations();
Map<String, List<Suggestion<EntityAsMap>>> suggest = searchResponse.suggest(); Map<String, List<Suggestion<EntityAsMap>>> suggest = responseBody.suggest();
return from(hitsMetadata, scrollId, aggregations, suggest, entityCreator, jsonpMapper); return from(hitsMetadata, scrollId, aggregations, suggest, entityCreator, jsonpMapper);
} }

View File

@ -25,7 +25,7 @@ import co.elastic.clients.elasticsearch.cluster.HealthResponse;
import co.elastic.clients.elasticsearch.core.IndexRequest; import co.elastic.clients.elasticsearch.core.IndexRequest;
import co.elastic.clients.elasticsearch.core.IndexResponse; import co.elastic.clients.elasticsearch.core.IndexResponse;
import co.elastic.clients.elasticsearch.core.SearchRequest; import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse; import co.elastic.clients.elasticsearch.core.search.ResponseBody;
import co.elastic.clients.elasticsearch.indices.ElasticsearchIndicesClient; import co.elastic.clients.elasticsearch.indices.ElasticsearchIndicesClient;
import co.elastic.clients.elasticsearch.indices.IndexSettings; import co.elastic.clients.elasticsearch.indices.IndexSettings;
import co.elastic.clients.transport.ElasticsearchTransport; import co.elastic.clients.transport.ElasticsearchTransport;
@ -300,7 +300,7 @@ public class DevTests {
.query(query -> query.match(matchQuery -> matchQuery.field("content").query(FieldValue.of("content1")))) .query(query -> query.match(matchQuery -> matchQuery.field("content").query(FieldValue.of("content1"))))
.build(); .build();
SearchResponse<EntityAsMap> searchResponse = null; ResponseBody<EntityAsMap> searchResponse = null;
try { try {
searchResponse = searchImperative(searchRequest); searchResponse = searchImperative(searchRequest);
assertThat(searchResponse).isNotNull(); assertThat(searchResponse).isNotNull();
@ -316,11 +316,11 @@ public class DevTests {
} }
} }
private SearchResponse<EntityAsMap> searchImperative(SearchRequest searchRequest) throws IOException { private ResponseBody<EntityAsMap> searchImperative(SearchRequest searchRequest) throws IOException {
return imperativeElasticsearchClient.search(searchRequest, EntityAsMap.class); return imperativeElasticsearchClient.search(searchRequest, EntityAsMap.class);
} }
private SearchResponse<EntityAsMap> searchReactive(SearchRequest searchRequest) { private ResponseBody<EntityAsMap> searchReactive(SearchRequest searchRequest) {
return Objects.requireNonNull(reactiveElasticsearchClient.search(searchRequest, EntityAsMap.class).block()); return Objects.requireNonNull(reactiveElasticsearchClient.search(searchRequest, EntityAsMap.class).block());
} }
// endregion // endregion

View File

@ -15,7 +15,7 @@
# #
# #
sde.testcontainers.image-name=docker.elastic.co/elasticsearch/elasticsearch sde.testcontainers.image-name=docker.elastic.co/elasticsearch/elasticsearch
sde.testcontainers.image-version=7.17.2 sde.testcontainers.image-version=7.17.3
# #
# #
# needed as we do a DELETE /* at the end of the tests, will be required from 8.0 on, produces a warning since 7.13 # needed as we do a DELETE /* at the end of the tests, will be required from 8.0 on, produces a warning since 7.13